Hallo,
ich habe ein Problem mit der UART Schnittstelle an einem ATmega168. Da
bin ich wohl nicht der einzige, aber die bisherigen Beitrage haben mir
leider nicht weitergeholfen...
Zuerst zur Hardware: am RX der UART Schnittstelle hängt ein DCF Modul,
welches mir eine Zeit senden sollte. Das manual sagt folgendes:
______________________________________________________________________
__
Antworten des Funkuhrmoduls
Schnittstellenparameter
Geschwindigkeit: 300 bps
Datenbits: 7
Paritätsbit: gerade
Stoppbits: 2
Funktion der Datenausgabe
Eine Antwort des Funkuhrmoduls besteht aus einer Folge von ASCII-Zeichen
und einem abschließenden Zeichen „CR“.
Der Wertevorrat ist auf die Ziffern 0 ... 9 und die Zeichen : ; < = > ?
beschränkt. Die Informationen sind stets in den niederwertigen vier Bits
enthalten. Bit4 und Bit5 eines jeden geantworteten Zeichens sind stets
gleich Eins, Bit6 ist gleich Null und Bit7 ist immer entsprechend der
geraden Parität des Zeichens gesetzt. Damit ergeben sich die
obengenannten 16 Zeichen des Wertevorrates.
______________________________________________________________________
__
Das RX Signal an Pin 30 des ATmega168 habe ich mir angeschaut (siehe
Anhang). Sieht meiner Meinung nach ok aus, Daten kommen und die 300bps
scheinen auch zu stimmen (kleinste Pulsbreite von 3.33ms).
Nun zum Code: In meiner main routine setze ich erst ein paar Ausgänge,
welche ich für andere Zwecke brauche (sollte wohl keinen Einfluss auf
die UART haben), dann kommt der Aufruf der UART init routine und
schliesslich warte ich auf ein Zeichen (die oberen 4bit lösche ich,
siehe Beschreibung DCF Modul oben)...
1 | #define F_CPU 8000000
|
2 | #define BAUD 300
|
3 | #define UBRR F_CPU/16/BAUD-1
|
4 |
|
5 | #include <avr/io.h>
|
6 | #include <util/delay.h>
|
7 | #include <stdint.h>
|
8 | #include "functions.c"
|
9 |
|
10 |
|
11 | int main (void) {
|
12 | DDRB |= (1 << DDB0); // Setzen des Pins 0 als Ausgang
|
13 | DDRC = 0xff; // 0xff: alle Pins Ausgänge
|
14 | DDRD |= (1 << DDD2) | (1 << DDD3) | (1 << DDD4) | (1 << DDD5) | (1 << DDD6) | (1 << DDD7);
|
15 | // Pins 2-7 Ausgänge
|
16 |
|
17 | init_USART0(UBRR); // initialisiere USART0
|
18 |
|
19 | while ('\r' != (receive_1byte_USART0() & 0x0f)) {}
|
20 |
|
21 | ... weiterer Verlauf des Programms...
|
Das Problem ist nun, dass mein Programm nur weiterläuft wenn ich auf
eine 0 warte. Bei allen anderen Zahlen und auch dem "CR" (auf welches
ich eigentlich warten wollte) bleibt es in der while Schleife hängen.
Hat jemand eine Idee wie ich das debuggen könnte?
Hier noch meine init- und Empfangsroutine:
1 | void init_USART0(unsigned int baud)
|
2 | {
|
3 | UBRR0 = baud; // Set Baudrate
|
4 | UCSR0C = (1<<USBS0)|(2<<UCSZ00)|(2<<UPM00); // 2 Stop Bits, Character Size 7 bit, Even Parity
|
5 | UCSR0B = (1<<RXEN0); // Receiver Enable
|
6 | }
|
7 |
|
8 | unsigned char receive_1byte_USART0(void)
|
9 | {
|
10 | loop_until_bit_is_set(UCSR0A, RXC0);
|
11 | return UDR0;
|
12 | }
|
Vielen Dank schon mal!