外部中断实验
了解一下:
外部中断中,需要设置优先级。抢占优先级高于响应优先级,数值越小,优先级越高。可以参考《STM32参考手册(寄存器版本)》“sys.h"的中断管理函数 。
外部中断的步骤:
1.初始化IO口(仿照前面所学的LED实验中的初始化,原理相同)
2.开启IO复用时钟并设置触发条件。
这里用到的函数为void Ex_NVIC_Config(u8 GPIOx,u8 BITx,u8 TRIM)
这里的三个参数分别是代表GPIOA~G,需要使能的位,触发模式
其中,触发模式TRLM:常用 RTIR 上升沿 \ FTIR 下降沿
3.配置中断分组,并使能
函数:void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group)
该函数有4个参数,
第一个参数NVIC_PreemptionPriority为中断抢占优先级数值,
第二个参数NVIC_SubPriority为中断子优先级数值,前两个参数的值必须在规定范围内,否则也可能产生意想不到的错误。
第三个参数NVIC_Channel为中断的编号,
最后一个参数NVIC_Group为中断分组设置(范围为0~4)。
4.设置中断服务函数。
以下代码使STM32中程序源码,因为是直接在原先按键基础上改进,所以我也没有重写代码。就是在看了程序源码之后,可以自己理解着往下写。(我就是这样做到)
exit.h
#ifndef __EXTI_H
#define __EXIT_H
#include "sys.h"
void EXTI_Init(void); //外部中断初始化
#endif
exit.c
#include "exit.h"
#include "led.h"
#include "key.h"
#include "delay.h"
#include "usart.h"
void EXTI0_IRQHandler(void)//WK_UP
{
delay_ms(10);
if(WK_UP==1)
{
LED0 = !LED0;
LED1 = !LED1;
}
EXTI->PR=1<<0;
}
void EXTI9_5_IRQHandler(void)
{
delay_ms(10);
if(KEY0==0)
{
LED0 = !LED0;
}
EXTI->PR=1<<5;
}
void EXTI15_10_IRQHandler(void)
{
delay_ms(10);
if(KEY1==0)
{
LED1 = !LED1;
}
EXTI->PR=1<<5;
}
void EXTI_Init(void)
{
KEY_Init();
//设置触发条件
Ex_NVIC_Config(GPIO_A,0,RTIR);
Ex_NVIC_Config(GPIO_C,5,FTIR);
Ex_NVIC_Config(GPIO_A,15,FTIR);
//配置分组并使能中断
MY_NVIC_Init(2,2,EXTI0_IRQn,2);//WK_UP
MY_NVIC_Init(2,1,EXTI9_5_IRQn,2);KEY0
MY_NVIC_Init(2,0,EXTI15_10_IRQn,2);//KEY1
}
main.c
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "exit.h"
int main(void)
{
Stm32_Clock_Init(9);
delay_init(72);
LED_Init();
KEY_Init();
EXTI_Init();
//LED0=0; //点亮LED
while(1)
{
delay_ms(20);
}
}