新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > avr的外部中斷

        avr的外部中斷

        作者: 時間:2016-11-20 來源:網絡 收藏
        關于AVR中斷:

        系統在正常運行主程序時,如果突然有一個重要的任務要馬上處理,那么系統就要保存現在的工作,然后再去處理這個任務,執行這個重要任務完畢以后再返回原來的主程序繼續運行,這就是中斷。

        本文引用地址:http://www.104case.com/article/201611/318679.htm

        主程序一旦進入中斷服務程序,那么AVR芯片將自動的關閉全局中斷,在這個期間不再執行其它的中斷請求,直到中斷程序結束以后芯片才自動的重新開放全局中斷。(注意,在這個期間某些中斷請求可能會被丟棄,某些請求會留下中斷請求標致,一旦當前的中斷執行完畢,這個有中斷標致的請求就有可能馬上得到響應,如INT0的下降沿觸發就會留下中斷請求標致,而低電平觸發就不會流下中斷請求標致)。如果你想在執行中斷服務程序時響應另外一個更重要的中斷,那么就要在中斷服務程序中加入一條打開全局中斷的語句。

        我們現在先來討論外部中斷

        外部中斷要要記得5個寄存器,分別是:

        1.status register -SREG狀態寄存器。而且外部中斷關心的是它的Bit-7-I位,全局中斷使能。置位時,使能全局中斷。那些單獨的中斷,就是你要實現的那些中斷,他們的使能由其他獨立的控制寄存器控制,就比如說下面說的EIMSK等。如果我們對I清0,則全部的中斷是不可能發生了,就象一個總的開關一樣,即使單獨中斷標志置位與否。I可以通過SEI和CLI指令來置位和清0。

        2.External Interrupt Mask Register -EIMSK外部中斷屏蔽寄存器。當INT7–INT0為1’,而且狀態寄存器SREG的I標志置位,相應的外部引腳中斷就使能了。

        3.External Interrupt Control Register A – EICRA外部中斷控制寄存器A。Bits 7..0–ISC31, ISC30–ISC00, ISC00:外部中斷3 - 0敏感電平控制位。詳見datesheet。如果SREG寄存器的I標志和EIMSK寄存器相應的中斷屏蔽位置位,那么外部中斷3 - 0由引腳INT3~INT0引腳激活。需要注意的是,改變ISCn時,有可能發生中斷。因此,建議首先在EIMSK里清除相應的中斷使能位INTn,然后再改變ISCn。最后呢,千萬不要忘記在重新使能中斷之前,通過對EIFR的相應中斷標志位INTFn寫“1”,使其清0。

        4.External Interrupt Control Register B – EICRB外部中斷控制寄存器B。Bits 7..0–ISC71, ISC70 - ISC41, ISC40:外部中斷7 - 4敏感電平控制位。詳見datesheet,它和EICRA可是不同的。檢測信號跳變沿之前MCU首先對INT7:4引腳進行采樣。如果選擇了跳變沿中斷或是電平變換中斷(上升沿和下降沿都將產生中斷),只要信號持續時間大于一個時鐘周期,中斷就會發生;否則無法保證觸發中斷。要注意由于XTAL分頻器的存在,CPU時鐘有可能比XTAL時鐘慢。若選擇了低電平中斷,低電平必須保持到當前指令完成,然后才會產生中斷。而且只要將引腳拉低,就會引發中斷請求。而且,同樣需要象EICRA一樣注意:改變ISCn1/ISCn0時一定要先通過清零EIMSK寄存器的中斷使能位來禁止中斷。否則在改變ISCn1/ISCn0的過程中可能發生中斷。

        5.External Interrupt Flag Register – EIFR。外部中斷標志寄存器。INT7:0引腳電平發生跳變時觸發中斷請求,并置位相應的中斷標志INTF7:0。如果SREG的位I以及EIMSK寄存器相應的中斷使能位為’1’,MCU既跳轉到中斷例程。中斷例程執行時標志被硬件清零。此外,標志位也可以通過寫入’1’的方式來清零。若INT7:0配置為電平觸發,這些標志位總是為0’。在睡眠模式下,如果中斷是禁止的,則這些引腳的輸入緩沖器也是禁止的。這有可能產生邏輯電平的變化并置位INTF3:0。更多信息請參考手冊的“數字輸入使能和睡眠模式”。

        我們應該清楚的是:外部中斷通過引腳INT7:0觸發。只要使能了中斷,即使引腳INT7:0配置為輸出,只要電平發生了合適的變化,中斷也會觸發。這個特點可以用來產生軟件中斷。通過設置外部中斷控制寄存器–EICRA (INT3:0)和EICRB (INT7:4),中斷可以由下降沿、上升沿,或者是低電平觸發。當外部中斷使能并且配置為電平觸發,只要引腳電平為低,中斷就會產生。若要求INT7:4在信號下降沿或上升沿觸發,I/O時鐘必須工作,如數據手冊P 33“時鐘系統及其分布”說明的那樣。INT3:0的中斷條件檢測則是異步的。也就是說,這些中斷可以用來將器件從睡眠模式喚醒。在睡眠過程(除了空閑模式)中I/O時鐘是停止的。

        上面的多為數據手冊里面的內容。也許我們回有幾個困惑。

        1.為何AVR寫“1”也能清0呢,這不是很奇怪嘛。你可以參考下面幾個網頁

        http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=749852

        http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=691118&bbs_page_no=1&bbs_id=1000

        http://www.c51bbs.com/c51bbs/topic1/c51bbs17322.htm

        但最終呢,真正的原因是在AVR-GCC的幫助文檔avr-libc本來就有的,FAQ24,Why are (many) interrupt flags cleared by writing a logical 1?當然,你的E文要好地。

        參見如下說明:

        Why are (many) interrupt flags cleared by writing a logical 1?

        Usually, each interrupt has its own interrupt flag bit in some control register, indicating the specified interrupt condition has been met by representing a logical1 inthe respective bit position. When working with interrupt handlers, this interrupt flag bit usually gets cleared automatically in the course of processing the interrupt, sometimes by just calling the handler at all, sometimes (e. g. for the U[S]ART) by reading a particular hardware register that will normally happen anyway when processing the interrupt.

        From the hardwares point of view, an interrupt is asserted as long as the respective bit is set, while global interrupts are enabled. Thus, it is essential to have the bit cleared before interrupts get re-enabled again (which usually happens when returning from an interrupt handler).

        Only few subsystems require an explicit action to clear the interrupt request when using interrupt handlers. (The notable exception is the TWI interface, where clearing the interrupt indicates to proceed with the TWI bus hardware handshake, so its never done automatically.)

        However, if no normal interrupt handlers are to be used, or in order to make extra sure any pending interrupt gets cleared before re-activating global interrupts (e. g. an external edge-triggered one), it can be necessary to explicitly clear the respective hardware interrupt bit by software. This is usually done by writing a logical 1 into this bit position. This seems to be illogical at first, the bit position already carries a logical 1 when reading it,so why does writing a logical 1 to it clear the interrupt bit?

        The solution is simple:writing a logical 1 to it requires only a single OUT instruction, and it is clear that only this single interrupt request bit will be cleared. There is no need to perform a read-modify-write cycle (like, an SBI instruction), since all bits in these control registers are interrupt bits, and writing a logical 0 to the remaining bits (as it is done by the simple OUT instruction) will not alter them, so there is no risk of any race condition that might accidentally clear another interrupt request bit. So instead of writing

        TIFR |= _BV(TOV0); /* wrong! */

        simply use

        TIFR = _BV(TOV0);

        2.只要使能了中斷,即使引腳INT7:0配置為輸出,只要電平發生了合適的變化,中斷也會觸發.這句怎么理解?答:也就是說,你打開了中斷int0和int1,同時這兩個管腳定義為輸出,然后,你使用軟件設置這兩個管腳的輸出電平,當滿足中斷條件時,中斷就發生了。這不就是軟件中斷嗎?

        3.在配置了外部中斷控制寄存器、屏蔽寄存器、標志寄存器后,是否還需要設置IO口為輸入端口呢?答:是的,不過IO口上電時就默認是輸入了,可以不寫這條指令。補充,設置成輸出也照樣產生中斷。它用PINx讀。



        關鍵詞: avr外部中

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 肇源县| 溧水县| 靖江市| 巢湖市| 景谷| 辉县市| 本溪| 无极县| 昌乐县| 衡山县| 上思县| 合山市| 南充市| 临夏县| 阜城县| 大名县| 洛浦县| 乌苏市| 九龙县| 邵东县| 鄂州市| 石楼县| 阿克苏市| 星座| 汕尾市| 桐庐县| 宜川县| 团风县| 庆阳市| 亳州市| 城口县| 大城县| 芜湖市| 扎囊县| 琼中| 获嘉县| 浠水县| 都江堰市| 同心县| 连平县| 柳州市|