Wer sieht den Fehler im Code

OP #3313668
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
}
#3313677
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'.
#3313697
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.
#3313765
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.
#3313779
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.
#3313797
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.
OP #3313857
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.
Angehängte Dateien:
#3313865
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.
OP #3314004
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
#3314036
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.
OP #3314880
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 */

}
#3314886
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)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren