ATMEGA88 UART seltsames Verhalten

Gast #1808515
Lesenswert?

Hallo!
Also vorweg muß ich sagen, daß ich noch nicht sehr erfahren bin mit den 
ATMEGAs..Ich verwende das STK500.
Mein ursprüngliches Programm habe ich nun auf das wesentliche Problem 
reduziert.
Ich möchte ein Signal erzeugen, das man per serieller Schnittstelle 
abändern kann.
Ich denke, daß ich hier einen grundlegenden Fehler gemacht habe, nur 
welchen?? Ich bin schon seit Tagen damit beschäftigt!


Nach dem Start ist auf  dem Oszilloskop das Rechtecksignal zu sehen wie 
es sein soll.
Sobald ich nun ein Zeichen sende, hält der Controller den Pegel 
(beliebig high/low). Er scheint irgendwo hängen zu bleiben.. Nur wo, 
warum?
Ich habe dann mal geguckt was passiert wenn ich die LEDs so ansteuer:
1
PORTC=UDR0;              //Bitkombination darstellen
hier gibt es kein Problem. Die LEDs werden je nach empfangenem Zeichen 
angesteuert.

Wo ist nun mein Fehler???
Würde mich sehr freuen, denn so langsam wird es frustrierend :-)
1
#define F_CPU 10000000UL //Takt in Hertz
2

3
#include <avr/io.h>
4
#include <avr/delay.h>
5
#include <avr/interrupt.h>
6

7
volatile unsigned char data;
8
#define myBRR0 64   //9600 bps 10MHz
9
void Uart0Init(void);
10

11

12
int main()
13
{ 
14
 DDRC  = 0xFF;        // Port C komplett Ausgang
15
 Uart0Init();           //UART initialisieren
16
 PORTC=0x00;
17

18
 while(1)      
19
 {
20
  data=UDR0;        //Wertzuweisung
21
  PORTC=~PORTC;                         //toggle
22
  _delay_us(data);                      //warte
23

24
 } // end while(1)
25
} //end main
26

27

28

29
//Routinen
30

31
void Uart0Init(void)      //UART-Initialisierung
32
{
33
    UBRR0H = (unsigned char)(myBRR0 >> 8);
34
    UBRR0L = (unsigned char)myBRR0; 
35
    UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0);
36
    UCSR0C = (3<<UCSZ00);  // 8-Bit Charaktersize  
37
}
#1808524
Lesenswert?

2 Problemkreise
1
 while(1)      
2
 {
3
  data=UDR0;        //Wertzuweisung
4
  PORTC=~PORTC;                         //toggle
5
  _delay_us(data);                      //warte
6

7
 } // end while(1)

1
  data=UDR0;        //Wertzuweisung

du kannst nicht einfach UDR0 auslesen. Du musst schon vorher fragen, ob 
auch ein Zeichen eingetroffen ist. UDR0 wird durch das Auslesen 
gelöscht, es ist nicht so, dass das zuletzt empfangene Zeichen da ewig 
erhalten bleibt.

1
  _delay_us(data);                      //warte
du sollst niemals eine Variable an _delay_us oder _delay_ms übergeben. 
Die beiden _delay Funktionen sind wesentlich darauf angewiesen, dass der 
Optimizer den kompletten Aufruf in eine fixe Anzahl von 
Schleifendurchläufen optimieren kann. Nur dann stimmen die Zeiten. 
Zumindest so einigermassen.


Zum Thema UART auslesen:
AVR-GCC-Tutorial
Da gibt es einen Abschnitt über UART. Und auch einen über _delay_xx

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