mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATMEGA88 UART seltsames Verhalten


Autor: Jürgen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
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 :-)
#define F_CPU 10000000UL //Takt in Hertz

#include <avr/io.h>
#include <avr/delay.h>
#include <avr/interrupt.h>

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


int main()
{ 
 DDRC  = 0xFF;        // Port C komplett Ausgang
 Uart0Init();           //UART initialisieren
 PORTC=0x00;

 while(1)      
 {
  data=UDR0;        //Wertzuweisung
  PORTC=~PORTC;                         //toggle
  _delay_us(data);                      //warte

 } // end while(1)
} //end main



//Routinen

void Uart0Init(void)      //UART-Initialisierung
{
    UBRR0H = (unsigned char)(myBRR0 >> 8);
    UBRR0L = (unsigned char)myBRR0; 
    UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0);
    UCSR0C = (3<<UCSZ00);  // 8-Bit Charaktersize  
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
2 Problemkreise
 while(1)      
 {
  data=UDR0;        //Wertzuweisung
  PORTC=~PORTC;                         //toggle
  _delay_us(data);                      //warte

 } // end while(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.

  _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

Autor: Gauchi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was passiert denn, wenn du das Zeichen ein zweites Mal sendest?

Autor: Kai (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jürgen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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??

Autor: Jürgen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.