嵌入式学习日志————对射式红外传感器计次
前言
这是第二次学习这部分内容了,第一次是大一上学期,因为大二下忙着其他事一直没来得及吧STM32学完,所以假期从头开始再学,比第一次也有了更深的理解,以下内容均是看【STM32入门教程-2023版 细致讲解 中文字幕】https://www.bilibili.com/video/BV1th411z7sn?p=11&vd_source=e1593f6552f3a4d79494f109d996e6d3这个系列的视频学习的,如有任何问题,欢迎指正!
正文
一、理论知识
1.中断
在主程序运行过程中,出现了特定的中断触发条件,使得 CPU 暂停当前正在运行的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续运行。
2.中断优先级
当有多个中断源同时申请中断时, CPU 会根据中断源的轻重缓急进行裁决,优先响应更加紧急的中断源。
3.中断嵌套
当一个中断程序正在运行时,又有新的更高优先级的中断源申请中断, CPU 再次暂停当前中断程序,转而去处理新的中断程序,处理完成后依次进行返回。
4.NVIC
1)定义
嵌套中断向量控制器(是内核外设——使用前不用使能时钟)。用来统一分配中断优先级和管理中断的。
2)NVIC优先级分组
NVIC的中断优先级由优先级寄存器的4位(0~15)决定,这4位可以进行切分,分为高n位的抢占优先级和低4-n位的响应优先级抢占优先级高的可以中断嵌套,响应优先级高的可以优先排队,抢占优先级和响应优先级均相同的按中断号排队。
抢占优先级&响应优先级区别
注意:优先级数字越大,优先级越低,反之优先级越高。
高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。 .抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。 .抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。 如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行。
特别说明:一般情况下,系统代码执行过程中,只设置一次中断优先级分组。
5.EXTI
1)简介
EXTI可以监测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXTI对应的中断程序。
支持的触发方式:上升沿(低电平—>高电平)/下降沿(高电平—>低电平)/双边沿(电平变化)/软件触发(程序里执行一段代码后触发)。
支持的GPIO口:所有GPIO口,但相同的Pin不能同时触发中断通道数:16个GPIO_Pin,外加PVD输出、RTC闹钟、USB唤醒、以太网唤醒触发。
响应方式:中断响应/事件响应(触发其他外设的操作)。
2)基本结构
3)AFIO复用IO口
AFIO主要用于引脚复用功能的选择和重定义在STM32中;
AFIO主要完成两个任务:复用功能引脚重映射、中断引脚选择。
4)EXTI框图
或门:只要输入一个1,输出就是高电平,只有全部输入0,输出才是低电平;
与门:只有全部输入1,输出才是高电平,反之则输出低电平;
非门(三角形加个圈):输入1就输出0,输入0就输出1.
二、实验
1.库函数代码
EXTI
(1)初始化EXTI,使用方法和GPIO一致。
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);
(2)软件触发外部中断。
void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);
(3)在主程序里查看和清除标志位
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);
void EXTI_ClearFlag(uint32_t EXTI_Line);
(4)在中断函数里查看和清除标志位。
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
NVIC+SysTick
(1)用来中断分组的,参数是中断分组的方式。
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
(2)初始化NVIC
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
(3)设置中断向量表
`void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);`
(4)系统低功耗配置
void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);
2.代码
(1)main.c
#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);}
}
(2) CountSensor.c
#include "stm32f10x.h" // Device header
uint16_t CountSensor_Count;void CountSensor_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//初始化GPIO口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);//配置APIOGPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);//配置EXTIEXTI_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_Falling;EXTI_Init(&EXTI_InitStruct);//配置NVICNVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);
}void EXTI15_10_IRQHandler(void)
{if(EXTI_GetFlagStatus(EXTI_Line14)==SET){CountSensor_Count++;EXTI_ClearITPendingBit(EXTI_Line14);}
}uint16_t CountSensor_Get(void)
{return CountSensor_Count;
}
(3)CountSensor.h
#ifndef __COUNT_SENSOR_H
#define __COUNT_SENSOR_Hvoid CountSensor_Init(void);
uint16_t CountSensor_Get(void);#endif
还会持续更新哒~