- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: Laufschrift aktualisieren, Probleme mit char*

  1. #1
    Erfahrener Benutzer Begeisterter Techniker Avatar von PCMan
    Registriert seit
    05.08.2006
    Ort
    Munich
    Beiträge
    311

    Laufschrift aktualisieren, Probleme mit char*

    Anzeige

    Praxistest und DIY Projekte
    Hallo Forum,
    nachblutigem rumprogrammieren bin ich mit meiner Geduld am Ende und ersuche hier erneut Rat. Kurz und Knapp:
    - Mittels den Bibliotheken von P. Fleury steuere ich erfolgreich ein LCD an
    - Durch einen Timer habe ich eine kleine Laufschrift realisiert.
    - Mit einem anderen Timer frage ich 4 Tasten ab.
    - Ich möchte, dass bei jedem Tastendruck ein anderer Text als Laufschrift auftaucht. Das klappt "eigentlich", nur nicht so wie ich will. Ich möchte dass bei dem Tastendruck die Laufschrift von Vorne startet, bisher ist es aber so, dass sich immer an's Ende des zuvorgehenden anhängt. Hier erstmal etwas Code:

    Hier wird die eigentliche Laufschrift gebildet.Ich muss immer die Länge des Strings ermitteln lassen. Wenn ich ihn einmal ermittle und in einer Variablen zwischenspeicher, dann läuft der Text sozusagen aus.

    Code:
    ISR(TIMER2_OVF_vect) 
    {
    	
    	if (LCD_hold==0){
    		if (T2Counter == 0) {	
    			lcd_gotoxy(0,LCD_SCROLLING_ROW);
    			
    			for (uint8_t i=0; i<=LCD_ROW_LENGTH; i++) {
    				lcd_putc(LCD_lauftext[i]);
    			}
    			
    			LCD_temp=LCD_lauftext[0];
    			for (uint8_t i=0; i<=strlength((const char *)LCD_lauftext); i++) {
    				LCD_lauftext[i]=LCD_lauftext[i+1];
    			}
    			LCD_lauftext[strlength((const char *)LCD_lauftext)]=LCD_temp;
    			
    			T2Counter = T2Counter_backup;
    		} else T2Counter--;
    	}
    	T2Of=1;
    	TCNT2=T2Preloader;
    }
    Die Funktionen, die mir den Timer initialisieren:
    Code:
    void lcd_clr_scrollbar() {
    	
    	TCCR2 &= ~(1<<CS22);			//timer abstellen
    	TCCR2 &= ~(1<<CS21);
    	TCCR2 &= ~(1<<CS20);
    	lcd_gotoxy(0,LCD_SCROLLING_ROW);
    	lcd_puts("                "); //löscht Zeile
    }
    
    void lcd_scroll_text(char* text, uint16_t Hz, uint8_t delay_factor){
    	/* Hier haebe ich schon verschiedenes getestet: direkte Zuweisung wie unten gezeigt, oder über eine for Schleife die einzelnen chars neu beschrieben, funktionierte alles nicht so wie ich wollte. Bei der For Schleife z.B. wurde einfac garnichts in den String LCD_lauftext aufgenommen. LCD_lauftext ist übrigens eine globale volatile char* variable*/
            LCD_lauftext=text;
            
    	T2Counter=delay_factor;
    	T2Counter_backup=delay_factor;
    	TCCR2|=(1<<CS22)|(1<<CS21)|(1<<CS20); //Prescaler=1024
    	T2Preloader=256-F_CPU/LCD_PRESCALER/Hz;
    	TCNT2=T2Preloader;
    	TIMSK |= (1<<TOIE2);
    	T2Of=0;	
    	LCD_hold=0;
    }
    In der Hauptschleife dann die Abfrage der Taste und Reaktion auf dem Display anzeigen:
    Code:
    keypad_open(KEYPAD_SCANNING_FREQUENCY,KEYPAD_DEBOUNCE_SLOW);
    for (;;) { 
    		
    		uint8_t key = keypad_check();
    		if (key==KEYPAD_KEYOK)  { lcd_clr_scrollbar(); lcd_scroll_text("Es wurde die Taste [OK] betaetigt +++ ",LCD_SCANNING_FREQUENCY,LCD_DELAY_FACTOR); keypad_open(KEYPAD_SCANNING_FREQUENCY,KEYPAD_DEBOUNCE_SLOW); } else
    		if (key==KEYPAD_KEYESC)  { lcd_clr_scrollbar(); lcd_scroll_text("Die Taste [ESC] gedrueckt +++ ",LCD_SCANNING_FREQUENCY,LCD_DELAY_FACTOR); keypad_open(KEYPAD_SCANNING_FREQUENCY,KEYPAD_DEBOUNCE_SLOW); } else
    		if (key==KEYPAD_KEYINC)  { lcd_clr_scrollbar(); lcd_scroll_text("[+] wurde betaetigt  +++ ",LCD_SCANNING_FREQUENCY,LCD_DELAY_FACTOR); keypad_open(KEYPAD_SCANNING_FREQUENCY,KEYPAD_DEBOUNCE_SLOW); } else
    		if (key==KEYPAD_KEYDEC)  { lcd_clr_scrollbar();  keypad_open(KEYPAD_SCANNING_FREQUENCY,KEYPAD_DEBOUNCE_SLOW); }
    	 }
    }
    So das war's eigentlich, wenn noch Fragen sind, bitte posten.
    System:
    ATMega 32, JTAGEN disabled, Crystal = 8MHz. Das Keypad verwendet Timer0, das LCD Timer2 (salopp formuliert)


    Freue mich auf Antworten,
    viele Grüße,
    Simon

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    13.04.2007
    Ort
    NRW
    Beiträge
    37
    Hallo,

    Hier wird die eigentliche Laufschrift gebildet.Ich muss immer die Länge des Strings ermitteln lassen. Wenn ich ihn einmal ermittle und in einer Variablen zwischenspeicher, dann läuft der Text sozusagen aus.....
    setz jedesmal bevor du die laufschrift auf dem dispaly aktualisierst ein

    Code:
    lcd_clear();
    davor....

    dann sollte der aktuelle text gelöscht werden und der neue erscheinen...

    mfg pierce
    Lasst mich Arzt, ich bin durch...

    http://www.pennergame.de/change_please/9251940/

  3. #3
    Erfahrener Benutzer Begeisterter Techniker Avatar von PCMan
    Registriert seit
    05.08.2006
    Ort
    Munich
    Beiträge
    311
    Meinst du jedes mal bevor ein neuer Text geladen wird oder vor jedem mal, wo die Buchstaben verschoben werden?
    Bevor ein neuer Text geladen wird lösche ich ja jedesmal bereits die Zeile (lcd_clr_scrollbar(). Das Problem ist, dass im Speicher (also in der globalen volatile Variablen LCD_lauftext) noch was drin steht. Und das muss ich löschen, aber ich weiß nicht wie ich das hinbekomme. Mit For-Schleifen zeichenweise zu überschreiben funktioniert nicht und eine Zuweisung à la LCD_lauftext = "" funktioniert auch nicht, da bleibt der Inhalt gänzlich unangetastet...
    vG

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    10.08.2004
    Ort
    Großbardorf
    Alter
    37
    Beiträge
    674
    Mit For-Schleifen zeichenweise zu überschreiben funktioniert nicht
    Eigentlich müsste das schon funktionieren. Zeig mal deinen code dazu.

  5. #5
    Erfahrener Benutzer Begeisterter Techniker Avatar von PCMan
    Registriert seit
    05.08.2006
    Ort
    Munich
    Beiträge
    311
    Das würde dann so aussehen:
    Code:
    void lcd_scroll_text(char* text, uint16_t Hz, uint8_t delay_factor){
    
    	for (uint8_t i=0; i<=strlength(text); i++){
    		LCD_lauftext[i]=text[i];
    	}
    	//LCD_lauftext=text;
    	T2Counter=delay_factor;
    	T2Counter_backup=delay_factor;
    	TCCR2|=(1<<CS22)|(1<<CS21)|(1<<CS20); //Prescaler=1024
    	T2Preloader=256-F_CPU/LCD_PRESCALER/Hz;
    	TCNT2=T2Preloader;
    	TIMSK |= (1<<TOIE2);
    	T2Of=0;	
    	LCD_hold=0;
    }
    Ergbnis: Scrollende Zeile bleibt schlict und ergreifend leer. Wieso? Das ergibt keinen Sinn!?

    Ich habe übrigens in die Anweisung, wo die Buchstaben verschoben werden (ISR v. TIMER2) ein lcd_clrscr() eingefügt. Das ändert aber ebenfalls nicht das Problem, dass bei einem neuen Text noch Reste des alten vorhanden sind. Scheinbar wird der neue Text auch "irgendwo" im alten eingefügt und nicht angehängt...
    vG Simon

  6. #6
    Erfahrener Benutzer Begeisterter Techniker Avatar von PCMan
    Registriert seit
    05.08.2006
    Ort
    Munich
    Beiträge
    311
    nochwas: außer "function isnt a prototype" habe ich sonst keine compiler warnungen die auf einen Fehler hindeuten. Aber das Prototypen-Problem hat damit ja nichts zu tun...

  7. #7
    Erfahrener Benutzer Begeisterter Techniker Avatar von PCMan
    Registriert seit
    05.08.2006
    Ort
    Munich
    Beiträge
    311
    Hallo Freunde,
    wenn ich aus
    volatile char* LCD_lauftext;

    volatile char LCD_lauftext[30]; mache funktioniert die Geschichte. Der Algorithmus funktioniert also. Das ganze erscheint mir aber recht undynamisch. Im Übrigem bestätigt es die Vermutung, dass es Pobleme mit char* gibt, dass sich wohl nicht wie ein Array behandeln lässt. Habt ihr eine Ahnung, wie sich das Problem beheben lässt?
    vG Simon

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    21.10.2005
    Ort
    Erde
    Alter
    57
    Beiträge
    1.195
    Wenn LCD_lauftext ein globaler char-Pointer ist muss er vor Benutzung auf einen existierenden Speicherbereich zeigen.

    Code:
    const textLength = 32;
    char* globalPointer = NULL;
    
    char myCharArray[textLength];
    
    void init( void )
    {
       globalPointer = myCharArray;
    }

  9. #9
    Erfahrener Benutzer Begeisterter Techniker Avatar von PCMan
    Registriert seit
    05.08.2006
    Ort
    Munich
    Beiträge
    311
    also damit ich das richtig verstehe: ich muss so oder so einen festen Speicher als Array reservieren? Kann man das auconh irgendwie dynamisch machen? In deinem Code beschränke ich mich auf 32 Zeichen, oder?
    Vielen Dank,
    vG Sim

  10. #10
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    21.10.2005
    Ort
    Erde
    Alter
    57
    Beiträge
    1.195
    Du brauchst Speicher, wo Deine Daten reinkommen. Ergo entweder den Speicher fest allokieren (z.B. char bla[länge]) oder dynamischen Speicher holen
    Code:
    char* globalPointer = NULL
    
    bool init( void )
    {
         globalPointer = malloc( stringlength * sizeof( char ) );
         return globalPointer != NULL;
    }
    Ich würde in Deinem Fall die statische Variante bevorzugen, weil das viel Platz im Flash spart, da im dynamischen Fall, die ganze Heapverwaltung mit hinzu gelinkt werden muss.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Labornetzteil AliExpress