2016-07-10 159 views
0

我正在使用Arduino Uno與Atmega328p微控制器。我試圖使用INT1作爲軟件中斷。我根據外部信息手動將INT1的關聯PORTD3設置爲高電平或低電平。我想要的是在器件啓動時將引腳設置爲高電平或低電平,然後在啓用中斷之前將引腳設置爲高電平,然後在引腳上啓用中斷而不引起中斷。中斷髮生之前發生的中斷髮生之前發生的中斷

它似乎並不重要,我啓用中斷的地方 - 如果我改變了引腳的狀態在某些時候中斷將發生一旦啓用。下面是代碼片段:

int main(void) 
{ 
    DDRD |= (1<<DDD7)|(1<<DDD3);//7 for siren 3 for software int1 
    USART_Init(MYUBRR);//Initialize USART 
    while(door!='C' && door!='O'){//get door state on startup 
     door = getDoorState(); 
    } 
    if(door=='O') 
     PORTD |= 1<<PORTD3; 
    else 
     PORTD &= ~(1<<PORTD3); 
    EIFR &= ~(1<<INTF1);//clear flag bit before enable, I'd heard this may help???? 
    EIMSK |= (1<<INT1);//enable door switch interrupt 
    EICRA |= (1<<ISC00)|(1<<ISC10);//int1 and int0 set for any logical change 

    sei();//global interrupt enable 

    while (1) 
     {} 
} 

只要全局中斷通過調用啓用SEI()將如PORTD3高,無論在哪裏PORTD3設置高或者SEI的(發生中斷)是。在理想情況下,調用sei()應該永遠不會導致此代碼中的中斷。

+0

許多硬件設備爲各個事件(例如入口更改)設置中斷狀態,而不考慮全局中斷狀態。然後,當您啓用全局中斷狀態時,您會獲得舊事件的中斷。在啓用中斷之前,您需要確保清除/確認任何舊事件。如何完成是寫在手冊中。 – 4386427

+1

對數據表的簡短介紹讓我相信這是錯誤的:'EIFR&=〜(1 << INTF1);'這行寫'0'給INTF1(由於〜)。但是,你似乎必須寫一個'1'來清除這個標誌。試試'EIFR | =(1 << INTF1);'代替。 – 4386427

回答

0

4386427是正確的。該位通過將其設置爲1來清除,而不是零。似乎對我非直覺,所以它把我扔了,但它現在起作用。

EIFR |= (1<<INTF1); 
0

EIFR &= ~(1<<INTF1)不正確。

這樣做的正確方法是EIFR = 1<<INTF1

數據表說:該標誌通過寫入'1'來清除。