六、EXTI
外部中斷/事件控制器包括用於生成高達23個事件/中斷的請求。每條中斷線可獨立配置選擇類型(響應或掛起)和相應的觸發事件(上升或下降或兩者)。每一中斷線可以獨立屏蔽。有一個掛起寄存器維持中斷線的狀態請求。
EXTI線0~15連接到PX0~15(可編程配置)
EXTI線16連接到PVD的輸出事件
EXTI線17連接到RTC報警事件
EXTI線18連接的USB OTG FS喚醒事件
EXTI線19連接到以太網喚醒事件
EXTI線20連接的USB OTG HS(在FS配置)喚醒事件
EXTI線21連接到RTC的篡改和TimeStamp事件
EXTI線22連接到RTC喚醒事件
設置步驟:
1. 使能相關時鐘
2. 設置中斷優先級分組(如果之前沒有設置),這個最好一個程序裏只在開頭設置一次。
3. 設置中斷線所要連接到的IO的輸入模式
4. 設置屏蔽寄存器,不能把中斷屏蔽掉
5. 設置中斷方式
6. 把中斷線連接到IO口
7. 設置中斷優先級
8. 使能中斷線
9. 編寫中斷服務函數(函數名是固定的)
10. 中斷服務函數裏檢查是哪個中斷掛起
11. 編寫相應的程序
12. 清除中斷掛起
程序:
/************************************
標題:操作EXTI的練習
軟件平臺:IAR for ARM6.21
硬件平臺:stm32f4-discovery
主頻:168M
author:小船
data:2012-01-17
*************************************/
#include <stm32f4xx.h>
void Led_Init (void);
void main ()
{
RCC->AHB1ENR |= 0x00000009; //使能GPIOD和GPIOA時鐘
RCC->APB2ENR |= (1<<14); //使能syscfg時鐘
SCB->AIRCR = 0x05FA0000 | 0x400; //中斷優先級分組 搶佔:響應=3:1
Led_Init();
GPIOA->MODER &= 0xFFFFFFFC; //浮空輸入模式
GPIOA->PUPDR &= 0xFFFFFFFC;
EXTI->IMR |= ( 1 << 0 ); //不屏蔽外中斷線0
EXTI->FTSR |= ( 1 << 0 ); //下降沿觸發
SYSCFG->EXTICR[0] &= 0xFFFFFF00; //配置外中斷線0到PA口
NVIC->IP[6] = 0xe0; //最低搶佔優先級,最高響應優先級1110
NVIC->ISER[0] |= (1<<6); //使能中斷線6,也就是外中斷0
while(1)
{
};
}
void Led_Init()
{
GPIOD->MODER &= 0x00FFFFFF; //設置PD12,13,14,15輸出
GPIOD->MODER |= 0x55000000;
GPIOD->OTYPER &= 0xFFFF0FFF; //設置PD12,13,14,15推輓輸出
GPIOD->OSPEEDR &= 0x00FFFFFF; //PD12,13,14,15 速度100m
GPIOD->OSPEEDR |= 0xff000000;
GPIOD->PUPDR &= 0x00FFFFFF; //PD12,13,14,15 無上拉無下拉
GPIOD->BSRRH = 0xf000; //reset register GPIOx_BSRRH, write only
//set register GPIOx_BSRRL, write only
SYSCFG->CMPCR = 0x00000001; //使用IO補償單元
}
void EXTI0_IRQHandler(void)
{
uint32_t tmp;
if(EXTI->PR & 0x00000001 != 0) //檢查是不是外中斷0掛起
{
tmp = (~GPIOD->ODR) & 0x0000f000; //PD15 14 13 12翻轉,板子上四個LED的亮滅
GPIOD->ODR &= 0xffff0fff;
GPIOD->ODR |= tmp;
EXTI->PR = (1<<0); //外中斷0解除掛起
}
}