• <acronym id="ibnab"><strong id="ibnab"></strong></acronym><track id="ibnab"><strike id="ibnab"></strike></track>
  • <track id="ibnab"></track><acronym id="ibnab"></acronym>
  • <pre id="ibnab"><ruby id="ibnab"></ruby></pre>
  • <td id="ibnab"><noscript id="ibnab"></noscript></td>
  • <p id="ibnab"><label id="ibnab"></label></p>
  • 專注電子技術學習與研究
    當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

    AVR單片機外部中斷0、1、2 詳解

    作者:佚名   來源:本站原創   點擊數:  更新時間:2014年09月01日   【字體:

     

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