STM32中断和外部中断

 

NVIC:嵌套中断向量控制器:用于统一分配中断优先级和管理中断

响应式优先级:也可以称为插队式优先级哪个优先级高优先处理哪个

抢占式优先级:优先级高的可以优先被处理,相当于CPU可以暂时中断当前处理的程序,优先处理优先级更高的程序,该程序执行完成后再执行原先没有执行完毕的程序,也可以称之为嵌入式中断优先级

AFIO中断引脚选择:是一个中断引脚选择器可以在前面GPIO外设的16个引脚中选择一个连接到EXTI边沿检测及控制中所以

相同的Pin不能同时触发中断,因为PA0,PB0,PC0通过AFIO选择后只有其中一个可以连接到EXTI的通道0上,PB1,PC1等也只有一个可以接入EXTI上

模拟电子技术与或门基础

旋转编码器讲解

旋转编码器的硬件电路

外部中断寄存器代码

1:接线

#include "stm32f10x.h"                  // Device header// 编写初始化函数--->模块化的第一步是编写初始化函数
void CountSersor_Init(void){/*外部中断配置  1: 配置RCC进涉及的外部中断时钟全部打开2:配置GPIO选择端口为输入模式3: 配置AFIO选择需要使用到的GPIO并连接后面的exit4:配置EXTI选择边沿触发的方式如上升沿,下降沿,或者是双边沿,选择触发响应的方式5:配置NVIC给中断选择一个合适的优先级*/}

AFIO相关函数


             用于复位AFIO外设,调用这个函数会清除AFIO外设
             void GPIO_AFIODeInit(void);
             用于锁定GPIO配置调用这个函数参数指定某个引脚,锁定引脚配置防止意外更改
             void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
             以下的两个函数是用于配置AFIO的事件输出功能
           void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
           void GPIO_EventOutputCmd(FunctionalState NewState);

             这个函数可以用作引脚重映射,第一个参数是重映射的方式,第二个参数是新的状态
             void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);
          
  这个函数外部中断需要使用到的函数,调用这个函数可以选择我们的中断引脚
       void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
             和以太网相关外设暂时没有使用到
             void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);

EXTI相关函数

NVIC配置

编写中断函数代码实现当遮挡传感器时oled显示屏中的数字加1

中断函数代码

#include "stm32f10x.h"                  // Device header
uint16_t CountSensor_Count;// 编写初始化函数--->模块化的第一步是编写初始化函数
void CountSersor_Init(void){//1------>todo : 配置RCC进涉及的外部中断时钟全部打开// 开启GPIOB的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);// 开启AFIO的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);// EXPI和NVIC的时钟一直处于打开状态不需要我们手动开启//2------>todo : 配置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初始化函数,初始GPIOBGPIO_Init(GPIOB,&GPIO_InitStructure);// 3:todo ------->  配置AFIO选择需要使用到的GPIO并连接后面的exitGPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);// 3:todo ------->配置EXTI选择边沿触发的方式如上升沿,下降沿,或者是双边沿,选择触发响应的方式EXTI_InitTypeDef Exit_InitStruct;// 引出结构体成员Exit_InitStruct.EXTI_Line =EXTI_Line14; // 指定需要配置的中断线Exit_InitStruct.EXTI_LineCmd =ENABLE; // 开启中断Exit_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; // 模式:中断模式Exit_InitStruct.EXTI_Trigger =EXTI_Trigger_Falling ;// 下降沿触发EXTI_Init(&Exit_InitStruct);// 选择中断分组函数NVIC_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);}
uint16_t CountSensor_Get(void){return CountSensor_Count;
}void  EXTI15_10_IRQHandler(void){if(EXTI_GetITStatus(EXTI_Line14) == SET){CountSensor_Count++;// 中断程序结束后一定要清除中断程序标志位函数EXTI_ClearITPendingBit(EXTI_Line14);}
}

中断函数头文件

#ifndef __COUNT_SENSOR_H__
#define __COUNT_SENSOR_H__/*外部中断配置  1: 配置RCC进涉及的外部中断时钟全部打开2:配置GPIO选择端口为输入模式3: 配置AFIO选择需要使用到的GPIO并连接后面的exit4:配置EXTI选择边沿触发的方式如上升沿,下降沿,或者是双边沿,选择触发响应的方式5:配置NVIC给中断选择一个合适的优先级*/
void CountSersor_Init(void);
uint16_t CountSensor_Get(void);#endif

主函数调用代码

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "CounterSensor.h"int main(void)
{// 初始化oledOLED_Init();CountSersor_Init();// 使用OLED显示字符串OLED_ShowString(1,3,"Count:");while (1){OLED_ShowNum(1, 7, CountSensor_Get(), 5);   }
}

旋转编码器中断

接线

编写中断函数模块部分代码

Encoder.c

#include "stm32f10x.h"                  // Device headerint16_t Encoder_Count;// 编辑初始化函数
void Encoder_Init(void){//1------>todo : 配置RCC进涉及的外部中断时钟全部打开// 开启GPIOB的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);// 开启AFIO的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);// EXPI和NVIC的时钟一直处于打开状态不需要我们手动开启//2------>todo : 配置GPIO选择端口为输入模式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初始化函数,初始GPIOBGPIO_Init(GPIOB,&GPIO_InitStructure);// 3:todo ------->  配置AFIO选择需要使用到的GPIO并连接后面的exitGPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);// 3:todo ------->配置EXTI选择边沿触发的方式如上升沿,下降沿,或者是双边沿,选择触发响应的方式EXTI_InitTypeDef Exit_InitStruct;// 引出结构体成员Exit_InitStruct.EXTI_Line =EXTI_Line0 | EXTI_Line1; // 指定需要配置的中断线Exit_InitStruct.EXTI_LineCmd =ENABLE; // 开启中断Exit_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; // 模式:中断模式Exit_InitStruct.EXTI_Trigger =EXTI_Trigger_Falling ;// 下降沿触发EXTI_Init(&Exit_InitStruct);// 选择中断分组函数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);
}//中断函数
void EXTI0_IRQHandler(void){// 检查中断标志位if(EXTI_GetITStatus(EXTI_Line0) ==  SET){// 判断另外一个引脚的电平if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0){// 向着相反的方向旋转Encoder_Count--;}EXTI_ClearITPendingBit(EXTI_Line0);}
}// 调用函数后返回count的变化值
int16_t Encoder_Get(void){int16_t Temp;Temp = Encoder_Count;Encoder_Count = 0;return Temp;
}void EXTI1_IRQHandler(void){// 检查中断标志位if(EXTI_GetITStatus(EXTI_Line1) ==  SET){// 判断引脚的电平if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0) == 0){// 向着正方向旋转Encoder_Count++;}EXTI_ClearITPendingBit(EXTI_Line1);}
}

Encoder.h代码

#ifndef  __ENCODER_H__
#define  __ENCODER_H__
void Encoder_Init(void);
int16_t Encoder_Get(void);
#endif

main.c调用编写好的中断函数

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Encoder.h"int16_t Num;
int main(void)
{// 初始化oledOLED_Init();Encoder_Init();// 使用OLED显示字符串OLED_ShowString(1,1,"Num:");while (1){Num += Encoder_Get();OLED_ShowSignedNum(1,5,Num,5);}
}

注:编写中断函数代码时尽量做到简洁,同时主函数中使用到的功能模块函数不要编写在中断函数中,会出行编译错误,中断程序中避免添加延时函数,中断函数多事件的实时性处理能力较强。

以上是本人基于STM32中断部分知识的学习总结,参考B站江科大教程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/538042.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电脑闹钟软件,电脑上定时提醒的软件

我们生活在一个忙碌的时代,工作、学习、生活等各种事务时常让我们忙得不知所措。而在这样的情况下,一款电脑闹钟软件,电脑上定时提醒的软件就成为了我们不可或缺的工具之一。 电脑闹钟软件,电脑上定时提醒的软件,是一…

1个二维码能包含多个视频吗?制作视频二维码的方法

二维码在生活中现在随处可见,除了用于支付之外,展示内容也可以通过二维码来展现,比如常见的视频、图片、文件、音频等内容都可以通过二维码来展现。那么当我们需要将多个视频存入一个二维码中展示时,该如何利用二维码生成器的工具…

request库安装和使用

前言 requests 库是 Python 中用于发送 HTTP 请求的一个非常流行的库,它简单易用,广泛应用于各种场景。主要用于爬虫和Web 服务的测试.前者是对外进行数据的收集,后者就是服务的性能. 通识 requests库用于实现HTTP请求.那我们最好了解一下HTTP协议以及请…

免费 Copilot 用户可以访问 OpenAI 的 GPT-4 Turbo;面向 3D 虚拟环境的多面手 AI 代理

🦉 AI新闻 🚀 免费 Copilot 用户可以访问 OpenAI 的 GPT-4 Turbo 摘要:微软宣布免费版Copilot已升级到GPT-4 Turbo模型,所有用户都可以免费使用。此外,Copilot Pro新增了GPT Builder工具,订阅者可创建自定…

vi 显示行号 显示色彩

首先进入当前用户目录下的.vimrc文件/.virc文件(具体要看操作系统) vi ~/.virc 显示行号 set number 显示色彩 highlight LineNr guifgred 效果

如何打开EDI文件?

使用EDI系统传输文件的过程中,用户可能会遇到这样的问题:如何打开EDI文件?电脑不在身边如何查看EDI文件?EDI文件未按照标准格式呈现如何梳理?为了解决上述问题,方便用户查看文件,知行之桥EDI系统…

如何在数据库中存储小数:FLOAT、DECIMAL还是BIGINT?

前言 这里还是用前面的例子: 在线机票订票系统的数据表设计。此时已经完成了大部分字段的设计,可能如下: CREATE TABLE flights ( flight_id INT AUTO_INCREMENT PRIMARY KEY, flight_number VARCHAR(10), departure_airport_code VARCHAR(3), arrival_air…

SAT和SMT介绍及求解器使用

一、SAT 1、介绍 (1)定义 SAT即命题逻辑公式的可满足性问题/布尔可满足性问题。即给定一个与或非和变量组成的命题公式,判断是否存在一些结果使得这个公式成立 它是第一个被确认为NP完全的问题。 输入:析取范式(C…

Three 材质纹理 (总结三)

THREE.MeshLambertMaterial(网格 Lambert 材质) 该材质使用基于非物理的Lambertian模型来计算反射率。可以用来创建暗淡的并不光亮的表面,该材质非常易用,而且会与场景中的光源产生反应。 MeshLambertMaterial属性 # .color : …

深度学习技巧总结

1、监控GPU使用情况 pip install nvitopnvitop -m fullhttps://zhuanlan.zhihu.com/p/577533593 2、本地拉取服务器上tensorboard数据并进行可视化显示 https://blog.csdn.net/Thebest_jack/article/details/125609849 3、服务器打不开pycharm软件 这个是已经有一个软件在运…

用Robotframework+selenium 进行webui页面自动化测试

Robotframework其实就是一个自动化的框架,想要进行什么样的自动化测试,就需要在这框架上添加相应的库文件,而用于webui页面自动化测试的就是selenium库. ​ 关于robotframework框架的搭建我这里就不说了,今天就给大家根据一个登录…

Dynamic Wallpaper v17.4 mac版 动态视频壁纸 兼容 M1/M2

Dynamic Wallpaper Engine 是一款适用于 Mac 电脑的视频动态壁纸, 告别单调的静态壁纸,拥抱活泼的动态壁纸。内置在线视频素材库,一键下载应用,也可导入本地视频,同时可以将视频设置为您的电脑屏保。 应用介绍 Dynam…