当前位置:网站首页>[Jiangsu University Automation Association stm32F103c8t6] Notes [Initial 32 MCU and EXTI External Interrupt Initialization Parameter Configuration]
[Jiangsu University Automation Association stm32F103c8t6] Notes [Initial 32 MCU and EXTI External Interrupt Initialization Parameter Configuration]
2022-07-30 07:14:00 【Clockwisee】
四、返回值函数
uint8_t Key_GetNum(void) Here with our regularvoidThe function written is different,uint8_t There can be a return value as a start
returnOnce returned,程序结束(But only function programs that return a value),The function has a numeric effect
uint8_t Key_GetNum(void)
{
uint8_t KeyNum = 0;
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
{
Delay_ms(20);
while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0);
Delay_ms(20);
KeyNum = 1;
}
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0)
{
Delay_ms(20);
while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0);
Delay_ms(20);
KeyNum = 2;
}
return KeyNum;
}
五、EXTI外部中断
EXTI基本结构---------------------------------Writing principles 如图中所述
1、配置RCC
Turn on all involved clocks
2、配置GPIO
Select our port as input mode
3、配置AFIO
选择我们用的这一路GPIO,连接到后面的EXTI
4、配置EXTI
选择边沿触发方式,比如上升沿、下降沿或者双边沿,There is also an option to trigger a response,Interrupt response can be selected(Generally configure this)和事件响应
5、配置NVIC
Give us an appropriate priority for this interrupt,通过NVIC,External interrupt signal can enterCPU了,这样CPUCan receive interrupt signal,To jump to the interrupt function to execute the interrupt program
——————————————————————————————————————There are five peripherals involved hereRCC、GPIO、AFIO、EXTI(There are no registersEXTI时钟的控制位)、NVIC(内核的外设,不用RCC开启时钟,RCCIt's the peripherals)
比如 : 我们将PB12Set as an interrupt pin
//首先,配置APB2总线上的RCC时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能gpio时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//使能afio时钟
//初始化GPIO
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入 (查手册 EXTI浮空、上拉、下拉 都行)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); //配置gpio
//其次,选择AFIO中断引脚
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource12);//配置AFIO中断引脚选择
//配置EXTI 类似于GPIO初始化
EXTI_InitTypeDef EXTI_InitStructure;//有四个参数
EXTI_InitStructure.EXTI_Line //EXIT_Line0 ~19 其中line16 ~line19 是 PVD(电压检测器) RTC(实时时钟) USB ETH(以太网)
EXTI_InitStructure.EXTI_LineCmd //ENABLE 开启 FALSE 关闭
EXTI_InitStructure.EXTI_Mode // EXTI_Trigger_Rising Upper edge trigger EXTI_Trigger_Falling Lower edge trigger EXTI_Trigger_Rising_Falling 双边沿触发
EXTI_InitStructure.EXTI_Trigger // EXTI_Mode_Interrupt 中断触发 EXTI_Mode_Event 事件触发
EXTI_Init(&EXTI_InitStructure)//void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)
//配置NVIC NVIC函数在Library----misc.h里面
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//在中断之前,First specify the interrupt grouping,分组2,2抢占 ,2响应,抢占(先占):It is equivalent to direct entry in severe casesicu
响应(从占):Equivalent to jumping in line to the next one
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //指定中断通道来开启或关闭 //每个f1型号不一样,c8是MDMedium model 10-15 都在EXTI15_10_IRQn里 //5-9 中断线 share one interrupt channel EXTI9_5_IRQn 10-15中断线 share one interrupt channel EXIT15_10IRQn//EXTI0_IRQn 指定通道
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//Specifies whether the channel is enabled or disabled
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级 2组 0-3 //There is one in the interruption //Multiple interrupt sources can consider changing the number of priority levels
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //响应优先级 0-3 //There is one in the interruption
NVIC_Init(&NVIC_InitStructure);//
//——————————————————————————————————————————————————————————————————————————————Here the external interrupt is written
//Write the interrupt function below
整个工程NVICOnly one grouping method can be used,In modular grouping, each module uses the same one,都需要写一次,如果放在main.cIt only needs to be written once at the beginning
中断函数
Each interrupt channel corresponds to an interrupt function,The name of the interrupt channel is the name of its corresponding interrupt function,At this point we can jump to the definition to copy and paste
——————————————————————————————————————————————————————————————————————————————Here the external interrupt is written
//Write the interrupt function below
void EXTI15_10_IRQHandler(void)///EXTI0_IRQHandler //The interrupt function does not need to be placed.h里面申明,它是自动执行的
{
if (EXTI_GetITStatus(EXTI_Line11) == SET) //Determine if the interrupt line is1
{
CountSensor_Count ++;
EXTI_ClearITPendingBit(EXTI_Line12);//Generally, the judgment of the interrupt flag bit is carried out in the interrupt function,Make sure that this function is triggered by the interrupt source we want To keep clearing the interrupt flag bit ,Otherwise the interrupt flag bit is1,Always execute the interrupt program and get stuck in the interrupt program
}
}
//Check the clear status in the interrupt function
EXTI_GetITStatus(EXTI_Line12)
EXTI_ClearITPendingBit(EXTI_Line12)
//Check the clearing status in the main program
EXTI_GetFlagStatus()
EXTI_ClearFlag()
最后献上代码:
viod CountSensor_Init(void)
{
//首先,配置APB2总线上的RCC时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能gpio时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//使能afio时钟
//初始化GPIO
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入 (查手册 EXTI浮空、上拉、下拉 都行)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); //配置gpio
//其次,选择AFIO中断引脚
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource12);//配置AFIO中断引脚选择
//配置EXTI 类似于GPIO初始化
EXTI_InitTypeDef EXTI_InitStructure;//有四个参数
EXTI_InitStructure.EXTI_Line //EXIT_Line0 ~19 其中line16 ~line19 是 PVD(电压检测器) RTC(实时时钟) USB ETH(以太网)
EXTI_InitStructure.EXTI_LineCmd //ENABLE 开启 FALSE 关闭
EXTI_InitStructure.EXTI_Mode // EXTI_Trigger_Rising Upper edge trigger EXTI_Trigger_Falling Lower edge trigger EXTI_Trigger_Rising_Falling 双边沿触发
EXTI_InitStructure.EXTI_Trigger // EXTI_Mode_Interrupt 中断触发 EXTI_Mode_Event 事件触发
EXTI_Init(&EXTI_InitStructure)//void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)
//配置NVIC NVIC函数在Library----misc.h里面
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//在中断之前,First specify the interrupt grouping,分组2,2抢占 ,2响应,抢占(先占):It is equivalent to direct entry in severe casesicu
响应(从占):Equivalent to jumping in line to the next one
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //指定中断通道来开启或关闭 //每个f1型号不一样,c8是MDMedium model 10-15 都在EXTI15_10_IRQn里 //5-9 中断线 share one interrupt channel EXTI9_5_IRQn 10-15中断线 share one interrupt channel EXIT15_10IRQn//EXTI0_IRQn 指定通道
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//Specifies whether the channel is enabled or disabled
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级 2组 0-3 //There is one in the interruption //Multiple interrupt sources can consider changing the number of priority levels
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //响应优先级 0-3 //There is one in the interruption
NVIC_Init(&NVIC_InitStructure);//
}
//——————————————————————————————————————————————————————————————————————————————Here the external interrupt is written
//Write the interrupt function below
void EXTI15_10_IRQHandler(void)///EXTI0_IRQHandler //The interrupt function does not need to be placed.h里面申明,它是自动执行的
{
if (EXTI_GetITStatus(EXTI_Line11) == SET) //Determine if the interrupt line is1
{
CountSensor_Count ++;
EXTI_ClearITPendingBit(EXTI_Line12);//Generally, the judgment of the interrupt flag bit is carried out in the interrupt function,Make sure that this function is triggered by the interrupt source we want To keep clearing the interrupt flag bit ,Otherwise the interrupt flag bit is1,Always execute the interrupt program and get stuck in the interrupt program
}
}
Then offer the initialization code of the two interrupt functions(旋转编码器):
int16_t Encoder_Count;
void Encoder_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_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line0 | EXTI_Line1;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStructure);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_Init(&NVIC_InitStructure);
}
int16_t Encoder_Get(void)
{
int16_t Temp;
Temp = Encoder_Count;
Encoder_Count = 0;
return Temp;
}
void EXTI0_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line0) == SET)
{
/*If there is a phenomenon of data jitter,The pin level can be judged again,to avoid jitter*/
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0)
{
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
{
Encoder_Count --;
}
}
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
void EXTI1_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line1) == SET)
{
/*If there is a phenomenon of data jitter,The pin level can be judged again,to avoid jitter*/
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
{
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0)
{
Encoder_Count ++;
}
}
EXTI_ClearITPendingBit(EXTI_Line1);
}
}
建议: 1、The interrupt function should not be too long,Don't add too long delays
2、Do not call the interrupt function on the same hardware as the main program,如:同时调用OLED,OLED会显示错误,Interrupt variables and flags can be manipulated,Then operate the display in the main program
边栏推荐
- 二叉树(一):深度优先遍历与广度优先遍历
- QT串口动态实时显示大量数据波形曲线(四)========“界面的美化与处理”
- [Punctuality Atom] Simple application of sys.c, sys.h bit-band operations
- HSPF model application
- 用户密码加密编码使用 Bcrypt 代替 MD5,SHA1和SHA256
- 逻辑右移和算术右移区别
- “R语言+遥感”的水环境综合评价方法
- 基于OpenCV的相机标定流程
- 遥感、GIS和GPS技术在水文、气象、灾害、生态、环境及卫生等应用
- User password encryption using Bcrypt instead of MD5, SHA1 and SHA256
猜你喜欢
无人机生态环境监测、图像处理与GIS数据分析
BLDC电机应用持续火爆,“网红神器”筋膜枪前景几何?
Configure MMdetection environment and train
Self-augmented Unpaired Image Dehazing via Density and Depth Decomposition程序运行记录
Pytorch(二):数据读取机制(DataLoader、DataSet)与图像预处理模块(transforms)
二叉树(一):深度优先遍历与广度优先遍历
OpenCV中(rows,cols)与图像(x,y)
【正点原子】IIC的学习与使用(未完...)
昆仑通态屏幕制作(连载1)---接触篇
基于全球模式比较计划CMIP6与区域气候-化学耦合模式 WRF-Chem 的未来大气污染变化模拟
随机推荐
Meta分析在生态环境领域里的应用
昆仑通态屏幕制作(连载5)---基础篇(串口接收,文本与灯显示)
边境的悍匪—机器学习实战:第六章 决策树
边境的悍匪—机器学习实战:第十一章 训练深度神经网络
CPU的三种工作模式:实模式、保护模式、长模式
2021-09-16 集成学习上--task1机器学习数学基础
HSPF model application
自定义类加载器
对于国内数据交换平台的分析
Application of remote sensing, GIS and GPS technology in hydrology, meteorology, disaster, ecology, environment and health
电子工程师怎么才能规范设计标准、提高设计效率?
干货 | 什么是FOC?一文带你看BLDC电机驱动芯片及解决方案
基于R语言地理加权回归、主成分分析、判别分析等空间异质性数据分析
无人机生态环境监测、图像处理与GIS数据分析
昆仑通态屏幕制作(连载2)---基础篇(设定与显示,串口发送)
Pytorch(一):动态图机制以及框架结构
基于QT的CAN通讯数据实时波形显示(连载八)====“子函数或新类调用ui控件”
HSPF 模型应用
华秋电子成为开放原子开源基金会openDACS捐赠人,共建 openDACS开源生态
基于PyTorch深度学习无人机遥感影像目标检测、地物分类及语义分割