前言:在STM32的工程代码的书写中,中断绝对是一个极其常见且重要的部分,下面我将介绍STM32单片机的外部中断代码与内部定时器中断。
一、外部中断
(1)介绍:外部中断一般用于单片机外设传回特定信号使得单片机在识别到这一信号后进入中断,使得程序跳到中断函数或程序中执行。执行完中断代码后才会继续回到原来进入中断的地方。
(2)代码部分(这里用对射式红外传感器作为例子,代码来自江协科技(江科大))
#include "stm32f10x.h" // CountSensor.c代码
uint16_t CountSensor_Count;//设置参数:计数次数
void CountSensor_Init(void)//初始化函数,在其中配置中断
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//开启GPIOB的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//开启AFIO(中断引脚选择)的时钟
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//GPIO端口配置为输入模式
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);//AFIO选择中断引脚为PB14
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line14;//选择中断线
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能这条线
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//选择模式为中断模式(另一个为事件模式)
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//选择下降沿触发
EXTI_Init(&EXTI_InitStructure);//EXIT初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置NVIC中断优先级分组
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;//选择EXIT通道10~15通道
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);//NVIC初始化
}
uint16_t CountSensor_Get(void)//给CountSensor_Count另外起一个名字,返回计数变量
{
return CountSensor_Count;
}
void EXTI15_10_IRQHandler(void)//中断函数(进入中断时要执行的函数)根据选择的通道去启动文件startup里复制中断函数名字
{
if (EXTI_GetITStatus(EXTI_Line14) == SET)//判断PB14引脚的电平
{
/*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0)
{
CountSensor_Count ++;
}
EXTI_ClearITPendingBit(EXTI_Line14);//清除中断标志位,防止程序卡死
}
}//中断函数不用写到头文件里面,因为它是自动执行的
主函数
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "CountSensor.h"
int main(void)
{
OLED_Init();
CountSensor_Init();
OLED_ShowString(1, 1, "Count:");
while (1)
{
OLED_ShowNum(1, 7, CountSensor_Get(), 5);
}
}