Forum: Mikrocontroller und Digitale Elektronik Wer sieht den Fehler im Code


von Peter N. (jackybroun)


Lesenswert?

Atmega32 nur über Tx und Rx mit Ft232Rl verbunden, soll Daten aus einem 
Terminal empfangen. Eingestellte Baud 9600, genutzt wird ein 12MHZ Oszi.

Wenn ich zB. eine 9 über das Terminal Sende blink eine LED kurz auf das 
was empfangen wurde und dann leuchtet wieder die Status LED. Sollte die 
Zahl 9 gesendet werden, sollten alle 3 leds aufleuhten, dies passiert 
aber nicht. Wer kann mir weiterhelfen?
1
#define F_CPU 12000000UL
2
#include <avr/io.h>
3
#include <util/delay.h>
4
#define USART_BAUDRATE 9600
5
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
6
7
uint8_t uart_getc(void)
8
{
9
  while (!(UCSRA & (1<<RXC)))   // warten bis Zeichen verfuegbar
10
  ;
11
  return UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben
12
}
13
14
int main (void){
15
  DDRB = 0b00001110; 
16
  UCSRB |= (1 << RXEN) | (1 << TXEN);
17
  UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);
18
  UBRRH = (BAUD_PRESCALE >> 8);
19
  UBRRL = BAUD_PRESCALE;
20
  //PORTB = 0b00000100;
21
  
22
  while (1)
23
  {
24
    if ( (UCSRA & (1<<RXC)) )
25
    {
26
      int buffer;
27
      int test = 9;
28
      // Zeichen wurde empfangen, jetzt abholen
29
      buffer = uart_getc();
30
      // hier etwas mit c machen z.B. auf PORT ausgeben
31
      //DDRC = 0xFF; // PORTC Ausgang
32
      //PORTC = c;
33
      if (buffer == test)
34
      {
35
        PORTB = 0b00001110;
36
        _delay_ms(100);
37
      } 
38
      else
39
      {
40
        PORTB = 0b00000100;
41
        _delay_ms(100);
42
      }
43
    }
44
    else
45
    {
46
      PORTB = 0b00001000;
47
      _delay_ms(100);
48
    }
49
  }
50
  return 0; // never reached
51
}

von Justus S. (jussa)


Lesenswert?

Peter Naschke schrieb:
> Atmega32 nur über Tx und Rx mit Ft232Rl verbunden,

GND sollte man natürlich auch mitnehmen...

von Peter (Gast)


Lesenswert?

haste vllt ne 9 als ASCII geschickt und Deine Prüfung ist auf dezimal 9?

von Justus S. (jussa)


Lesenswert?

und

Peter Naschke schrieb:
> if (buffer == test)

ist ja auch Käse, außer du sendest ein TAB...

von Karl H. (kbuchegg)


Lesenswert?

Peter Naschke schrieb:

> Wenn ich zB. eine 9 über das Terminal Sende

Das bedeutet was ganz genau?

Du drückst die Taste, auf der 9 steht?

Dann wird nicht die Zahl 9 versendet, sondern der ASCII Code für diesen 
Buchstaben. Und der ist 0x39 und nicht 9


>       if (buffer == test)

       if (buffer == '9')

Auf dieser Ebene sind alles 'Buchstaben'. Egal ob es wirklich Buchstaben 
(klein, groß), oder Ziffern oder Sonderzeichen sind. Wir sagen daher 
auch einfach nur 'Zeichen'. Und welcher Code für welches Zeichen steht, 
findet sich in den ASCII Tabellen. Muss man aber nicht auswendig wissen, 
der Compiler kennt die genauso. Also kann man genausogut auch '9' 
schreiben, anstelle des ASCII Codes für das Zeichen '9'.

von Route_66 (Gast)


Lesenswert?

Wie sendest Du die 9? Durch Druck auf die Taste "9" wird leider 0x39 
gesendet. Wie hast Du dich vergewissert, daß Deim µC wirklich mit den 12 
MHz läuft?

von Conny G. (conny_g)


Lesenswert?

Das Signal des Ft232 ist kompatible in puncto Spannung und Invertierung 
und so?

Ansonsten fällt mir auf, dass bei den Zeichen mit "int" hantiert wird, 
sollte das nicht besser uint8_t sein? (8 bit vs. 16 bit)

Sonst sieht's kurz überflogen ganz gut aus.

von Peter N. (jackybroun)


Lesenswert?

Ich habe in H_Term die 9 als Dezimal gesendet

Die Schaltung hat die gleiche Spannungsquelle, soll heißen ich benutze 
den Busspowered Mode des ft232rl nicht

von Justus S. (jussa)


Lesenswert?

Peter Naschke schrieb:
> Ich habe in H_Term die 9 als Dezimal gesendet

also die TAB-Taste gedrückt

von Karl H. (kbuchegg)


Lesenswert?

Peter Naschke schrieb:
> Ich habe in H_Term die 9 als Dezimal gesendet

dann sende vom µC aus einfach mal zurück, was der µC empfängt.
Sowas ist immer ein guter Test um festzustellen, ob der Empfänger auch 
wirklich das empfängt, was man denkt :-)

Deine Serielle Schnittestelle mit allem drum und drann hast du 
hoffentlich vorher schon verifiziert, indem du erst mal nur vom µC aus 
sendest, und nachsiehst ob du um HTerm auch das Erwartete empfängst. Man 
nimmt immer zuerst diese Richtung in Betrieb, weil man leichter 
verifizieren kann, ob alles funktioniert und zb die Baudraten korrekt 
sind.

von Uwe (Gast)


Lesenswert?

Bau mal ne anständige Statemachine für den Empfang. Und wenn du im 
Terminal ne '9' sendest kommt natürlich der ASCII code 0x39 an.

von Peter N. (jackybroun)


Lesenswert?

Mal anders herum gefragt, habe ich die Fuses falsch gewählt?

HI 0xD9
LO 0x3F

habe wie gesagt einen atmega32 mit einem ext oszi von 12MHz

von Karl H. (kbuchegg)


Lesenswert?

Peter Naschke schrieb:
> Mal anders herum gefragt, habe ich die Fuses falsch gewählt?

ganz einfach:
schreib ein Programm, welches auf dem AVR ein paar Zeichen (zb TEST) auf 
der seriellen ausgibt.
Steht in deinem HTerm dann auch TEST im Empfnagsfenster, dann ist deine 
Serielle Kommunikation fehlerfrei. Steht dort was anderes oder gar 
nichts, dann ist irgendwo ein Hund begraben (der in den meisten Fällen 
bei einer fehlerhaften Baudrate und/oder Taktfrequenz zu suchen ist).

Aber das Blödeste was du tun kannst, ist dir einen Test auszudenken, bei 
dem du ausser 'Funktioniert/funktioniert nicht' keinerlei Aussage 
ableiten kannst. Ein Zeichen vom PC zum AVR zu schicken und dann darauf 
aufbauend eine LED ein/aus schalten fällt genau in diese Kategorie. Wenn 
die Übertragung AVR->PC einwandfrei klappt, dann tut sie das auch in der 
anderen Richtung. Um also festzustellen, ob die Übertragung an sich 
fehlerfrei funktioniert, testet man die Richtung AVR->PC zuerst. Denn am 
PC kann man davon ausgehen, dass sowohl die Serielle als auch die 
AUswertung bzw. Anzeige erst mal fehlerfrei ist, wohingegen auf dem AVR 
bei diesem Test nur das Senden korrekt funktionieren muss.

von Peter N. (jackybroun)


Lesenswert?

Genau das habe ich grade gemacht, leider kommt nichts beim Terminal 
an.Deswegen war ich grade am überlegen ob die fuses so stimmen.

von Karl H. (kbuchegg)


Lesenswert?

Peter Naschke schrieb:
> Genau das habe ich grade gemacht, leider kommt nichts beim Terminal
> an.

:-)
Also eine nicht getestete Verbindung.

Gut.
Erster Test:
Mega32 aus dem Sockel, den Tx Pin mit dem RX Pin im µC-Sockel mit einem 
Drahtstück verbinden. Auf dem PC auf der Tatstatur klimpern. Alles was 
du drückst muss über das Kabel und die Drahtbrücke sofort wieder zum PC 
zurückkommen. Gegentest: Drahtbrücke raus - das Echo muss aufhören.

Wenn dem nicht so ist, dann ist höchst wahrscheinlich das RS232 Kabel 
falsch gekreuzt.

von Karl H. (kbuchegg)


Lesenswert?

Peter Naschke schrieb:

> an.Deswegen war ich grade am überlegen ob die fuses so stimmen.

Unwahrscheinlich.
Wenn die Fuses nicht stimmen hast du eine andere Taktfrequenz. Das zeigt 
sich, indem Kauderwelsch ankommt. Aber irgendwas kommt an.

von Karl H. (kbuchegg)


Lesenswert?

PS:
Man kann sich die Signale auf einer RS232 mit einer LED sichtbar machen. 
Einfach eine LED (+330 Ohm Vorwderstand) nach GND schalten und mit dem 
anderen Bein auf die unter Verdacht stehende Signalleitung gehen. Bei 
diesen Baudraten sieht man die LED noch eindeutig blinken/flackern.

Legst du einen Stein auf die PC Tastatur, dann muss auf der RS232 Seite 
vom FT232 es einen Pin geben (weiß die Pinnummer nicht auswendig), an 
dem die seriellen Daten rauskommen - dort blinkt dann die LED.
Wenn nicht, dann stimmt mit dem FT232 bzw. dem Treiber im PC was nicht.
Wenn schon, dann nachverfolgen, an welchem µC Pin diese blinkende 
Leitung geht. Es muss der Rx Pin vom µC sein.

von Peter N. (jackybroun)


Lesenswert?

Als ich den µc raus genommen habe und durch eine Brücke ersetzt habe, 
habe ich auch nichts zurück bekommen. An der Brücke liegt aber 5V an und 
auch RX ist mit TX und TX mit RX ist richtig verbunden.

von Peter N. (jackybroun)



Lesenswert?

Mal ein Paar Bildchen anhängen:

alle 3 Bilder sind von der D+ Leitung hinterm USB-B auf der Platine 
gemessen. Bild 4 bei geschlossener Leitung selten mal ein flákern

Bild 1,2 und 3 bei im Terminal geöffneter Leitung, kaum was zu erkennen 
ohne das ich was sende.

von Karl H. (kbuchegg)


Lesenswert?

Die USB Leitungen zu verifizieren dürfte ohne Spezialequipment recht 
schwierig sein.
D.h. du musst darauf vertrauen, dass die Kommunikation PC zu FT232 
funktioniert.
Mit ordinären Messmitteln kannst du erst am TXD bzw. RXD Pin vom FT232 
irgendwelche Aussagen treffen.

D.h. PC auf Dauersenden stellen (zb Stein auf Tastatur) und nachsehen, 
ob am FTDI232 an dessen TXD Pin was rauskommt. Wenn möglich alles 
abklemmen, was irgendwie die TXD bzw. RXD Leitung blockieren könnte 
(daher auch: µC aus dem Sockel nehmen).

Eines ist hoffentlich auch klar. Solange diese einfachen Hardwaretests 
nicht erfolgreich absolviert sind, brauchst du dir keine Gedanken um 
Software oder dgl. zu machen. Denn diese Tests sind Voraussetzung für 
alles andere.

von Peter N. (jackybroun)


Lesenswert?

So da bin ich wieder,

also ich habe eine Drahtbrücke zwischen RX und TX auf der Fassung des 
Atmega gesteckt. An der Drahtbrücke habe ich mit einem Oszi gemessen.

Mit HTerm habe ich 1sen in 0,2ms und dann nochmal in 0,4ms gesendet und 
konnte sie auf dem oszi anhand der flanken deutlich erkennen. Aber bei 
HTerm selbst ist nichts angekommen.

Kann das ein Problem mit dem Treibern sein? Sonst irgendwelche ideen

von Karl H. (kbuchegg)


Lesenswert?

Peter Naschke schrieb:
> So da bin ich wieder,
>
> also ich habe eine Drahtbrücke zwischen RX und TX auf der Fassung des
> Atmega gesteckt. An der Drahtbrücke habe ich mit einem Oszi gemessen.
>
> Mit HTerm habe ich 1sen in 0,2ms und dann nochmal in 0,4ms gesendet und
> konnte sie auf dem oszi anhand der flanken deutlich erkennen. Aber bei
> HTerm selbst ist nichts angekommen.

OK. Siehst du sie am Eingang des FT232 auch noch?

> Kann das ein Problem mit dem Treibern sein? Sonst irgendwelche ideen

Wenn sie am Eingang des FTD232 auch noch da sind, dann wird das wohl das 
Problem sein.

von Peter N. (jackybroun)


Lesenswert?

Also mit einer Drahtbrücke Funktioniert das senden und ampfangen, aber 
sobald der chip wieder drauf sitzt, kommt nichts an.

Wenn ich etwas vom PC sende und am Pin des Atmega32 messe kann ich es 
auch deutlich sehen. Hingegen ich das was ich vom Atmega sende nicht 
sehen kann auf den leitungen
1
#define F_CPU 12000000     // Systemtakt in Hz - Definition als unsigned long beachten
2
#include <avr/io.h>
3
#include <util/delay.h>
4
#define BAUD 9600
5
#include <util/setbaud.h>
6
7
void uart_init(void)   
8
{
9
   UBRRH = UBRRH_VALUE;
10
   UBRRL = UBRRL_VALUE;
11
   /* evtl. verkuerzt falls Register aufeinanderfolgen (vgl. Datenblatt)
12
      UBRR = UBRR_VALUE;
13
   */
14
#if USE_2X
15
   /* U2X-Modus erforderlich */
16
   UCSRA |= (1 << U2X);
17
#else
18
   /* U2X-Modus nicht erforderlich */
19
   UCSRA &= ~(1 << U2X);
20
#endif
21
 
22
  UCSRB=(1<<RXEN)|(1<<TXEN);
23
  UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // Asynchron 8N1 
24
}
25
26
int uart_putc(unsigned char c)
27
{
28
  while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
29
  {
30
  }
31
  
32
  UDR = c;                      /* sende Zeichen */
33
  return 0;
34
}
35
36
int main (void){
37
  
38
39
  uart_init();
40
  
41
  while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich                   */
42
  {
43
  }
44
45
  UDR = 'x';                    /* schreibt das Zeichen x auf die Schnittstelle */

}

von Karl H. (kbuchegg)


Lesenswert?

> Also mit einer Drahtbrücke Funktioniert das senden und ampfangen,

Gut. Das sollte soweit als Funtionsnachweis für die Verkabelung, die 
PC_Seite und den FT232 ausreichend sein.

> aber
> sobald der chip wieder drauf sitzt, kommt nichts an.

Sende da mal etwas mehr als nur ein einziges lausiges Zeichen.
1
int main (void)
2
{
3
  uart_init();
4
5
  while( 1 )
6
  {
7
    usart_putc( 'x' );
8
    _delay_ms( 500 );
9
  }
10
}


Und wieder geht das Spielchen los:
Messequipment an den Tx Pin vom Mega und nachsehen, ob da was rauskommt. 
Wenn ja, kommt das auch am FT232 an?



Zusätzlich:
Sind die
#define F_CPU 12000000UL
verifiziert worden?
Läuft der µC wirklich mit 12Mhz?

(kann man zb mit einer blinkenden LED und delay_ms leicht verifizieren. 
Entwder ein delay_ms(1000) dauert tatsächlich 1 Sekunde oder er dauert 
das 12-fache davon, weil der µC noch mit den default-1Mhz statt mit den 
angegebenen 12Mhz läuft)

von Peter N. (jackybroun)


Lesenswert?

Vielen Dank, das x kommt als x an, also alles super =). Den rest bekomme 
ich auch alleine hin.

Fals es von interesse ist, der Fehler war eine Durchkontaktierung der 
Platine auf der RX Leitung. Diese hatte nicht richtik Kontakt und die 
Daten sind verloren gegangen

liebe grüße

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.