Forum: Mikrocontroller und Digitale Elektronik Atmega32, UART sendet konstant bei zweitem Zeichen


von Clemens K. (clemensk)


Lesenswert?

Hallo,

ich habe ein seltsames Problem mit UART und vielleicht sieht jemand 
meinen Fehler sofort.

Ich initialisiere UARt mit 9600 Baud, 8 bit, 1 Stop bit no parity. Ich 
moechte einen Buchstaben empfangen, einen Pin schalten und einen 
Buchstaben zuruecksenden.

Initialisierung:
1
 #define BAUD 9600                           // define baud
2
#define BAUDRATE ((F_CPU)/(BAUD*16UL)-1)    // set baudrate value for UBRR
3
                  // set the CPU clock
4
5
// function to initialize UART
6
void uart_init (void)
7
{
8
  UBRRH=(BAUDRATE>>8);
9
  UBRRL=BAUDRATE;                         //set baud rate
10
  UCSRB|=(1<<TXEN)|(1<<RXEN);             //enable receiver and transmitter
11
  UCSRC|=(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);// 8bit data format
12
}
Senden:
1
void uart_transmit (unsigned char data)
2
{
3
   if(UCSRA & (1<<UDRE))         /* Senden, wenn UDR frei ist                    */
4
   {    UDR = data;               /* schreibt das Zeichen x auf die Schnittstelle */
5
   }
6
}
Empfangen:
1
unsigned char uart_recieve (void)
2
{
3
  
4
  while(!(UCSRA) & (1<<RXC));           // wait while data is being received
5
  return UDR; 
6
                          // return 8-bit data
7
  
8
}
Main:
1
int main (void)
2
{
3
  unsigned char LED;
4
  uart_init();                            // initialize UART
5
  DDRA = 0xFF;
6
  while(1)
7
  {
8
    LED=uart_recieve();   // save the received data in a variable
9
    
10
      switch (LED)
11
      {
12
    case 'a':
13
      LED = '0';
14
      PORTA |= (1<<PA0);
15
      uart_transmit('a');
16
      
17
      break;
18
    
19
    case 'A':
20
      LED = '0';
21
      PORTA &= ~(1<<PA0);
22
      uart_transmit('A');
23
      
24
      break;
Das Problem ist nun, es funktioniert mit dem ersten Buchstaben perfekt. 
(Verbindung ueber HTerm), sobald ich den zweiten sende wird der 
vorhergehende Buchstabe in einer endlosschleife vom uC gesendet.

von Theor (Gast)


Lesenswert?

Der Code ist unvollständig. Poste die gesamte main-Funktion, bitte.

Der soweit gepostete Code scheint das beschriebene Verhalten nicht zu 
erkären.

von Michael D. (sirs)


Lesenswert?

Löscht du denn deinen Puffer nach dem Empfang wieder?
Ja, mehr von der main wäre echt sehenswert.

von Jim M. (turboj)


Lesenswert?

Clemens K. schrieb:
1
while(!(UCSRA) & (1<<RXC)); 
2
//----^^-----^

Das hier ist ein übler Programmierfehler, der Dein Verhalten fast 
vollständig erklären könnte. Das "!" bindet stärker als das "&".

Richtig wäre:
1
while(!(UCSRA & (1<<RXC))); 
2
//           ^

von Dietrich L. (dietrichl)


Lesenswert?

Clemens K. schrieb:
> Senden:
1
void uart_transmit (unsigned char data)
2
 {
3
    if(UCSRA & (1<<UDRE))         /* Senden, wenn UDR frei ist */
4
    {    UDR = data;              /* schreibt das Zeichen x auf die  Schnittstelle */
5
    }
6
 }

Das hat zwar nichts mit dem Fehler "Dauersenden" zu tun, aber statt
1
    if(UCSRA & (1<<UDRE))         /* Senden, wenn UDR frei ist */
sollte da
1
    while (!(UCSRA & (1<<UDRE)))  /* warten bis UDR frei ist */
stehen.

In Deinen Fall können beim Senden Zeichen verloren gehen.

von Clemens K. (clemensk)


Lesenswert?

Jim M. schrieb:
> Clemens K. schrieb:
>
1
> while(!(UCSRA) & (1<<RXC));
2
> //----^^-----^
3
>
>
> Das hier ist ein übler Programmierfehler, der Dein Verhalten fast
> vollständig erklären könnte. Das "!" bindet stärker als das "&".
>
> Richtig wäre:
>
1
> while(!(UCSRA & (1<<RXC)));
2
> //           ^
3
>

Jup, das war es! Brilliant!

von Cyborg (Gast)


Lesenswert?

Clemens K. schrieb:
> Jup, das war es! Brilliant!

Brillianter wäre den Debugger zu benutzen. Dann kann man Fehler
selber finden. Wenn man trotzdem nicht weiter kommt, kann man
immer noch andere fragen.

von Theor (Gast)


Lesenswert?

Clemens K. schrieb:
> Jim M. schrieb:
>> Richtig wäre:
>>
1
>> while(!(UCSRA & (1<<RXC)));
2
>> //           ^
3
>>
>
> Jup, das war es! Brilliant!

Au wei. Hab ich nicht gesehen. Prima, Jim.

von Clemens K. (clemensk)


Lesenswert?

Cyborg schrieb:
> Clemens K. schrieb:
>> Jup, das war es! Brilliant!
>
> Brillianter wäre den Debugger zu benutzen. Dann kann man Fehler
> selber finden. Wenn man trotzdem nicht weiter kommt, kann man
> immer noch andere fragen.

Das habe ich sogar getan, ich bin mit jtag und dem avr dragon Zeile fuer 
Zeile durchgegangen und habe Code eingefuegt wie flushen des Speichers 
usw. Er ist immer nach aufrufen der uart recieve Funktion in die switch 
case gegangen. Das ist sehr untypisch, daher war mir bewusst das es 
irgendwo eine Kleinigkeit ist die ich uebersehen habe. Natuerlich bin 
ich dann durch die Forumssuche gegangen, aber die haeufigsten Probleme 
dort waren nur das es gar keine Datenuebertragung gibt. Klar, es ist 
vll. etwas verfrueht das Forum zu fragen, aber manchmal sieht ein 
aussenstehender meinen Fehler sofort und ich lerne dadurch schneller.

So, vielen Dank!

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.