Forum: Mikrocontroller und Digitale Elektronik USART1 ISR mit Atmega162


von xp3 (Gast)


Lesenswert?

Hi Leute, ich wollte in meinem Programm warten, bis ein Zeichen an
USART1 empfangen wird und darauf reagieren. Hab es ausprobiert, bis
jetzt aber ohne Erfolgt.
Also zum Anfang erlaube ich interrupts
sei();
Und meine ISR sieht folgendermaßen aus:
ISR(USART1_RXC_vect) // USART1, Rx Complete verctor: 21
{
 printf("USART1 ISR ok\t");
}

Das was ich vom PC aus an USART1 sende, kommt auch am µC an. Jedoch
wird  die ISR nicht ausgeführt. Muss man sonst was beachten? Ich wollte
eigentlich beim Empfang eines Zeichens in die ISR springen und da
weiteren Zeichen einlesen.

von Der inoffizielle WM-Rahul (Gast)


Lesenswert?

>printf("USART1 ISR ok\t");
<Sarkasmus>
Sowas gehört auch unbedingt in eine ISR...
</Sarkasmus>

Hast du die Interrupt-Freigabe-Flags (RXCIE und TXIE) und die
UART-Freigabe-Flags (RXC und TXC) freigegeben?
Wirf mal ein Blick ins Datenblatt. Da sind Besipiele für den
Poll-Betrieb angegeben.
Und sonst würde auch ein grösseres Stück deines Codes etwas bringen.

von xp3 (Gast)


Lesenswert?

Ja hmm, das sollte auch ein Test sein, ob die ISR funktioniert.
Die Datenkommunikation zwischen dem PC und dem µC ist auch i.O., also
was USART1 Initialisierung angeht. Nur der Einsprung in die ISR geht
nicht.
Aus dem Datenblat werde ich auch nicht schlauer, weil da nur ein
Beispiel zu, externen IR in assembler vorhanden ist.

von Der inoffizielle WM-Rahul (Gast)


Lesenswert?

Zeig doch mal die Initialisierung!

von xp3 (Gast)


Lesenswert?

void usart1_init(void)
{
  unsigned int a= 103;
  UBRR1H = a<<8;
  UBRR1L = a;
  UCSR1A = 0x00;
  UCSR1B = (1<<RXEN1) | (1<<TXEN1);
  UCSR1C = (1<<UCSZ11) | (1<<UCSZ10) | (1<<URSEL1);
}

Hier :)
Und wie gesagt, ich kann über usart1 Daten senden/empfangen.

von Der inoffizielle WM-Rahul (Gast)


Lesenswert?

>UCSR1B = (1<<RXEN1) | (1<<TXEN1);

Muss noch erweitert werden:
UCSR1B = (1<<RXEN1) | (1<<TXEN1) | (1<<RXCIE); // für
Empfangsinterrupt

Wirf mal einen Blick auf die USART-Register auf Seite 185ff.

von Der inoffizielle WM-Rahul (Gast)


Lesenswert?

>UCSR1B = (1<<RXEN1) | (1<<TXEN1) | (1<<RXCIE);

Muß natürlich

>UCSR1B = (1<<RXEN1) | (1<<TXEN1) | (1<<RXCIE1);

oder so ähnlich heissen.

von xp3 (Gast)


Lesenswert?

Ich check das irgendwie nciht. Hab jetzt so initialisiert:
void usart1_init(void)
{

  unsigned int a= 103;
  UBRR1H = a<<8;
  UBRR1L = a;
  UCSR1A = (1 << RXC1);
  UCSR1B = (1<<RXEN1) | (1<<TXEN1)   | (1<<RXCIE1);
  UCSR1C = (1<<UCSZ11) | (1<<UCSZ10) | (1<<URSEL1);
 }

Als Test, will ich im Hauptprogramm eine LED leuchten lassen (die FKT
funzt)

  sei();
  char a;
  unsigned char dummy;
  ISR (USART1_RXC_vect)
  {
    cli();
    eia485_led_on();
                while (UCSR1A & (1<<RXC1) ) dummy = UDR1;
  }

Und das klappt immer noch nicht :(
Hab jetzt  while (UCSR1A & (1<<RXC1) ) dummy = UDR1; reingetan, wegen
der Beschreibung 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.

von xp3 (Gast)


Lesenswert?

Ahh ok,. habs jetzt hinbekommen!
Vielen Dank für deine Hilfe @ WM-Rahul.
War ein Fehler ganz wo anders (DAO-Fehler).

von André K. (freakazoid)


Lesenswert?

Hi,

> unsigned int a= 103;
> UBRR1H = a<<8;
> UBRR1L = a;
soll wohl so nicht sein, oder?

Grüße, Freakazoid

von xp3 (Gast)


Lesenswert?

und warum nicht?
Beim 16 MHz Quarz und 9600 Baud ist es richtig. Funktioniert ja auch.

von Der inoffizielle WM-Rahul (Gast)


Lesenswert?

naja, es sollte
> UBRR1H = a>>8;
heissen...

von André K. (freakazoid)


Lesenswert?

Lesbarer wäre auch so was:

#define Crystal     16000000
#define BAUD        9600
#define UBRR        Crystal/(16*BAUD)-1

...

Damit rechnet der Preprozessor und nicht Du (nicht so fehleranfällig).
Ein Wert von '103' mitten im Quellcode und dann noch als 'a'
deklariert ist unschön. Außerdem läßt sich das Programm so schnell an
einen neuen Quarz anpassen.

Grüße, Freakazoid

von Der inoffizielle WM-Rahul (Gast)


Lesenswert?

#define UBRR        Crystal/(16_L_*BAUD)-1

UBRR1H = (unsigned char) (UBRR>>8);
UBRR1L = (unsigned char) UBRR;

Um es ganz korrekt zu machen...
Ist aber auch im Datenblatt beschrieben...

von André K. (freakazoid)


Lesenswert?

@Der inoffizielle WM-Rahul:

Hatte das DB gerade nicht hier, aber dafür war ich schon nah dran. 103
ist jedenfalls ungut.

Grüße, Freakazoid

von xp3 (Gast)


Lesenswert?

Hab aber 103 nach der Formel da oben berechnet. Und Baud wird von mir
sicherlich nicht geändert oO

von André K. (freakazoid)


Lesenswert?

Wie geasgt, UBRR ist auch vom Quarz abhängig.
Letztlich ist es jedem selbst überlassen was er
schon vorher ausrechnet, allerdings ist so ein Code
eine ungünstige Bedingung für das Debugging - und
das wurde ja hier gefordert.

Grüße, Freakazoid

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.