RS232 bei Atmega 16 Datenverlust

Gast #3215023
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
}
#3215045
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.

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