Forum: Mikrocontroller und Digitale Elektronik ATMEGA88 UART seltsames Verhalten


von Jürgen (Gast)


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
}

von Karl H. (kbuchegg)


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

von Gauchi (Gast)


Lesenswert?

Was passiert denn, wenn du das Zeichen ein zweites Mal sendest?

von Kai (Gast)


Lesenswert?

Hallo,

wo ist denn Deine Interruptroutine für den Empfang auf UART0? Nehme an 
das ist das Problem.

Probier mal:
UCSR0B = (1<<RXEN0) | (1<<TXEN0); //ohne Interrupt
//UCSR0C ist nicht notwendig, da 'Initial Value' nach Reset

VG
Kai

von Jürgen (Gast)


Lesenswert?

Sorry.. würde meinen Beitrag gerne editieren..

Also das funktioniert nun doch!! Aber mein ursprüngliches Programm 
verwendet eine ISR für den Timer. Wenn ich nun in dem Programm oben 
Interrupts zulasse, dann bleibt der Controller hängen.. Scheinbar in 
einem Interrupt ausgelöst durch UART??

von Jürgen (Gast)


Lesenswert?

:-)

Super!! Das war´s.. Dein Beitrag und mein vorheriger Beitrag haben sich 
überschnitten..
Mann, bin ich glücklich!!!
Vielen Dank!!
Das kommt davon, wenn man sein Programm zusammenwürfelt...
Super!
Bin echt begeistert wie schnell man hier Hilfe bekommt!
TOP!

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.