www.mikrocontroller.net

Forum: Compiler & IDEs USART probleme mega162


Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich versuche gerade, die beiden USARTs vom Mega162 zum laufen zu 
bringen. Folgendes Problem:
Wenn ich beide USARTs benutzen will, sendet er nur einmal 'a', nachdem 
ich spannung anlege (also den uC einschalte). Wenn ich usart0_init(); 
auskommentiere, sendet er brav alle 2sec 'a'.
Das CLCKDV fusebit ist deaktiviert. Ich arbeite mit externem 8mhz quarz.
Hier mal mein Code:
void usart0_init(void)
{
  int ubrr0 = (F_CPU / 16 / BaudRate - 1);          // Baudrate UART0 einstellen  
  UBRR0H = (unsigned char)(ubrr0>>8);
  UBRR0L = (unsigned char)ubrr0;
         
  UCSR0C = (1<<URSEL0)|(3<<UCSZ00);              // UART0 Frame Format einstellen: 8data, 1 Stop-bit, keine Parity 
  UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1 << RXCIE0);        // UART0 Receiver und Transmitter einschalten
}

void usart1_init(void)
{    
  int ubrr1 = (F_CPU / 16 / BaudRate - 1);          // Baudrate UART1 einstellen  
  UBRR1H = (unsigned char)(ubrr1>>8);
  UBRR1L = (unsigned char)ubrr1;

  UCSR1C = (1<<URSEL1)|(3<<UCSZ10);          // UART1 Frame Format einstellen: 8data, 1 Stop-Bit, keine Parity
  UCSR1B = (1<<RXEN1)|(1<<TXEN1)|(1<<RXCIE1);          // UART1 Receiver und Transmitter einschalten 
}


void usart0_putc(uint8_t c)
{
  while (!(UCSR0A & (1<<UDRE0)));
  UDR0 = c;
}

void usart1_putc(uint8_t c)
{
  while (!(UCSR1A & (1<<UDRE1)));
  UDR1 = c;
}


int main(void)
{
  usart1_init();
  usart0_init();
  sei();
  
  
  while (1)
  {    
    usart1_putc('a');
    _delay_ms(1000);
    usart0_putc('b');
    _delay_ms(1000);
  }  
}

Ich schau mit hyperterminal nur, was von USART1 gesendet wird, was bei 
USART0 rauskommt weiß ich nicht.

mfg

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich das sei(); ausklammere, funktioniert das programm einwandfrei. 
Gibt es dafür eine erklärung?

mfg

Autor: Ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aktiviert das hier nicht den uart-Interrupt?

1<<RXCIE1


wenn du keine interruptfunktion implementierst dan darfst du den auch 
nicht einschalten

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja, der RXCIE1 ist eben eingeschaltet, also darf ich doch auch die 
interrupts global mit sei(); aktivieren.

mfg

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus wrote:
> ja, der RXCIE1 ist eben eingeschaltet, also darf ich doch auch die
> interrupts global mit sei(); aktivieren.
Dann musst Du aber auch einen Interrupt Handler haben, und der fehlt bei 
Dir oben! Ohne Handler gibt's bei jedem Auftreten des Interrupts einen 
Reset.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ob da jetzt noch ein Handler (du meinst eine ISR, oder?) im programm ist 
oder nicht, sollte keinen unterschied machen. Außerdem würde diese eh 
nicht ausgeführt werden, da ich nichts an den uC sende. Er soll ja nur 
'a' und 'b' ausgeben.

mfg

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, gerade nochmal ein bisschen im Forum gewühlt, da findet sich ein 
Zitat aus dem Datenblatt:
"When the Receive Complete Interrupt Enable (RXCIE) in UCSRB is set, the
USART Receive Complete Interrupt will be executed as long as the RXC
Flag is set (provided that global interrupts are enabled). When
interrupt-driven data reception is used, the receive complete routine
must read the received data from UDR in order to clear the RXC Flag,
otherwise a new interrupt will occur once the interrupt routine
terminates."

Man muss also doch einen Handler im Code haben, in dem der UDR0/1 dann 
ausgelesen wird. Allerdings dürfte bei mir diese ISR ja garnicht 
aufgerufen werden, da ich garnichts an den uC sende. Wird sie aber 
trotzdem (und zwar willkürlich), wenn die pins eines USARTs in der luft 
hängen. Erst wenn ich beide USARTs mit einem MAX232 verbinde, werden die 
ISRs nicht ausgeführt. Ist das normal? Könnte man das Problem auch mit 
Pullups/Pulldowns an den Portpins lösen? Ich will nämlich, dass der code 
auch läuft, wenn mal nicht beide USARTs verbunden sind.

mfg

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ist das normal?

Offene Pins floaten - sprich sie haben keinen definierten Eingangspegel.
Dann braucht nur eine fallende Flanke detektiert werden, und schon geht 
der Controller davon aus, dass etwas empfangen wurde.
Wenn du es sowieso nicht brauchst, schmeiss das (1<<RCXIE) einfach raus.

Autor: Markus (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ja, das mit dem undefinierten eingangspegel ist mir schon klar, ich war 
nur verwundert, weil ich dieses problem bisher bei noch keinem anderen 
AVR hatte.
RXCIE rausschmeißen kann ich auch nicht, da ich diesen interrupt schon 
brauche (das mit dem 'a' und 'b' senden war ja nur ein kleines 
testprogramm, nicht die eigentliche anwendung).

In der eigentlichen Anwendung kommt an den einen USART ein xbee-modul 
und an den anderen USART der PC. Ich möchte eben nicht, dass ständig ein 
interrupt ausgelöst wird, wenn das xbee-modul mal nicht angeschlossen 
ist.

Am USART1 hängt ein MAX232, der die Pegel von RX und TX sauber auf 5V 
hält, hier wird kein Interrupt ausgelöst. Am USART0 hängt das xbee-modul 
(TX vom uC über einen Spannungsteiler an RX vom xbee, RX vom uC direkt 
an TX vom xbee), das auf 3,3V Basis arbeitet, deshalb auch der 
spannungsteiler. RX vom uC würde also, wenn kein xbee-modul 
angeschlossen ist, in der Luft hängen. Kann ich den RX also nicht 
einfach mit einem Pullup auf 3,3V ziehen?

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>RXCIE rausschmeißen kann ich auch nicht, da ich diesen interrupt schon
>brauche (das mit dem 'a' und 'b' senden war ja nur ein kleines
>testprogramm, nicht die eigentliche anwendung).

Das war auch nur für den Fall gemeint, wo du noch keinen 
Interrupt-Handler für den Interrupt hast.

>Ich möchte eben nicht, dass ständig ein interrupt ausgelöst wird, wenn das 
>xbee-modul mal nicht angeschlossen ist.
>Kann ich den RX also nicht einfach mit einem Pullup auf 3,3V ziehen?

Ja.

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.