六、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解除挂起
}
}