Forum: Mikrocontroller und Digitale Elektronik RS232 bei Atmega 16 Datenverlust


von Jonko (Gast)


Lesenswert?

Hallo,
ich habe meinen Atmega 16 mit einem rs232 adapter mit meinem Pc 
verbunden. Ich schicke über HTerm Ascii Zeichen an den Controller. 
Verwendet wird ein 8 MHz Quartz(extern(Eingestellt 
ist:EXTHIFXTALRES_16KCK_64MS)). Der geschickte String soll auf Port B 
ausgegeben werden, wo ich LED's zur besseren Ansicht angebracht habe. 
Schicke ich beispielsweise "1111" über HTERM an den Controller, leuchten 
alle LED's, schicke ich "11111111111111111" leuchtet eine weniger. 
Schicke ich die gleiche Anzahl an einsen nochmal leuchten andere 
LED's... Sieht mir so aus als wäre die Übertragung ungenau und Zeichen 
würden abhanden kommen. Ich hatte das Projekt eigentlich schon 
aufgegeben, also verzeiht mir wenn ich nicht mehr auf den aktuellsten 
Stand bin. Ich freu mich dennoch über jeden Tipp :) Dabei gibt es noch 
den Quellcode der benutzt wird:
1
#include <avr/io.h>
2
3
#define FOSC 8000000 // Set clock Speed in Hz
4
5
#define BAUD 9600 // Set baud rate
6
7
#define UBRR_Value FOSC/16/BAUD-1 // Set baud rate value in baud rate register
8
9
 
10
11
void USART_Init( unsigned int ubrr)
12
13
{
14
15
UBRRH = (unsigned char)(ubrr>>8); // Set baud rate in high- and low-register
16
17
UBRRL = (unsigned char)ubrr;
18
19
UCSRC = (1<<UCSZ1)|(1<<UCSZ0); // Set frame format: 8data, 1stop bit
20
21
UCSRB = (1<<RXEN)|(1<<TXEN); // Enable receiver and transmitter
22
23
}
24
25
26
void USART_Transmit(unsigned char data)
27
28
{
29
30
while ( !( UCSRA & (1<<UDRE)) ); // Wait for empty transmit buffer
31
32
UDR = data; // Put data into buffer, sends the data
33
34
}
35
36
37
unsigned char USART_Receive(void)
38
39
{
40
41
while ( !(UCSRA & (1<<RXC)) ); // Wait for data to be received
42
43
return UDR; // Get and return received data from buffer
44
45
}
46
47
48
void USART_Flush(void) // Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger Werte)
49
50
{
51
52
unsigned char dummy;
53
54
while (UCSRA & (1<<RXC))
55
56
dummy = UDR;
57
58
}
59
60
61
void main( void )
62
63
{
64
65
unsigned char data;
66
67
USART_Init(UBRR_Value); // Init UART
68
69
USART_Flush(); // Flush Receive-Buffer
70
71
DDRA = 0xFF; // alle PINs an PortB als Ausgänge
72
73
while(1)
74
75
{
76
77
USART_Transmit(data = USART_Receive()); // receive on byte, send it
78
79
PORTA = data; // and write to Port B
80
81
}
82
83
}

von Karl H. (kbuchegg)


Lesenswert?

> UCSRC = (1<<UCSZ1)|(1<<UCSZ0); // Set frame format: 8data, 1stop bit


Du beschreibst hier nicht das UCSRC Register, sondern zerstörst dir den 
Inhalt von UBRRH. Sprich du verstellst dir hier unabsichtlich die 
Baudrate.

Tu dir selbst einen Gefallen und nimm immer zuerst die Richtung µC->PC 
in Betrieb. Denn vom PC weißt du, dass dessen Baudrateneinstellung 
korrekt ist. Wenn am PC, im Terminal-Programm nicht das erscheint, was 
du am µC wegschickst, dann kann das Problem immer nur in einem 
Baudratenproblem am µC liegen. Damit hast du diesen Teil erst mal 
getestet und hast dadurch eine gewisse Sicherheit, dass bei 
Empfangsproblemen am µC die Baudrate erst mal schuldlos ist.
1
int main()
2
{
3
  unsigned char data;
4
5
  DDRA = 0xFF; // alle PINs an PortB als Ausgänge
6
  USART_Init(UBRR_Value); // Init UART
7
8
  USART_Transmit( 'x' );
9
10
  while(1)
11
  {
12
    ...
13
}

Ach ja. Du musst das URSEL Bit setzen um beim Beschreiben von UCSRC auch 
wirklich ins UCSRC zu schreiben und nicht uns UBRRH. SIehe Datenblatt, 
Kapitel USART, die Registerbeschreibung.

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.