2017-07-01 5 views
1

Ich schreibe ein Programm für ein nRF52-basierten Board mit der Redbear Arduino Library. Effektive Behandlung meiner Platine als BLE Nano 2.Aktivieren I2C-Interrupt innerhalb Timer-Interrupt auf nRF52 Arduino

Ich habe einen Timer, der alle x Millisekunden tickt, zum Beispiel 50ms.

In diesem Timer möchte ich Daten von einem I2C-Sensor lesen und den Messwert in einen Puffer hinzufügen.

Ich bin mir bewusst, dass Interrupts standardmäßig innerhalb des Timers ISR deaktiviert sind. Ich würde gerne wissen, wie ich den I2C-Interrupt kurz wieder aktivieren kann und den Sensor lesen und dann die Interrupts wieder deaktivieren kann.

Das Intervall zwischen den Sensormesswerten ist kritisch, und ich möchte nicht nur ein Flag im Timer-ISR setzen, da ich nicht weiß, wie lange es dauern wird, bis dieses Flag überprüft wird.

Kann mir bitte jemand sagen, wie man die I2C Interrupts innerhalb einer Timer ISR kurz aktiviert?

ich mit experimentiert habe:

__disable_irq(); 

__enable_irq(); 

NVIC_EnableIRQ(SPI0_TWI0_IRQn); 

NRF_TWI0->INTENSET = 1; 

Keine Freude mit dieser kommt, verstehe ich, dass einige von ihnen nur von bestimmten Orten in der Software arbeiten, funktioniert so nicht richtig in einer ISR.

void setup() { 
    // put your setup code here, to run once 
    NVIC_SetPriority (TIMER0_IRQn, 2); 
    NVIC_SetPriority (TIMER1_IRQn, 2); 
    NVIC_SetPriority (TIMER2_IRQn, 2); 
    NVIC_SetPriority (SPI0_TWI0_IRQn, 3); 
    NVIC_SetPriority (SPI1_TWI1_IRQn, 3); 
    Serial.begin(9600); 
    Serial.println("Start "); 
    Serial.print("Priority of TWI0: "); 
    Serial.println(NVIC_GetPriority (SPI0_TWI0_IRQn)); 
    Serial.println(NVIC_GetPriority (SPI1_TWI1_IRQn)); 
    Serial.print("Priority of Ticker: "); 
    Serial.println(NVIC_GetPriority (TIMER0_IRQn)); 
    Serial.println(NVIC_GetPriority (TIMER1_IRQn)); 
    Serial.println(NVIC_GetPriority (TIMER2_IRQn)); 


    Wire.begin(); 
    __disable_irq(); 
    __enable_irq(); 
    ticker1s.attach(task_handle, 1); 
    Wire.requestFrom(0x02,6); 

} 

void task_handle(void) { 
    __enable_irq(); 
    Serial.println("Task handle "); 
    Serial.println("-IRQ enable status: "); 
    Serial.println(NVIC_GetEnableIRQ(SPI0_TWI0_IRQn)); 
    Serial.println(NVIC_GetEnableIRQ(SPI1_TWI1_IRQn)); 
    NVIC_EnableIRQ(SPI0_TWI0_IRQn); 
    NRF_TWI0->INTENSET = 1; 

    NVIC_EnableIRQ(SPI1_TWI1_IRQn); 
    NRF_TWI1->INTENSET = 1; 
    Serial.println("-IRQ enable status: "); 
    Serial.println(NVIC_GetEnableIRQ (SPI0_TWI0_IRQn)); 
    Serial.println(NVIC_GetEnableIRQ (SPI1_TWI1_IRQn)); 
    delay(1000); 
    Wire.requestFrom(0x02,6); 

} 
+0

Ich habe auch versucht, mit NVIC_GetPriority und NVIC_SetPriority alle Interrupts SPIx_TWIx_IRQn sowohl höher als auch niedriger als die Priorität aller TIMERx_IRQn Prioritäten zu machen. NVIC_GetPriority bestätigt, dass die Prioritäten gesetzt wurden, aber immer noch keine Freude – Steve

Antwort

0

standardmäßig Interrupts werden nicht in ISRs auf Cortex-M deaktiviert, sondern Interrupts sind vorweggenommen, basierend auf den festgelegten Prioritäten in NVIC (daher der "Nested" Teil NVIC). Dies bedeutet, dass Sie den I2C-Interrupt wie gewohnt aktivieren und dann die Priorität mit NVIC_SetPriority(IRQn, priority) festlegen sollten.

ist jedoch zu beachten, dass die Prioritätszahlen sind in umgekehrten bestellt, so dass eine Priorität von 0 würde eine Priorität von 6.em vorgreifen sagt in diesem Fall, dass Sie die Timer-Interrupt-Prioritäten 1 zu sagen gesetzt würden und die I2C-Interrupt 0

+0

Danke, ich nahm an, dass der Fall war, und ich habe versucht, alle Timer-Prioritäten auf 2, und alle SPIx_TWIx auf 1 unterbricht, und dann in einem separaten Test zu 3. Ich überprüfte, dass NVIC_GetEnableIRQ eingestellt wurde, und sie schienen ihre korrekten Werte zu melden, aber mein I2C-Aufruf verursacht immer noch, dass mein Programm hängt, wenn ich es im Timer verwende. ISR – Steve

+0

@Steve Ich sehe, dass Sie Ihre Skizze aufgenommen haben , aber ich bemerke, dass die ISR für die I2C-Controller fehlen, standardmäßig denke ich nicht, dass der Arduino-Kern Interrupt verwendet, um I2C zu behandeln. Wenn Sie also den Interrupt aktivieren, springt er zum Standard-Handler, der eine Endlosschleife ist. Dies erklärt wahrscheinlich den Hang. –

+0

Außerdem habe ich bemerkt, dass Sie ein "Ticker" -Objekt als Ihren "Timer" verwenden, aber denken Sie daran, dass sie typischerweise mit SysTick-Timer implementiert werden, der auf jedem Cortex-M verfügbar ist, und seine Interrupt-Priorität ist von den gewöhnlichen "Timern getrennt "verfügbar auf der NRF52. –