Forum: Mikrocontroller und Digitale Elektronik Eigenartige ausgabe des UART an Mega32


von Jan S. (spongebob)


Lesenswert?

Moin!!!
Ich versuche gerade Daten per UART an meinen PC zu senden. Zum Senden 
vom Controller aus habe ich 8 Datenbits, 2 Stopbits und Parität disabled 
eingestellt.
Wenn ich nun beispielsweise eine 1 senden will und mit die empfangenen 
Werte im Terminal ansehe, liegt folgendes Bitmuster vor: 11100001.
Bei einer 2 -> 11100010
Bei einer 3 -> 11100011
und so weiter.
Ich habe echt keine Idee woran das liegen könnte.
Da mein Code noch sehr einfach ist, werde ich hier einfach mal meine 
Funktionen Posten:

Zuerst mein Hauptprogramm:
1
/*RS232.c*/
2
3
#include <avr/io.h>
4
5
int main(void)
6
{
7
  unsigned char data;
8
  data = 3;
9
  
10
  init_rs232();
11
  set_rs232_baud();
12
  
13
  while(!(UCSRA & (1<<UDRE)))
14
  {
15
  }
16
    UDR = data;
17
  
18
    while(1)
19
    {     
20
    }
21
}

Dann die Funktionen für die Initialisierung:
1
/*rs232_init.c*/
2
3
4
#include <avr/io.h>
5
6
#ifndef F_CPU
7
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 16000000"
8
#define F_CPU 16000000UL
9
#endif
10
11
#define BAUD 9600
12
#include <util/setbaud.h>
13
14
void init_rs232(void)
15
{
16
  /* UART Status/Control Register (A) */
17
  UCSRA = 0x00; 
18
  
19
  /* UART Control Register (B) */
20
  UCSRB = 0x00
21
  UCSRB |= (1<<TXEN);    //Transmitter Enable
22
  
23
  /* UART Control Register (C) */
24
  UCSRC = 0x00;
25
  UCSRC |= (1<<URSEL);  
26
        //Select bit:1 -> write to UCSRC 0 -> write to Baud rate Register
27
  UCSRC |= (1<<USBS);    //2 Stop Bits
28
  UCSRC |= ((1<<UCSZ1) | (1<<UCSZ0));
29
        //combined with UCSZ2 = 0 -> 8Bit data
30
  UCSRC &= ~(1<<URSEL);
31
  //Asynchronous Mode 8N2
32
}
33
34
void set_rs232_baud(void)
35
{
36
UBRRH = UBRRH_VALUE;
37
UBRRL = UBRRL_VALUE;
38
}

Ich hoffe mir kann hier irgendwer einen Tipp geben.

Grüße Jan

von troll (Gast)


Lesenswert?

Jan S. schrieb:
>   /* UART Control Register (C) */
>   UCSRC = 0x00;
>   UCSRC |= (1<<URSEL);
>         //Select bit:1 -> write to UCSRC 0 -> write to Baud rate
> Register
>   UCSRC |= (1<<USBS);    //2 Stop Bits
>   UCSRC |= ((1<<UCSZ1) | (1<<UCSZ0));
>         //combined with UCSZ2 = 0 -> 8Bit data
Das wird  so nichts. Wenn du UCSRC schreiben willst muss URSEL *bei 
jedem Schreibzugriff* gesetzt sein.

von Rumpel & Stilz (Gast)


Lesenswert?

Mir scheint, man sollte warten, bis das Byte effektiv gesendet wurde. So 
wird das Senderegister UDR immer erneut ueberschrieben.

von Jan S. (spongebob)


Lesenswert?

troll schrieb:
> Das wird  so nichts. Wenn du UCSRC schreiben willst muss URSEL *bei
> jedem Schreibzugriff* gesetzt sein.

Ok, wenn ich URSEL setze und danach nicht wieder zurück setze müsste es 
doch theoretisch gesetzt bleiben und bei jedem Schreibzugriff 1 sein.

Rumpel & Stilz schrieb:
> Mir scheint, man sollte warten, bis das Byte effektiv gesendet wurde. So
> wird das Senderegister UDR immer erneut ueberschrieben.

Ich habe das mit dem warten bis gesendet werden kann aus dem tutorial 
dieser Seite direkt nachprogrammiert. Eigentlich sollte doch alles ok 
sein, wenn ich folgendes Programmiere:
1
while(!(UCSRA & (1<<UDRE)))
2
  {
3
  }

oder???

von Karl H. (kbuchegg)


Lesenswert?

Jan S. schrieb:
> troll schrieb:
>> Das wird  so nichts. Wenn du UCSRC schreiben willst muss URSEL *bei
>> jedem Schreibzugriff* gesetzt sein.
>
> Ok, wenn ich URSEL setze und danach nicht wieder zurück setze müsste es
> doch theoretisch gesetzt bleiben und bei jedem Schreibzugriff 1 sein.

Nein.
Tu dir selbst einen Gefallen und benutze erst mal die Initiallisierung 
so, wie du sie im AVR-GCC-Tutorial/Der UART findest.


Irgendwann wirst du mal den entsprechenden Abschnitt im Datenblatt 
finden und lesen und dort auch nachlesen, was bei einem Lesezugriff 
tatsächlich passiert und warum du mittels

    UCSRC |= .....

nicht arbeiten kannst, bzw. wie die korrekte Vorgehensweise ist.

Mittels
  UCSRC |= (1<<URSEL);
hast du deine USART auf 1 Stopp-Bit, 5 Datenbit gestellt und die 
nachfolgenden Anweisungen ändern daran nichts mehr. Der Hauptgrund dafür 
ist, dass sie nicht das tun, was du denkst dass sie tun, weil man das 
UCSRC nicht einfach so auslesen kann. Im Datenblatt gibt es dazu sogar 
ein eigenes Kapitel.

von Jan S. (spongebob)


Lesenswert?

Moin!

Hab noch mal nach dem Kapitel geschaut und es gefunden. Nachdem ich mich 
jetzt noch genauer damit befasst habe, hab ich das richtige Senden jetzt 
endlich hinbekommen.

Danke für die hilfreichen Antworten!!!

Grüße Jan

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.