Forum: Mikrocontroller und Digitale Elektronik Atmega8 scheint UART zu empfangen


von Gerrit (Gast)


Lesenswert?

Hallo zusammen,

ich habe das myAVR MK2 bei mir im Einsatz. Nun habe ich laut Datenblatt 
versucht Text zu senden bzw. zu empfangen.

Der Versand einer Zeichenkette funktioniert. Seltsam ist nur, dass der 
Terminal vor der Empfangenen Zeichenkette immernoch ein kryptisches 
Zeichen darstellt.

Viel irritierender finde ich aber, dass ich LEDs am PORTC einschalte, 
bevor ich in meinen while(1) gehe. In der Schleife rufe ich dann die 
folgende Funktion auf:

unsigned char USART_Receive( void )
{
    /*
    Wait for data to be received
    */
    while ( !(UCSRA & (1<<RXC)) );
    /*
    Get and return received data from buffer
    */
    return UDR;
}

Den Rückgabewert setze ich dann als PORTC:

    unsigned char zeichen = USART_Receive();
    PORTC = zeichen;

Wenn ich den AVR nun resette, gehen die LEDs an und gleich wieder aus. 
Und das ohne, dass ich den Terminal auch nur geöffnet, geschweige 
verbunden habe.

PS: Ich hatte auch versucht das empfangene Zeichen gleich wieder zu 
senden. Das ist dann aber ebenfalls ein kryptisches Zeichen, welches 
immer und immer wieder im Terminal ankommt.

Hat jemand eine Idee??

von Stefan F. (Gast)


Lesenswert?

Zeige mal das ganze Programm.
Hast du ein Oszilloskop oder Logiktester?
Kannst du den RxD Pin mal fest auf High legen, damit er ganz sicher 
nichts empfängt?

von Karl M. (Gast)


Lesenswert?

Hallo Gerrit,

aus meinen Anfängen habe ich auch noch solch ein Board herumliegen.

Wie sieht dein Makefile aus und welchen AVR µC CPU hast Du verwendet ?

von Clemens L. (c_l)


Lesenswert?

Gerrit schrieb:
> Seltsam ist nur, dass der Terminal vor der Empfangenen Zeichenkette
> immernoch ein kryptisches Zeichen darstellt.

Welches?  ÿ?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?


: Bearbeitet durch Moderator
von Gerrit (Gast)


Lesenswert?

Ich habe das MK2 mit einem Atmega8.

von Gerrit (Gast)


Lesenswert?

Ja, so sieht das Zeichen aus, welches als erstes geschickt wird.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Gerrit schrieb:
> Ja, so sieht das Zeichen aus, welches als erstes geschickt wird.
Das ist kein Zeichen, sondern ein simpler Pegelwechsel an der 
RX-Leitung.

Du solltest da auch einen Übertragungsfehler "Framing Error" bekommen, 
weil da kein Stopbit übertragen wird. Du solltest also hier diese 
Fehlerbits auch noch auswerten, wenn dein Protokoll ein solches 
Startup-Verhalten nicht ignorieren kann...

von Gerrit (Gast)


Lesenswert?

Okay, das komische Bit zu Beginn, war der Druck der Reset-Tast.

Mein Code ist nun wie folgt:
1
#define F_CPU 3686400// Clock Speed
2
#define BAUD 9600
3
#define MYUBRR F_CPU/16/BAUD-1
4
5
#include <avr/io.h>
6
#include "util/delay.h"
7
8
9
void USART_Init(unsigned int ubrr) {
10
  /* Set baud rate */
11
  UBRRH = (unsigned char)(ubrr>>8);
12
  UBRRL = (unsigned char)ubrr;
13
  /* Enable receiver and transmitter */
14
  UCSRB = (1<<RXEN)|(1<<TXEN);
15
  /* Set frame format: 8data, 2stop bit */
16
  UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
17
}
18
19
unsigned char receiveByte(void) {
20
  while ( !(UCSRA & (1<<RXC)) )       /* Wait for incoming data */
21
  return UDR;                                /* return register value */
22
}
23
24
void USART_Transmit( unsigned char data )
25
{
26
  /* Wait for empty transmit buffer */
27
  while ( !( UCSRA & (1<<UDRE)) )
28
  ;
29
  /* Put data into buffer, sends the data */
30
  UDR = data;
31
}
32
33
void printString(const char myString[]) {
34
  uint8_t i = 0;
35
  while (myString[i]) {
36
    USART_Transmit(myString[i]);
37
    i++;
38
  }
39
}
40
41
int main(void)
42
{
43
    /* Replace with your application code */
44
  
45
  USART_Init(MYUBRR);
46
  unsigned char zeichen;
47
  
48
  printString("Welcome AVR!\r\n");
49
  
50
  DDRC = 0b11111111;
51
  PORTC = 0b11111111;
52
  
53
    while (1) 
54
    {
55
    zeichen = receiveByte();
56
    PORTC= zeichen;
57
    printString("Test\r\n")
58
    _delay_ms(200);
59
    }
60
  
61
  return 1;
62
}
Seltsam ist halt, dass die leuchtenden LEDs kurz angehen und gleich 
wieder aus.

von Georg G. (df2au)


Lesenswert?

Schaltbild?

von Gerrit (Gast)


Lesenswert?

Wie bereits geschrieben, habe ich das MK2 mit mySmartUsb MK2 im Einsatz. 
Heißt, das ist alles verkabelt und der SmartUsb steht auf Datenmodus. An 
PORTC sind nur LEDs.

von Georg G. (df2au)


Lesenswert?

Gerrit schrieb:
> PORTC sind nur LEDs.

LED gegen Masse oder gegen VCC?

von Alex P. (alex2203)


Lesenswert?

Ich tippe mal ganz schwer, das die LED's gegen Masse sind. Somit ist 1 
gleich 0 und umgekehrt.

Schmeiss das hier mal raus

  DDRC = 0b11111111;
  PORTC = 0b11111111;


und stattdessen:

  DDRC = 0xFF;
  PORTC = 0x00;

von Gerrit (Gast)


Lesenswert?

Guten Abend zusammen,

ich habe mir das nun noch mal in Ruhe angesehen. Ich habe meine Main() 
wie folgt geändert:
1
int main(void)
2
{
3
    /* Replace with your application code */
4
  
5
  USART_Init(MYUBRR);
6
  unsigned char zeichen;
7
  
8
  printString("Welcome AVR!\r\n");
9
  
10
  DDRC = 0xFF;
11
  PORTC = 0xFF;
12
  _delay_ms(1000);
13
  
14
    while (1) 
15
    {
16
    zeichen = receiveByte();
17
    PORTC = PORTC << 1;
18
    //PORTC= zeichen;
19
    //printString("Test\r\n")
20
    _delay_ms(200);
21
    }
22
  
23
  return 1;
24
}

Die Funktion zum Empfangen ist:
1
unsigned char receiveByte(void) {
2
  while ( !(UCSRA & (1<<RXC)) )       /* Wait for incoming data */
3
  return UDR;                                /* return register value */
4
}

Es gehen nun alle LEDs an. Sobald ich in den Loop komme, geht eine nach 
der anderen LED aus. Woraus ich schließe, dass die 
receiveByte()-Funktion nicht auf das Bit wartet bzw. das Bit scheinbar 
gesetzt ist.

Ich habe auch versucht in der Init das RXC Bit auf 0 zu setzen, änderte 
am Verhalten auch nichts:
1
UCSRA &= ~(1 << RXC);

von Gerrit (Gast)


Lesenswert?

Gelöst: Fehlendes Semikolon in while() in receiveByte();

von Stefan F. (Gast)


Lesenswert?

Interessant finde ich, dass der Compiler diese Stelle nicht mit einem 
Syntaxfehler bemängelt hat.

von Georg G. (df2au)


Lesenswert?

Stefan U. schrieb:
> Interessant finde ich, dass der Compiler diese Stelle nicht mit einem
> Syntaxfehler bemängelt hat.

Warum sollte er? War alle syntaktisch korrekt.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Georg G. schrieb:
> War alle syntaktisch korrekt.
Er hat eben nur nicht gewartet, bis ein Zeichen da ist...

Gerrit schrieb:
1
 while ( !(UCSRA & (1<<RXC)) )
2
 return UDR;
Dort steht: "solange nicht fertig, gib das UDR zurück"...

: Bearbeitet durch Moderator
von Georg G. (df2au)


Lesenswert?

Lothar M. schrieb:
> Er hat eben nur nicht

Genau das ist meist das Problem, der Compiler versteht einfach den 
Programmierer nicht richtig. Für viele dieser Missverständnisse hat ein 
guter Compiler Warnungen, die ein defensiver Programmierer auch ernst 
nimmt. Aber leider funktioniert das nicht immer. Und viele Programmierer 
finden es auch toll, wenn sie jede überflüssige Klammer, jeden Kommentar 
weglassen.

> Dort steht: "solange nicht fertig, gib das UDR zurück"...
Und das ist dummerweise das genaue Gegenteil dessen, was beabsichtigt 
war :-)

: Bearbeitet durch User
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.