Forum: Mikrocontroller und Digitale Elektronik Schon wieder das LCD


von Matthias (Gast)


Lesenswert?

Dere nochmals,

also langsam frag ich mich ob ich unfähig bin oder sonst noch was, denn 
bei jedem Problem lande ich wieder bei euch...

Nachdem die Uart-Übertragung der Werte nun gut funktioniert, gehts jetzt 
nochmal um das Display. Controller Atmega16, Display mit HD44780 als Lib 
zur Ausgabe fungiert die von Peter Fleury.

Schreiben kann ich ist kein Problem, mehr jedenfalls. Aber ich habe ein 
mir etwas komisches Problem. Und zwar will ich in einer while Schleife 
in meinem Main- Programm ständig mein Display aktualisieren, aber er 
machts nicht. Aufhängen tut sich der Controller auch nicht da ich nach 
wievor meine Daten abrufen kann. Ich machs im grunde genauso wie bei der 
Übertragung der Daten im Uart und nutze statt usart_putc() die Funktion 
lcd_putc().

Hier mal der Code
1
//--Aktualisierung des Displays
2
    
3
//--Auslesen des AD Wandlers 1  
4
adcval=ReadChannel(2);
5
//--Umwandeln des Intwertes in String Variable
6
itoa(adcval,string,10);
7
    
8
//--Löschen der alten Analogwerte aus dem Display
9
lcd_gotoxy(0,1);
10
lcd_puts("                 ");
11
12
lcd_gotoxy(0,1);
13
14
while( string[i] != '\0' )
15
{
16
     lcd_putc( string[i++] );
17
}
18
19
//--Ausgabe der Digitalwerte
20
//--Zustand 1
21
lcd_gotoxy(0,3);
22
if (bit_is_set(PINB,0))
23
{
24
    lcd_putc('1');
25
}
26
else
27
{
28
    lcd_putc('0');
29
}

Problem ist das er mir die änderungen nicht aufs Display schreibt, 
sondern nur Einmalig beim Einschalten. Ich hab auch schon versucht in 
der while Schleife jedesmal das Display zu clearen, hilft aber auch 
nichts. Und wie gesagt am Uart kommen die Daten richtig an.
Bin ich zu schnell fürs Display?
Eigentlich sollte er jeden Befehl der Reihe nach ja ausführen können, da 
ja in der Lib das Busyflag abgefragt wird.

MfG
Matthias

von Karl H. (kbuchegg)


Lesenswert?

> while( string[i] != '\0' )
> {
>      lcd_putc( string[i++] );
> }

wo kriegt i einen neuen Wert (nämlich 0).

Das was ich für die UART gesagt habe, gilt auch hier:
Einen String ausgeben ist eine so häufige Operation,
dass es sich lohnt, dafür eine eigene Funktion
zu schreiben. Meines Wissens hat die Fleury Lib sogar
eine derartige Funktion mit:  lcd_puts
Wenn nicht, dann ist sie in 20 Sekunden geschrieben.

> lcd_gotoxy(0,3);

Ich weiss jetzt nicht auswendig, was die Parameter
bedeuten. Ist das erste die Zeile oder die Spalte.
Glaube jedoch das, die erste Zahl die Spalte ist.
Daher: Hat dein Display mindestens 4 Zeilen?
Hast du vorher mal ausprobiert, ob du alle 4 Zeilen
auch wirklich ansprechen kannst?

von Matthias (Gast)


Lesenswert?

Servus,

4 Zeilen hat das Display...
Erste ist Position in der Zeile und das zweite die Spalte.
Er zeigt auch beim ersten Durchlauf die Daten an, aber halt nicht mehr 
beim zweiten...

von Matthias (Gast)


Lesenswert?

So ich hab etz gefunden worans liegt...

Und zwar an genau dieser Zeile:

UartEingang=usart_getc();

Dort wartet der Controller bis eine Eingabe am Uart kommt, deshalb wird 
das Display nicht geupdatet. Geschrieben ist die usart_getc() so:
1
char usart_getc(void)
2
{
3
  if (!usart_buffer_overflow)
4
    while(usart_buffer_pos_first == usart_buffer_pos_last);
5
  usart_buffer_overflow = 0;
6
  if (++usart_buffer_pos_first >= USART_BUFFER_SIZE) 
7
    usart_buffer_pos_first = 0;
8
  return usart_buffer[usart_buffer_pos_first];
9
}

Der Quellcode für den Uart ist mehr oder weniger von mir geklaut.

Bei Bascom gibts ja die Befehle Waitkey (warte bis eingabe) und 
Inkey(ist Eingabe vorhanden dann auslesen).
Gibts sowas in C auch?
Und wie müsste das dann aussehen?

MfG
Matthias

von Karl H. (kbuchegg)


Lesenswert?

Matthias wrote:

> Bei Bascom gibts ja die Befehle Waitkey (warte bis eingabe) und
> Inkey(ist Eingabe vorhanden dann auslesen).
> Gibts sowas in C auch?
> Und wie müsste das dann aussehen?

Hier
1
char usart_getc(void)
2
{
3
  if (!usart_buffer_overflow)
4
    while(usart_buffer_pos_first == usart_buffer_pos_last);
ist in deinem Code die Warteschleife, die darauf wartet, dass
ein Zeichen ankommt.
Wenn du nicht willst, dass hier gewartet wird, dann wirst du
wohl hier keine Schleife machen dürfen, sondern einen return
(mit einem sinnvollen Returnwert) wenn kein Zeichen vorhanden
ist. :-)

> Der Quellcode für den Uart ist mehr oder weniger von mir geklaut.

Was einen ja nicht daran hindern soll, auch zu verstehen, was man
da tut.

von Ulrich P. (uprinz)


Lesenswert?

Hi!

Ich habe mir dazu meine UART Routinen um zwei Flags erweitert. Das eine 
Flag wird gesetzt, wenn ein Zeichen im Puffer gelandet ist, das andere, 
wenn ein CR eine komplette Eingabezeile signalisiert:

uint8_t uart_char_ready()
{
  return (usart_buffer_pos_first == usart_buffer_pos_last)? 0:1;
}

uint8_t uart_line_ready()
{
  return (usart_cr_recvd);
}

usart_cr_recvd wird im receiver-interrupt automatisch gesetzt, wenn ein 
CR enpfangen wurde. Das CR wird automatisch in ein \0 übersetzt und in 
dem Puffer geschrieben, um anschließen mit handelsüblichen 
String-Funktionen weiter arbeiten zu können. usart_cr_recvd wird durch 
uart_get_line( uint8_t*) wieder zurück gesetzt, wenn die Zeile aus dem 
Puffer herauskopiert wurde.

Das macht das Leben wirklich einfacher :)

Gruß, Ulrich

von Matthias (Gast)


Lesenswert?

Servus,

wenn ich
1
  if (!usart_buffer_overflow)
2
    while(usart_buffer_pos_first == usart_buffer_pos_last);
rauslasse, dann läuft er ewig durch. Also ist noch was im Buffer.
Sprich bei
1
UartEingang=usart_getc();
2
3
if(UartEingang=='#')
geht er mir immer in die if-schleife rein.
Ich hab jetzt auch versucht, mit
1
if(bit_is_set(UCSRA,RXC))
den Zustand im Uart abzufragen ob ein Zeichen vorhanden ist, was aber 
nicht funktioniert. Auch wenn ich mit sei() die globallen Interrupts 
aktiviere.

Welches Flag könnte ich da abfragen ob Daten vorhanden sind?
RXCIE oder eben RXC? Oder Frag ich einfach nur falsch ab.

Ich hab mir jetzt auch mal die Routinen von eurem Tutorial angeschaut, 
und da ist auch ne While drin um zu warten bis was kommt.
Die von Peter Fleury ist zu viel um sie auf die schnelle zu verstehen...
Wartet er da auch oder nicht?

MfG
Matthias

von Karl H. (kbuchegg)


Lesenswert?

Matthias wrote:
> Servus,
>
> wenn ich
>
1
>   if (!usart_buffer_overflow)
2
>     while(usart_buffer_pos_first == usart_buffer_pos_last);
3
>
> rauslasse,

Wer hat denn was von 'rauslassen' gesagt?
1
  ...
2
3
  if( usart_buffer_pos_first == usart_buffer_pos_last ) {
4
    // kein Zeichen vorhanden, nicht warten sondern
5
    // dem Benutzer mitteilen, dass nichts da ist.
6
    // zv. indem 0xFF returniert wird
7
    return 0xFF;
8
  }
9
10
  ...
11
12
13
14
> [c]
15
> UartEingang=usart_getc();
16
17
  if( UartEingang != 0xFF ) {   // war überhaupt ein Zeichen da?
18
 
19
>    if(UartEingang=='#')
>
> geht er mir immer in die if-schleife rein.

if ist keine Schleife. Eine Schleife heist deshalb Schleife
weil ein Programmteil immer wieder und immer wieder
wiederholt wird. Ein if wiederholt aber nichts. Ein if
trifft eine Auswahl anhand einer Bedingung.

> Die von Peter Fleury ist zu viel um sie auf die schnelle zu verstehen...
> Wartet er da auch oder nicht?

Da wird nicht gewartet. Rate mal wie er das Problem löst?
Richtig: Seine Lesefunktion hat einen Returnwert, der
dem Aufrufer mitteilt: Nichts vorhanden.
Kommt dir irgendwie bekannt vor :-)

von Matthias (Gast)


Lesenswert?

Servus,

dann hatte ich dich falsch Verstanden...so gehts jedenfalls.
Ich weis blos eins, wenns an der einen Seite hängt, fängt die andere 
Seite auch an...durfte gerade Windows neu Aufsetzten weils total 
abgestürzt war. Permanet geflacker aufn Monitor...also kann ich durfte 
jetzt das Programm vom Stand von vor 2 Wochen neu anfangen...

Also dank dir für deine Hilfe.
Hab etz ne 2te Funktion geschrieben die nicht wartet in dem Stil wie du 
geschrieben hast und auch ne 2te puts funktion für normale Strings mit 
'\0' als Abbruchzeichen.

Hab etz auch die Display- Probleme gelöst, sieht jetzt alles Klasse aus.

Also denne

Schenes Wochenende!!!

MfG
Matthias

von Peter D. (peda)


Lesenswert?

Matthias wrote:

> Seite auch an...durfte gerade Windows neu Aufsetzten weils total
> abgestürzt war. Permanet geflacker aufn Monitor...also kann ich durfte
> jetzt das Programm vom Stand von vor 2 Wochen neu anfangen...

Wie kommt das denn?

Windows kannst Du so oft neu installieren, wie Du willst, die 
Datenpartition wird davon nicht beeinflußt.

Man muß natürlich auch seine eigenen Dateien (Sourcetexte, Briefe, 
E-Mails,...) auf der 2. Partition abspeichern lassen.


Peter

von Matthias (Gast)


Lesenswert?

Wie das kommt frag ich mich auch...keine Ahnung. Früher zu MSDOS Zeiten 
häts sowas net gegeben.
Wenn Windows spinnt geht die Windows Partition übern Jordan, spich wird 
gleich neu Formatiert, alle Programme etc gehen dann natürlich auch hobs 
und müssen neu drauf. Hab mittlerweilen schon Übung drin. 2 Stunden und 
das meiste steht dann wieder.
Leider hab ich trottel vergessen mal zwischenrein auf die 2te Partion 
und USB- Stick zu sichern. Lag alles aufn Desktop...

Ausserdem hab ich schon seit über einem Jahr Probleme mit meinem Rechner 
in Grafikbelagen. Spiele laufen nicht mehr obwohl vorher gingen, 
Videoausgang der Grafikkarte geht auch nicht mehr, zwischenrein noch nen 
Festplattencrash mit "Sand im Getriebe"...(die 3te in dem Rechner, 2 WD 
und eine Maxtor)
Hab schon fast alles zeitweise auf leihbasis ausgetauscht ausser das 
Mainboard und die Probleme blieben...naja sind ja auch schon ein paar 
Konids wies ausschaut ausgelaufen...halt nur noch Schrott und hat erst 5 
Jahre aufn Buckel das ganze...Traumhaft...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.