Forum: Mikrocontroller und Digitale Elektronik TWI Interrupt auf Atmel sam "immer aktiv"


von Michael (Gast)


Lesenswert?

Ich bastel immer noch an meinem twi rum. Nachdem er sich eh bei der 
Benutzung der Atmel ASF routinen nach einer gewissen Laufzeit aufhängt 
versuche ich seit gestern das senden von Bytes interrupt basiert zu 
lösen.

Nachdem ich die routinen eigentlich schon trocken vorgeschrieben hatte, 
habe ich das Ganze wieder auf ein Minimum reduzieren müssen, da ich 
schon ein grundlegendes Problem habe.

Sobald ich (nach initialisierung des NVIC und des TWI) das interrupt 
enable register (IER) beschreibe und dort die Flags TXCOMP und TXRDY 
setze bleibt der Prozessor immer in dem TWI0_Handler. Der nachfolgende 
Code wird nicht mehr ausgeführt. Steppe ich allerdings im 
einzelschrittmodus beim Debuggen durch, wird auch der nachfolgende Code 
ausgeführt. Sonst nicht.

Die Flags TXCOMP und TXRDY sind natürlich (automatisch) gesetzt im 
Status Register (SR). Aber kommt deshalb der Interrupt andauernt? Ist 
das so gedacht? Soll man den in der Handler disabeln und zum Ende des 
Handlers,  wenn man auf ein bestimmtes Flag wartet, wieder einschalten?! 
Ich dachte eher, dass wenn eine !Änderung! im SR vorhanden ist der 
Interrupt (wenn die Maske übereinstimmt) auslöst und ich dann das SR 
auslese und "gucke" was passiert ist. Und erst dann der nächste 
Interrupt ausgelöst wird, wenn sich das SR ändert!

Muss ich den interrupt noch irgendwie bestätigen?! Eigentlich ja nicht 
oder? Meine timer interrupts etc. funktionieren ja auch tadellos. Nur 
bei dem TWI ist es irgendwie verrückt.

Atmel selbst hält sich auch ziemlich bedeckt im Datenblatt was den TWI 
mit Interrupts angeht. Demnach ist es einfach (was ich auch bis gestern 
Mittag dachte).

Hier der Code
1
void TWI0_Handler (void){
2
  uint32_t twi_status;
3
  twi_status = TWI0->TWI_SR;
4
}
5
6
7
int main (void)
8
{
9
  enum {IDLE,TX_START,TX_WAIT,RX_WAIT,TX_CMPL,RX_CMPL};
10
  uint32_t twi0_state = IDLE;
11
  sysclk_init();
12
  board_init();
13
14
    NVIC_DisableIRQ(TWI0_IRQn);
15
    NVIC_ClearPendingIRQ(TWI0_IRQn);
16
    NVIC_SetPriority(TWI0_IRQn , 0); 
17
    NVIC_EnableIRQ(TWI0_IRQn);
18
  
19
    twi_master_options_t opt_bus1 = {
20
      .speed = 50000,
21
      .chip  = I2C_BUS0_ADDR_U1,
22
      .smbus = 0,
23
      .master_clk = sysclk_get_peripheral_bus_hz(TWI0)
24
    };
25
26
    twi_master_setup(TWI0, &opt_bus1);
27
    
28
  
29
  //twi_init(); //BUS0 und 1
30
  TWI0->TWI_IER =  TWI_IER_NACK | TWI_IER_TXCOMP | TWI_IER_TXRDY;
31
//hier kommt der Interrupt, nachstehender Code wird nicht mehr erreicht.
32
  twi0_state = IDLE;
33
  
34
  if (twi_load_write_buffer1()){
35
    if (twi0_state == IDLE){
36
      twi0_state = TX_START;
37
      twi_write_trigger_next_transmission(TWI0);
38
    }
39
  }
40
  
41
  while(1){
42
    
43
  }

von Karlo (Gast)


Lesenswert?

Michael schrieb:
> Atmel selbst hält sich auch ziemlich bedeckt im Datenblatt was den TWI
> mit Interrupts angeht. Demnach ist es einfach (was ich auch bis gestern

Welches meinst du denn da oder sind ALLE gleich?

von Michael (Gast)


Lesenswert?


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.