AVR的INT外部中斷和PCINT中斷之區(qū)別與使用
INT外部中斷是幾乎所有通用單片機(jī),嵌入機(jī)中都會(huì)帶有的,早期的51系列和arm系列也都有,然而大多數(shù)因?yàn)樵O(shè)計(jì)原因,多只有帶兩個(gè)INT,最近別人提到了一個(gè)“所有端口都可以外部中斷”這樣的說(shuō)法,因?yàn)楸硎敬嬉?,因此找了些資料,也就找到了avr328p自帶的PCINT引腳功能
INT外部中斷和AVR和PCINT具體區(qū)別如下:
差別1. INT限制在了兩個(gè)端口上面,而PCINT則是所有接口都具備。
差別2. INT具有上沿,下沿,低電平,高電平觸發(fā)這幾種模式,而PCINT只有測(cè)量電平的變化這一個(gè)模式。
差別3. INT可以了解具體是哪個(gè)口觸發(fā)的,而PCINT不行。
差別4. PCINT不會(huì)直接跳轉(zhuǎn)入指定的程序,用戶需要讀取寄存器來(lái)做判斷是哪個(gè)PCINT端口產(chǎn)生了變化。
差別5. INT0和INT1各自可配置一個(gè)中斷程序入口,而所有的PCINT都只會(huì)觸發(fā)跳轉(zhuǎn)進(jìn)入一條指定的程序。
提供一道avr環(huán)境下的PCINT相關(guān)代碼與注釋,代碼功能是初始化三個(gè)PCINT
參考地址:https://sites.google.com/site/qeewiki/books/avr-guide/external-interrupts-on-the-atmega328
#include
#include// 頭文件,內(nèi)含了uint8的聲明
#include// Needed to use interrupts
volatileuint8_t portbhistory = 0xFF;// default is high because the pull-up
int main(void)
{
DDRB &= ~((1 << DDB0) | (1 << DDB1) | (1 << DDB2));//拉低PB0,1,2三個(gè)口的電平
// PB0,PB1,PB2 (PCINT0, PCINT1, PCINT2 pin)現(xiàn)在處于輸入態(tài)
PORTB |= ((1 << PORTB0) | (1 << PORTB1) | (1 << PORTB2));//開啟上拉
// PB0, PB1, PB2 現(xiàn)在處于上拉輸入狀態(tài)下
PCICR |= (1 << PCIE0);//設(shè)置 PCIE0以啟用 PCMSK0 偵測(cè)
PCMSK0 |= (1 << PCINT0);//設(shè)置 PCINT0 來(lái)測(cè)量狀態(tài)變化并產(chǎn)生中斷
sei();// turn on interrupts
while(1)
{
}
}
ISR (PCINT0_vect)
{
uint8_t changedbits;//設(shè)立一個(gè)無(wú)符號(hào)整數(shù)來(lái)記錄寄存器的變化
changedbits = PINB ^ portbhistory;
portbhistory = PINB;
if(changedbits & (1 << PINB0))
{
}
if(changedbits & (1 << PINB1))
{
}
if(changedbits & (1 << PINB2))
{
}
}
結(jié)論:
PCINT在當(dāng)年的設(shè)計(jì)中堪稱創(chuàng)新,但和所謂的全端口外部中斷依然有一定差距,但相對(duì)于按鍵掃描等方式來(lái)說(shuō),依然有一部分中斷服務(wù)的優(yōu)勢(shì)