第N章 STM32学习笔记之OLED屏幕
第N章 STM32学习笔记之EXTI外部中断
第N章 STM32学习笔记之对射式红外传感器计次
目录
系列文章目录
一、对射式红外传感器
1.简介
2.硬件电路
二、软件驱动
1.模块化编程
2.初始化函数
a.开启外设时钟
b.配置GPIO
c.配置AFIO
d.配置EXTI
e.配置NVIC
3.编写中断函数
4.声明初始化函数
5.main函数处理
三、功能实现
1.传感器.c文件
1.传感器.h文件
3.main.c文件
总结
前言:
笔记:跟着B站教学视频做的学习笔记,基于STM32F103C8T6
测速传感器模块,可用于电机转速检测,脉冲计数,位置限位等
VCC:接电源正极-3.3V~5V
GND:接电源负极
DO:TTL开关信号输出,这里接STMF103C8T6的PB14引脚
AO:此模块不起作用,不用接
新增红外传感器模块.c和.h文件和一些预处理,详情见第N章 STM32....
根据EXTI基本结构图可以看出,使用外部中断需要配置GPIO、AFIO、EXTI、NVIC这些外设
外设工作需要先开启时钟,由于EXTI和NVIC外设时钟是一直开启的,所以只需要开启GPIO和AFIO的时钟就好
void CountSensor_Init(void)
{//GPIO时钟在APB2总线上
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//AFIO时钟在APB2总线上
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//NVIC和EXTI时钟总是开着的,不需要再开启
}
void CountSensor_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
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);
}
AFIO的库函数是和GPIO在同一个文件里的,可以在GPIO的.h文件里找
void CountSensor_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
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);
//因为是PB14,所以两个参数分别是PortSourceGPIOB和PinSource14
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);
}
在库函数中找到exti.h文件
void CountSensor_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
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_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);
EXTI_InitTypeDef EXTI_InitStruct;
EXTI_InitStruct.EXTI_Line = EXTI_Line14;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_Init(&EXTI_InitStruct);
}
因为NVIC是内核外设,它的库函数被ST发配到misc.h(杂项)文件里,在这里找它的库函数
void CountSensor_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
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_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);
EXTI_InitTypeDef EXTI_InitStruct;
EXTI_InitStruct.EXTI_Line = EXTI_Line14;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_Init(&EXTI_InitStruct);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStruct);
}
在STM32中,中断通道的名字都是固定的,每个中断通道都对应一个中断函数,可以在启动文件里查看,里面以“ IRQHandler ”结尾的字符串就是中断函数的名字
找到“ EXTI15_10_IRQHandler ”这一项,这就是EXTI15_10的中断函数,复制后回到.c文件里编写中断函数
void EXTI15_10_IRQHandler(void)
{}
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetFlagStatus(EXTI_Line14) == SET)
{
}}
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetFlagStatus(EXTI_Line14) == SET)
{
EXTI_ClearFlag(EXTI_Line14);
}}
在.h文件里声明刚刚编写的传感器初始化函数,这样在别的文件里就能调用该函数了,中断函数不用声明
声明红外传感器.h文件和调用初始化函数
定义一个变量“Count”,用于计数
uint16_t Count;
在中断函数里让Count++
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetFlagStatus(EXTI_Line14) == SET)
{
Count ++;
EXTI_ClearFlag(EXTI_Line14);
}}
写一个Get函数,返回Count值
uint16_t GetCount(void)
{
return Count;
}
声明Get函数
在OLED屏幕上显示计数,即“Count:0000X”
int main()
{
OLED_Init();
CountSensor_Init();
OLED_ShowString(1,1,"Count:");//显示“Count”这个字符串
while(1)
{
OLED_ShowNum(1,7,GetCount(),5);//显示计数
}
}
最终效果
本节内容是基于EXTI外部中断内容来进行的实操,一些外设的初始化步骤基本都差不多,驱动写出来后,至于怎么让其计数就见仁见智了。