Forum: Mikrocontroller und Digitale Elektronik Uart IRQ auf dem ATtiny87


von Michael Nienhaus (Gast)


Lesenswert?

Hallo,

nach einigen Versuchen wende ich mich nun an Euch. Ich habe einen 
ATtiny87 und verwende dabei die UART.

Senden und Empfangen funktioniert, jedoch nur pollend. Danach habe ich 
versucht dies Interrupt-gesteuert zu realisieren. Beim Senden ging das 
ohne Probleme, jedoch finde ich fürs Empfangen keinen Interrupt.Vektor.

Die UART ist bei dem ATtiny87 im LIN-Controller integriert. Folgendes 
habe ich Initialisiert:

1
void UartInit(){
2
  LINCR = (1<<LENA) | (1<<LCMD0) | (1<<LCMD1) | (1<<LCMD2); // enable UART in 8bit Full Duplex Mode
3
  unsigned int  ubrr = (F_CPU/32/BAUDRATE)-1;    //calculate Baudrate
4
  LINBRRH = ubrr >> 8;
5
  LINBRRL = ubrr & 0xFF;
6
  LINENIR = (1<<LENTXOK) | (1<<LENRXOK);  // Transmit and Receive IRQ enable
7
  BufferPos = 0;
8
}

von Chris (Gast)


Lesenswert?

Wieso nicht den ganzen Code gepostet?
Vergessen sei(); zu setzten?

von Benedikt (Gast)


Lesenswert?

Welchen Interrupt Vector verwendest du denn?

So wie ich das sehe gibt es nur einen Transfer Complete Handler, also 
für RX und TX gemeinsam. Aber ich bin da nicht der Interrupt-Spezi. Aber 
vielleicht hilft es dir trotzdem weiter.

Ansonsten würde der gesamte Code auf jeden Fall weiter helfen.

von Michael Nienhaus (Gast)


Lesenswert?

Code sieht so aus:


sei() habe ich gemacht.

Habe bisher den "LIN/UART Transfer Complete (LIN_TC_vect)" aus 
http://www.atmel.com/Images/doc8265.pdf (Seite 59). Wie mann den genau 
anwendet weis ich aber leider noch nicht.

von Chris (Gast)


Lesenswert?

Vielleicht liegt es an mir, aber ich sehe hier kein Code.

von Michael Nienhaus (Gast)


Lesenswert?

oh sry glad vergessen


interrupt sieht so aus:
1
void UartInit(){
2
  LINCR = (1<<LENA) | (1<<LCMD0) | (1<<LCMD1) | (1<<LCMD2); // enable UART in 8bit Full Duplex Mode
3
  unsigned int  ubrr = (CPU_CLOCK/32/BAUDRATE)-1;    //calculate Baudrate
4
  LINBRRH = ubrr >> 8;
5
  LINBRRL = ubrr & 0xFF;
6
  LINENIR = (1<<LENTXOK) | (1<<LENRXOK);  // Transmit and Receive IRQ enable
7
  BufferPos = 0;
8
}
9
10
ISR(LIN_TC_vect){
11
  for(;;){
12
          PORTB ^= 2;
13
  }  
14
}

einfach nur pin toggeln um es zusehen wenn etwas passiert.
Tut sich aber leider bisher nichts.

von Benedikt (Gast)


Lesenswert?

Ich sehe auch keinen Code.

Wenn meine Theorie stimmt das der 87er nur ein Interrupt für RX und TX 
bietet dann versuche mal den LENTXOK wegzulassen, also nur den RX 
Interrupt aktivieren. Dann sollte er in den LIN_TC_vect nur springen 
wenn etwas auf RX reinkommt.

Falls das so funktioniert, müsstest du dann im vollständigen Code 
RX-Interrupt und TX-Interrupt abwechselnd an und abschalten, je nachdem 
was du gerade brauchst. Oder du kannst das über ein zusätzliches Flag 
abfragen.

Haut mich wenn ich Blödsinn erzähle :-)

von Michael Nienhaus (Gast)


Lesenswert?

Habe LENTXOK nun rausgenommen aber der Interrupt wird nicht 
angesprungen. An dem Pin tut sich nichts aber der Pin in der 
Main-schleife(PORTB ^= 1) toggelt nicht mehr.

von Chris (Gast)


Lesenswert?

Also mit den 5 Zeilen mehr Code, kann man nicht wirklich mehr anfangen. 
Was spricht dagegen das gesamte Programm zu zeigen?

von Michael Nienhaus (Gast)


Lesenswert?

zu abstrakt um alles zu posten...
habe den Interrupt nun hinbekommen aber mit einem Vector der nicht dafür 
vorgesehen ist (BADISR_vect).
Ist nicht schlimm aber auch nicht schön..
Habe wie schon gesagt schon LIN_TC_vect & LIN_ERR_vect für den ATTiny87 
probiert aber die sind es nicht für UartRX

von Falk B. (falk)


Lesenswert?

@ Michael Nienhaus (Gast)

>habe den Interrupt nun hinbekommen aber mit einem Vector der nicht dafür
>vorgesehen ist (BADISR_vect).
>Ist nicht schlimm aber auch nicht schön..

Es ist Murks.

>Habe wie schon gesagt schon LIN_TC_vect & LIN_ERR_vect für den ATTiny87
>probiert aber die sind es nicht für UartRX

Nimm die gescheiten Namen aus dem Datenblatt und setze auch das 
RICHTIGE, zugehörige Interrupt Enable Bit.

>Habe wie schon gesagt schon LIN_TC_vect & LIN_ERR_vect für den ATTiny87
>probiert aber die sind es nicht für UartRX

Wenn ich das Datenblatt richtig verstehe, ist LIN_TC_vect der einzige 
Vector bei diesem AVR, der für RX und TX benutzt wird. Dort muss man per 
Polling prüfen, ob es ein RX oder TX Interrupt war.

von Michael Nienhaus (Gast)


Lesenswert?

Falk Brunner schrieb:
> Nimm die gescheiten Namen aus dem Datenblatt und setze auch das
> RICHTIGE, zugehörige Interrupt Enable Bit.



Ich habe lt. Datenblatt folgende Flags gesetzt:

LINENIR = (1<<LENTXOK) | (1<<LENRXOK);  // Transmit and Receive IRQ 
enable

Damit sollten die IRQs enabled sein. Jetzt muss ich diesen IRQ auch mit 
der zugeh. ISR, also dem entspr. Vector abfangen:

ISR(LIN_TC_vect){
          PORTB ^= 2;
}

Dies ist auch lt. Datenblatt der Vector. Fakt ist, dass mit diesen 
Einstellungen der Interrupt nicht kommt. (ja, der Pin ist vorher auf 
Ausgang gestellt worden, der Pin funktioniert auch (Test in der Main 
loop) also ist ein HW Schaden am Port B auszuschließen.)

Warum dieser Interrupt nicht kommt, ist unklar. Auch das Macro Sei(); 
haben wir genutzt, die Benutzung von Interrupts ist uns auch geläufig.

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.