欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

專(zhuān)注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

AVR單片機(jī)外部中斷0、1、2 詳解

作者:佚名   來(lái)源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2014年09月01日   【字體:

 

 
中斷基本包含:
1.中斷源
2.中斷向量(中斷入口地址)
3.中斷優(yōu)先級(jí)
4.中斷函數(shù)
除此之外,在單片機(jī)中,中斷的執(zhí)行或者中斷的觸發(fā)必須符合以下的規(guī)則:中斷觸發(fā)|執(zhí)行= 全局中斷使能位AND 中斷源使能位AND 中斷源標(biāo)志位
單片機(jī)內(nèi)部中斷的觸發(fā)必須完成,全局中斷使能,中斷源使能,中斷源標(biāo)志位置一等條件。除此之外,如果是外部中斷0,1,2(INT0,1,2),必須設(shè)置引腳觸發(fā)的規(guī)則。最后呢,就是需要在程序里建立處理中斷的中斷函數(shù)。
在編程的時(shí)候的步驟大致如下:(無(wú)視INT2)
1. 初始化PD2,PD3 為輸入狀態(tài)。DDRD|=BIT(2)|BIT(3);
2. 設(shè)置INT0,1 引腳觸發(fā)的規(guī)則,實(shí)驗(yàn)中為低電平觸發(fā)。MCUCR=0xF0;
3. 設(shè)置INT0,1 中斷源使能位為邏輯1。GICR|BIT(7)|BIT(6);
4. 清除INT0,1 的中斷標(biāo)志位(軟件寫(xiě)入,邏輯1 為清除)。GIFR|=BIT(7);BIT(6);
5. 全局中斷允許位使能。SREG|=BIT(7);
6. 編輯中斷處理函數(shù)。
/*ATmega16提供3個(gè)外部中斷,分別由INT0、INT1和INT2引腳觸發(fā)。
需要注意的是,如果將ATmega16設(shè)置為允許外部中斷,則即使把INT0、INT1和INT2引腳
設(shè)置為輸出方式,外部中斷仍然會(huì)被觸發(fā)。外部中斷可選擇采用上升沿觸發(fā)、下降沿觸發(fā)和
低電平觸發(fā)(INT2中斷只能采用沿觸發(fā)方式。
*/
#include<iom16v.h>
#include<macros.h>
#include "smg.h"
/*1.狀態(tài)寄存器SREG
bit7      bit6      bit5      bit4      bit3      bit2      bit1      bit0
  I        T        H        S        V        N        Z        C
I:全局中斷使能位。
    在I置位后,單獨(dú)的中斷使能由不同的中斷寄存器控制。若I為0,則禁止中斷。
MCU 控制寄存器- MCUCR        MCU 控制寄存器包含中斷觸發(fā)控制位與通用 MCU 功能
Bit        7      6    5    4    3    2    1    0
            SM2    SE    SM1  SM0  ISC11 ISC10 ISC01 ISC00
外部中斷 1 由引腳 INT1 激發(fā),如果 SREG 寄存器的 I 標(biāo)志位和相應(yīng)的中斷屏蔽位置位的話(huà)。在檢測(cè)邊沿前 MCU 首先采樣 INT1 引腳上的電平。如果選擇了邊沿觸發(fā)方式或電平變化觸發(fā)方式,那么持續(xù)時(shí)間大于一個(gè)時(shí)鐘周期的脈沖將觸發(fā)中斷,過(guò)短的脈沖則不能保證觸發(fā)中斷。如果選擇低電平觸發(fā)方式,那么低電平必須保持到當(dāng)前指令執(zhí)行完成。
SE:MCU休眠使能位
SM1~SM0:MCU休眠模式選擇
    SM2            SM1              SM0                  休眠模式
      0              0                0                    空閑
      0              0                1              ADC 噪聲抑制模式
      0              1                0                  掉電模式
      0              1                1                  省電模式
      1              0                0                    保留
      1              0                1                    保留
      1              1                0              Standby(1) 模式
      1              1                1            擴(kuò)展Standby(1) 模式
                          ISC11 ISC10 說(shuō)明
                            0      0    INT1 為低電平時(shí)產(chǎn)生中斷請(qǐng)求
                            0      1    INT1 引腳上任意的邏輯電平變化都將引發(fā)中斷
                            1      0    INT1 的下降沿產(chǎn)生異步中斷請(qǐng)求
                            1      1    INT1 的上升沿產(chǎn)生異步中斷請(qǐng)求
外部中斷 0 由引腳 INT0 激發(fā),如果 SREG 寄存器的 I 標(biāo)志位和相應(yīng)的中斷屏蔽位置位的話(huà)。在檢測(cè)邊沿前 MCU 首先采樣 INT0 引腳上的電平。如果 選擇了邊沿觸發(fā)方式或電平變化觸發(fā)方式,那么持續(xù)時(shí)間大于一個(gè)時(shí)鐘周期的脈沖將觸發(fā)中斷,過(guò)短的脈沖則不能保證觸發(fā)中斷。如果選擇低電平觸發(fā)方式,那么低電平必須保持到當(dāng)前指令執(zhí)行完成
                          ISC01  ISC00 說(shuō)明
                            0        0    INT0 為低電平時(shí)產(chǎn)生中斷請(qǐng)求
                            0        1    INT0 引腳上任意的邏輯電平變化都將引發(fā)中斷
                            1        0    INT0 的下降沿產(chǎn)生異步中斷請(qǐng)求
                            1        1    INT0 的上升沿產(chǎn)生異步中斷請(qǐng)求*/
/*MCU 控制與狀態(tài)寄存器-MCUCSR-
  Bit        7      6    5      4      3      2    1      0
              JTD    ISC2  –    JTRF WDRF  BORF  EXTRF PORF
                            * Bit 6 – ISC2: 中斷 2 觸發(fā)方式控制
                            異步外中斷 2 由外部引腳 INT2 激活,如果 SREG 寄存器的 I 標(biāo)志和 GICR 寄存器相應(yīng)的
                            中斷屏蔽位置位的話(huà)。若 ISC2 寫(xiě) 0 , INT2 的下降沿激活中斷。若 ISC2 寫(xiě) 1 , INT2 的上
                            升沿激活中斷。 INT2 的邊沿觸發(fā)方式是異步的。只要 INT2 引腳上產(chǎn)生寬度大于50ns
        (1s=1000ms,1 ms=1000μs,1μs=1000ns )
                            所示數(shù)據(jù)的脈沖就會(huì)引發(fā)中斷。若選擇了低電平中斷,低電平必須保持到當(dāng)前指令完成,
                            然后才會(huì)產(chǎn)生中斷。而且只要將引腳拉低,就會(huì)引發(fā)中斷請(qǐng)求。改變 ISC2 時(shí)有可能發(fā)生
                            中斷。因此建議首先在寄存器 GICR 里清除相應(yīng)的中斷使能位 INT2 ,然后再改變ISC2。
                            最后,不要忘記在重新使能中斷之前通過(guò)對(duì) GIFR 寄存器的相應(yīng)中斷標(biāo)志位 INTF2 寫(xiě) '1’
                            使其清零。*/
/*通用中斷控制寄存器- GICR
                            Bit        7      6    5      4      3      2      1      0
                                        INT1  INT0 INT2    –    –      –    IVSEL    IVCE
                            * Bit 7 – INT1: 使能外部中斷請(qǐng)求 1
                            當(dāng) INT1 為 '1’ ,而且狀態(tài)寄存器SREG 的 I 標(biāo)志置位,相應(yīng)的外部引腳中斷就使能了。
                            MCU通用控制寄存器– MCUCR的中斷敏感電平控制1位 1/0 (ISC11與ISC10)決定中斷是
                            由上升沿、下降沿,還是 INT1 電平觸發(fā)的。只要使能,即使 INT1 引腳被配置為輸出,
                            只要引腳電平發(fā)生了相應(yīng)的變化,中斷可將產(chǎn)生。
                            * Bit 6 – INT0: 使能外部中斷請(qǐng)求 0
                            當(dāng) INT0 為 '1’ ,而且狀態(tài)寄存器SREG 的 I 標(biāo)志置位,相應(yīng)的外部引腳中斷就使能了。
                            MCU通用控制寄存器– MCUCR的中斷敏感電平控制0位 1/0 (ISC01與ISC00)決定中斷是
                            由上升沿、下降沿,還是 INT0 電平觸發(fā)的。只要使能,即使 INT0 引腳被配置為輸出,
                            只要引腳電平發(fā)生了相應(yīng)的變化,中斷可將產(chǎn)生。
                          * Bit 5 – INT2: 使能外部中斷請(qǐng)求 2
                            當(dāng) INT2 為 '1’ ,而且狀態(tài)寄存器SREG 的 I 標(biāo)志置位,相應(yīng)的外部引腳中斷就使能了。
                          MCU通用控制寄存器– MCUCR 的中斷敏感電平控制2位 1/0 (ISC2與ISC2)決定中斷是由
                          上升沿、下降沿,還是 INT2 電平觸發(fā)的。只要使能,即使 INT2 引腳被配置為輸出,只
                          要引腳電平發(fā)生了相應(yīng)的變化,中斷可將產(chǎn)生*/
/*通用中斷標(biāo)志寄存器- GIFR
                            Bit        7      6    5      4    3      2    1      0
                                      INTF1 INTF0 INTF2  –    –    –    –    –
                          * Bit 7 – INTF1: 外部中斷標(biāo)志 1
                          INT1引腳電平發(fā)生跳變時(shí)觸發(fā)中斷請(qǐng)求,并置位相應(yīng)的中斷標(biāo)志INTF1。如果SREG 的位
                          I以及GICR寄存器相應(yīng)的中斷使能位INT1為”1” ,MCU即跳轉(zhuǎn)到相應(yīng)的中斷向量。進(jìn)入中
                          斷服務(wù)程序之后該標(biāo)志自動(dòng)清零。此外,標(biāo)志位也可以通過(guò)寫(xiě)入 ”0” 來(lái)清零。
                          * Bit 6 – INTF0: 外部中斷標(biāo)志 0
                          INT0引腳電平發(fā)生跳變時(shí)觸發(fā)中斷請(qǐng)求,并置位相應(yīng)的中斷標(biāo)志INTF0。如果SREG 的位
                          I以及GICR寄存器相應(yīng)的中斷使能位INT0為”1” ,MCU即跳轉(zhuǎn)到相應(yīng)的中斷向量。進(jìn)入中
                          斷服務(wù)程序之后該標(biāo)志自動(dòng)清零。此外,標(biāo)志位也可以通過(guò)寫(xiě)入 ”0” 來(lái)清零。
                          * Bit 5 – INTF2: 外部中斷標(biāo)志 2
                          INT2引腳電平發(fā)生跳變時(shí)觸發(fā)中斷請(qǐng)求,并置位相應(yīng)的中斷標(biāo)志INTF2。如果SREG 的位
                          I以及GICR寄存器相應(yīng)的中斷使能位INT2為”1” ,MCU即跳轉(zhuǎn)到相應(yīng)的中斷向量。進(jìn)入中
                          斷服務(wù)程序之后該標(biāo)志自動(dòng)清零。此外,標(biāo)志位也可以通過(guò)寫(xiě)入 ”0” 來(lái)清零。注意,當(dāng)
                          INT2中斷禁用進(jìn)入某些休眠模式時(shí),該引腳的輸入緩沖將禁用。這會(huì)導(dǎo)致INTF2標(biāo)志設(shè)置
                          信號(hào)的邏輯變化*/
//外部中斷0向量端口
#pragma interrupt_handler INTER_0:iv_INT0
//外部中斷1向量端口
#pragma interrupt_handler INTER_1:iv_INT1
//外部中斷2向量端口       
#pragma interrupt_handler INTER_2:iv_INT2
void INTER_init_0(unsigned char a)//a取值0-3
{
 switch(a)
 {
   case 0:MCUCR&=~(1<<ISC01);MCUCR&=~(1<<ISC00);break;//INT0 為低電平時(shí)產(chǎn)生中斷請(qǐng)求
   case 1:MCUCR&=~(1<<ISC01);MCUCR|=1<<ISC00;break;// INT0 引腳上任意的邏輯電平變化都將引發(fā)中斷
   case 2:MCUCR|=1<<ISC01;MCUCR&=~(1<<ISC00);break;//INT0 的下降沿產(chǎn)生異步中斷請(qǐng)求
   case 3:MCUCR|=1<<ISC01;MCUCR|=1<<ISC00;break;//INT0 的上升沿產(chǎn)生異步中斷請(qǐng)求
   default : MCUCR|=1<<ISC01;MCUCR&=~(1<<ISC00);break;//設(shè)置錯(cuò)誤時(shí),下降沿產(chǎn)生異步中斷請(qǐng)求
 }
}
void INTER_init_1(unsigned char a)//a取值0-3
{
 switch(a)
 {
   case 0:MCUCR&=~(1<<ISC11);MCUCR&=~(1<<ISC10);break;//INT1 為低電平時(shí)產(chǎn)生中斷請(qǐng)求
   case 1:MCUCR&=~(1<<ISC11);MCUCR|=1<<ISC10;break;// INT1 引腳上任意的邏輯電平變化都將引發(fā)中斷
   case 2:MCUCR|=1<<ISC11;MCUCR&=~(1<<ISC10);break;//INT1 的下降沿產(chǎn)生異步中斷請(qǐng)求
   case 3:MCUCR|=(1<<ISC11)|(1<<ISC10);break;//INT1 的上升沿產(chǎn)生異步中斷請(qǐng)求
   default : MCUCR|=1<<ISC11;MCUCR&=~(1<<ISC10);break;//設(shè)置錯(cuò)誤時(shí),下降沿產(chǎn)生異步中斷請(qǐng)求
 }
}
void INTER_init_2(unsigned char a)
{
 if(a)
   MCUCSR|=(1<<ISC2);//上升沿觸發(fā);
 else
   MCUCSR&=~(1<<ISC2);//下降沿觸發(fā);
}
void INTER_0(void)
{
 show(2,1);
//add your code here!
}
void INTER_1(void)
{
 show(1,0);
//add your code here!
}
void INTER_2(void)
{
// show(3,2);
//add your code here!
}
void InterruptInit(void)
{
 PORTD |= (1 << PD2)|(1 << PD3); //INT0、INT1端口輸出高電平
 DDRD &= ~(1 << PD2)&~(1 << PD3); //方向:輸入
 PORTB = (1 << PB3);    //INT2端口輸出高電平
 DDRB &= ~(1 << PB3);    //方向:輸入
 GICR |= (1 << INT0)|(1 << INT1)|(1<<INT2);//使能INT0,INT1
 GIFR&=~(1<<INTF0)&~(1<<INTF1)&~(1<<INTF2);//清零中斷標(biāo)志
 SREG|=0x80;//使能全局中斷
}
///////////////////////////////////////////////////////////////////
#include "smg.h"
#pragma data:code
//共陽(yáng)數(shù)碼管斷碼表
const  table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
                0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xb6,0xff};
//**********1ms基準(zhǔn)延時(shí)程序**********************************   
void delay(uint ms)
{
        uint i,j;
 for(i=0;i<ms;i++)
    {
    for(j=0;j<1141;j++);
       }
}
//***********系統(tǒng)初始化*************************
void SmgInit(void)
{
    DDRA|=BIT(PA2);//設(shè)置PA2為輸出
    DDRB=0XFF;//設(shè)置PB口為輸出
    PORTA|=BIT(PA2);//PA2=1,使能控制LED的74HC573
    PORTB|=0XFF;//PB口輸出1111 1111,使得所有的LED熄滅
    PORTA&=~BIT(PA2);//PA2=0,禁止控制LED的573,使控制LED的數(shù)據(jù)鎖存
    DDRA|=BIT(PA3);//設(shè)置PA3(smgd_lk)為輸出
    DDRA|=BIT(PA4);//設(shè)置PA4(SMGB_LK)為輸出
 DDRA|=BIT(PA6);//設(shè)置蜂鳴器控制口為輸出
 PORTA&=~BIT(PA6);//關(guān)閉蜂鳴器
}
//***********數(shù)碼管動(dòng)態(tài)掃描程序*************************
void show(uchar data,uchar bit)
{
    PORTA|=BIT(3);//PA3=1,使能控制數(shù)碼管數(shù)據(jù)的74HC573
 PORTB=table[data];//送數(shù)碼管斷碼數(shù)據(jù)
 PORTA&=~BIT(3);//關(guān)閉控制數(shù)碼管數(shù)據(jù)的573,使得數(shù)碼管數(shù)據(jù)鎖存
 PORTB=0X00;//PB口輸出0000 0000
 PORTA|=BIT(4);//PA4=1,使能控制數(shù)碼管數(shù)據(jù)口的573
 PORTB|=BIT(bit);//數(shù)碼管位選
 PORTA&=~BIT(4);//數(shù)碼管位選鎖存
 delay(1);//稍微延時(shí)
}
///////////////////////////////////////////////////////////////////////////////
#include "smg.h"
#include "interrupt.h"
void main(void)
{
// unsigned char i;
 SmgInit();
 InterruptInit();
 INTER_init_0(2);
 INTER_init_1(2);
 INTER_init_2(0);
 while(1)
 {
  ;
 }
}
 
關(guān)閉窗口