一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

stm32庫函數(shù)學(xué)習(xí)篇---NVIC與外部中斷

 XeonGate 2017-08-25

實現(xiàn)功能:外部中斷線0(PA0)與線15(PA15)分別連接到兩個按鈕,一個按鈕用于產(chǎn)生上升沿,另一個用于產(chǎn)生下降沿,兩個中斷函數(shù)里均對PA8口連接的led燈取反,同時PD2連接的led燈隨意延時取反指示程序運行。

這次我用了官方提供的例程來構(gòu)建自己的工程,這樣可以省下不少時間,而且減少了出錯率,調(diào)試起來容易多了。

 

首先是stm32中斷與外部中斷的概念。

ARM Coetex-M3內(nèi)核共支持256個中斷,其中16個內(nèi)部中斷,240個外部中斷和可編程的256級中斷優(yōu)先級的設(shè)置。STM32目前支持的中斷共84個(16個內(nèi)部+68個外部),還有16級可編程的中斷優(yōu)先級的設(shè)置,僅使用中斷優(yōu)先級設(shè)置8bit中的高4位。

STM32可支持68個中斷通道,已經(jīng)固定分配給相應(yīng)的外部設(shè)備,每個中斷通道都具備自己的中斷優(yōu)先級控制字節(jié)PRI_n(8位,但是STM32中只使用4位,高4位有效),每4個通道的8位中斷優(yōu)先級控制字構(gòu)成一個32位的優(yōu)先級寄存器。68個通道的優(yōu)先級控制字至少構(gòu)成17個32位的優(yōu)先級寄存器。

4bit的中斷優(yōu)先級可以分成2部分,從高位看,前面定義的是搶占式優(yōu)先級,后面是響應(yīng)優(yōu)先級。4bit一共可以分成5組。

第0組:所有4bit用于指定響應(yīng)優(yōu)先級;

第1組:最高1位用于指定搶占式優(yōu)先級,后面3位用于指定響應(yīng)優(yōu)先級;

第2組:最高2位用于指定搶占式優(yōu)先級,后面2位用于指定響應(yīng)優(yōu)先級;

第3組:最高3位用于指定搶占式優(yōu)先級,后面1位用于指定響應(yīng)優(yōu)先級;

第4組:所有4位用于指定搶占式優(yōu)先級。

所謂搶占式優(yōu)先級和響應(yīng)優(yōu)先級,他們之間的關(guān)系是:具有高搶占式優(yōu)先級的中斷可以在具有低搶占式優(yōu)先級的中斷處理過程中被響應(yīng),即中斷嵌套。

1、  當(dāng)兩個中斷源的搶占式優(yōu)先級相同時,這兩個中斷將沒有嵌套關(guān)系,當(dāng)一個中斷到來后,如果正在處理另一個中斷,這個后到來的中斷就要等到前一個中斷處理完之后 才能被處理。

2、  如果這兩個中斷同時到達,則中斷控制器根據(jù)他們的響應(yīng)優(yōu)先級高低來決定先處理哪一個;

3、  3如果他們的搶占式優(yōu)先級和響應(yīng)優(yōu)先級都相等,則根據(jù)他們在中斷表中的排位順序決定先處理哪一個。每一個中斷源都必須定義2個優(yōu)先級。

有幾點需要注意的是:

1)如果指定的搶占式優(yōu)先級別或響應(yīng)優(yōu)先級別超出了選定的優(yōu)先級分組所限定的范圍,將可能得到意想不到的結(jié)果;

2)搶占式優(yōu)先級別相同的中斷源之間沒有嵌套關(guān)系;

3)如果某個中斷源被指定為某個搶占式優(yōu)先級別,又沒有其它中斷源處于同一個搶占式優(yōu)先級別,則可以為這個中斷源指定任意有效的響應(yīng)優(yōu)先級別。

 

STM32有20個外部中斷線,其中EXTI0-EXTI15給I/O端口使用,對應(yīng)如下圖:

EXTI線16連接到PVD輸出 
EXTI線17連接到RTC鬧鐘事件 
EXTI線18連接到USB喚醒事件 
EXTI線19連接到以太網(wǎng)喚醒事件(只適用于互聯(lián)型產(chǎn)品)。

 

其中,每個外部中斷都具有對應(yīng)的硬件機制,如下圖:

 

STM32中,每一個GPIO都可以觸發(fā)一個外部中斷,但是,GPIO的中斷是以組位一個單位的,同組間的外部中斷同一時間只能使用一個。比如說,PA0,PB0,PC0,PD0,PE0,PF0,PG0這些為1組,如果我們使用PA0作為外部中斷源,那么別的就不能夠再使用了,在此情況下,我們只能使用類似于PB1,PC2這種末端序號不同的外部中斷源。每一組使用一個中斷標(biāo)志EXTIx。EXTI0 – EXTI4這5個外部中斷有著自己的單獨的中斷響應(yīng)函數(shù),EXTI5-9共用一個中斷響應(yīng)函數(shù),EXTI10-15共用一個中斷響應(yīng)函數(shù)。但是在中斷函數(shù)里面可以查詢中斷標(biāo)志,從而判斷是哪個外部中斷,雖然共用同一個中斷號,但是具有獨立的中斷標(biāo)志位EXTI_LineX,X為0~15。

 

使用外部中斷需要準(zhǔn)備的工作如下:

1、初始化IO口為輸入。

這一步設(shè)置你要作為外部中斷輸入的IO口的狀態(tài),可以設(shè)置為上拉/下拉輸入,也可以設(shè)置為浮空輸入,但浮空的時候外部一定要帶上拉,或者下拉電阻。否則可能導(dǎo)致中斷不停的觸發(fā)。在干擾較大的地方,就算使用了上拉/下拉,也建議使用外部上拉/下拉電阻,這樣可以一定程度防止外部干擾帶來的影響。

2、開啟IO口的復(fù)用時鐘。

3、開啟與該IO口相對應(yīng)的線上中斷/事件,設(shè)置觸發(fā)條件。

4、配置NVIC,并使能中斷。

5、編寫相應(yīng)中斷函數(shù)。

 

 

下面是main.c文件源碼

 

//main.c

#include "stm32f10x.h"

EXTI_InitTypeDef   EXTI_InitStructure;

GPIO_InitTypeDef   GPIO_InitStructure;

NVIC_InitTypeDef   NVIC_InitStructure;

 

void GPIO_Config(void);

void EXTI0_Config(void);

void EXTI15_10_Config(void);

void delay(void);

 

int main(void)

{

  GPIO_Config();

  /* Configure PA.00 in interrupt mode */

  EXTI0_Config();

  /* Configure PA.15 in interrupt mode */

  EXTI15_10_Config();

       

  while (1)

  {

  GPIO_WriteBit(GPIOD, GPIO_Pin_2, Bit_RESET);

  delay();

  GPIO_WriteBit(GPIOD, GPIO_Pin_2, Bit_SET);

  delay();

  }

}

 

void delay(void)

{

u16 i,j;

for(i=0;i<1000;i++)

for(j=0;j<1000;j++)

;

}

void GPIO_Config(void)

{

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE);

  /* Configure PA.08 pin as output */

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

 

  /* Configure PD.02 pin as output */

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

  GPIO_Init(GPIOD, &GPIO_InitStructure);

}

 

 

/**

  * @brief  Configure PA.00 in interrupt mode

  * @param  None

  * @retval None

  */

void EXTI0_Config(void)

{

  /* Enable GPIOA clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

  /* Configure PA.00 pin as input*/

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

 

  /* Enable AFIO clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

 

  /* Connect EXTI0 Line to PA.00 pin */

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);

 

  /* Configure EXTI0 line */

  EXTI_InitStructure.EXTI_Line = EXTI_Line0;

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; 

  EXTI_InitStructure.EXTI_LineCmd = ENABLE;

  EXTI_Init(&EXTI_InitStructure);

 

  /* Enable and set EXTI0 Interrupt to the lowest priority */

  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

}

 

/**

  * @brief  Configure PA.15 in interrupt mode

  * @param  None

  * @retval None

  */

void EXTI15_10_Config(void)

{

 

  /* Enable GPIOA clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

 

  /* Configure PA.15 pin as input*/

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

 

  /* Enable AFIO clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

  /* Connect EXTI15 Line to PA.15 pin */

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource15);

 

  /* Configure EXTI15 line */

  EXTI_InitStructure.EXTI_Line = EXTI_Line15;

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;

  EXTI_InitStructure.EXTI_LineCmd = ENABLE;

  EXTI_Init(&EXTI_InitStructure);

 

  /* Enable and set EXTI15_10 Interrupt to the lowest priority */

  NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0E;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

 

  NVIC_Init(&NVIC_InitStructure);

 

}

 

 

 

 

下面是中斷函數(shù)的源碼。

 

//stm32f10x_it.c

#include "stm32f10x_it.h"

 

u8 flag=0;

 

/**

  * @brief  This function handle External line 0 interrupt request.

  * @param  None

  * @retval None

  */

void EXTI0_IRQHandler(void)

{

  if(EXTI_GetITStatu(EXTI_Line0) != RESET)

  {

   

     if(flag)

             {

              GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_RESET);

              flag=0;

              }

        else

             {

              GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_SET);

              flag=1;

              }

    /* Clear the  EXTI line 0 pending bit */

    EXTI_ClearITPendingBit(EXTI_Line0);

  }

}

 

/**

  * @brief  This function handle External lines 15 to 10 interrupt request.

  * @param  None

  * @retval None

  */

void EXTI15_10_IRQHandler(void)

{

  if(EXTI_GetITStatu(EXTI_Line15) != RESET)

  {

        if(flag)

             {

              GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_RESET);

              flag=0;

              }

        else

             {

              GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_SET);

              flag=1;

              }

 

    /* Clear the  EXTI line 15 pending bit */

    EXTI_ClearITPendingBit(EXTI_Line15);

  }

}

 

編程配置后,可以看到連接到PD2上的led不斷閃爍,按下PA0和PA15上任意一個按鈕均可取反連接到PA8上的led燈。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    日韩1区二区三区麻豆| 欧美日韩乱码一区二区三区| 欧美成人精品国产成人综合| 美国欧洲日本韩国二本道| 黑丝袜美女老师的小逼逼| 亚洲精品中文字幕在线视频| 一区二区三区日韩在线| 免费在线播放一区二区| 黄色片一区二区三区高清| 夫妻性生活真人动作视频| 日韩精品区欧美在线一区 | 国产欧美精品对白性色| 亚洲视频一区二区久久久| 国产又粗又爽又猛又黄的 | 久久机热频这里只精品| 成人三级视频在线观看不卡| 亚洲国产成人久久99精品| 在线观看免费午夜福利| 欧美国产日本免费不卡| 青青操视频在线播放免费| 亚洲一区二区久久观看| 久久99青青精品免费| 亚洲超碰成人天堂涩涩| 99久久成人精品国产免费| 欧美人妻免费一区二区三区| 国产美女精品午夜福利视频| 日韩不卡一区二区视频| 欧美日韩国产二三四区| 亚洲中文字幕熟女丝袜久久| 亚洲欧美中文字幕精品| 日本午夜一本久久久综合| 中文人妻精品一区二区三区四区 | 欧美加勒比一区二区三区| 91欧美亚洲视频在线| 亚洲香艳网久久五月婷婷| 国产av一区二区三区四区五区| 国产日本欧美韩国在线| 日本 一区二区 在线| 国产精品日韩精品最新| av在线免费观看在线免费观看| 精品一区二区三区免费看|