STM32外部中断(红外传感器与旋转编码器计数案例)

文章目录

  • 一、介绍部分
    • 简介中断系统
    • 中断执行流程
    • STM32中断
    • NVIC基本结构
    • NVIC优先级分组
    • 外部中断
      • 外部中断简介
      • 外部中断基本结构
      • 外部中断的流程
      • AFIO
      • EXTI框图
    • 相关外设介绍
      • 旋转编码器介绍
      • 硬件电路
      • 对射式红外传感器
  • 二、代码实现
    • 对射式红外传感器计次
      • 连接电路
        • 封装红外传感器与中断函数
    • 旋转编码器计数
      • 连接电路
        • 封装旋转编码器函数、外部中断函数
  • 补充



一、介绍部分

简介中断系统

在这里插入图片描述

中断执行流程

在这里插入图片描述

STM32中断

在这里插入图片描述
在这里插入图片描述
此地址是用于编译器来跳转到中断函数的地址

NVIC基本结构

NVIC作用是为CPU分配各个中断优先级,然后直接告诉CPU先执行的中断函数。

在这里插入图片描述

NVIC优先级分组

在这里插入图片描述

外部中断

外部中断简介

在这里插入图片描述

外部中断基本结构

在这里插入图片描述

外部中断的流程

**

AFIO先从GPIOA、GPIOB、GPIOC中选择16个不同Pin值的引脚(如不能同时有GPIOA 的PIN_1或GPIOB的PIN_1),以此来选出16个中断通道,然后选择这些中断是否是跳转到其他外设,不是的话就会通过NVIC来配置要打开的中断通道、中断通道的优先级,最后按照优先级顺序依次交予CPU执行

**

AFIO

在这里插入图片描述

EXTI框图

在这里插入图片描述

相关外设介绍

旋转编码器介绍

在这里插入图片描述

硬件电路

在这里插入图片描述

对射式红外传感器

两个面板对射红外线,被遮挡恢复一次后就会产生一个电平变化。
在这里插入图片描述

二、代码实现

对射式红外传感器计次

让对射式红外传感器每被遮挡一次时,让OLED显示的数字+1

连接电路

在这里插入图片描述

封装红外传感器与中断函数

IRSensor.c

#include "stm32f10x.h"                  // Device header
// 初始化
void IRSensor_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_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);EXTI_InitTypeDef EXTI_InitStructure;// 选择中断线,14号端口对应14号线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);// 设置中断优先级组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 Count = 0;
// 获取计数器的值
uint16_t GetCount(void){return Count;
}// 中断函数
void EXTI15_10_IRQHandler(void){// 获取中断线是否打开if(EXTI_GetITStatus(EXTI_Line14) == SET){// 如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0){// 计数器+1Count++;}// 清除中断EXTI_ClearITPendingBit(EXTI_Line14);}
}

主函数main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "IRSensor.h"int main(void)
{OLED_Init();IRSensor_Init();OLED_ShowString(1,1,"Count:");while (1){OLED_ShowNum(2,1,GetCount(),4);}
}

旋转编码器计数

连接电路

在这里插入图片描述

封装旋转编码器函数、外部中断函数

有多条中断线时,要分别初始化,不能有相同的优先级,不过定义的初始化结构体可以重复使用。

Encoder.c内容

#include "stm32f10x.h"                  // Device headeruint16_t EncoderCount;
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);// 配置AFIO引脚选择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);
}// 获取计数数据
uint16_t Encoder_Get(void){uint16_t Temp;Temp = EncoderCount;EncoderCount = 0;return Temp;
}// 中断函数
void EXTI0_IRQHandler(void){if(EXTI_GetITStatus(EXTI_Line0) == SET){if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0)EncoderCount++;// 清除此中断通道标志EXTI_ClearITPendingBit(EXTI_Line0);}
}
void EXTI1_IRQHandler(void){if(EXTI_GetITStatus(EXTI_Line1) == SET){if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0) == 0)EncoderCount--;// 清除此中断通道标志EXTI_ClearITPendingBit(EXTI_Line1);}
}

主函数main.c内容

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Encoder.h"int16_t Num;
int main(void)
{OLED_Init();Encoder_Init();OLED_ShowString(1,1,"Num:");while (1){// 每次的数加旋转的数Num += Encoder_Get();OLED_ShowSignedNum(2,1,Num,5);}
}

补充

两种获取中断标志与清除标志函数
前两中适用于普通函数执行
后两种适用于中断函数中执行

// 获取中断线标志
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);
// 清除此中断线标志
void EXTI_ClearFlag(uint32_t EXTI_Line);
// 获取中断线标志
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
// 清除此中断线标志
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);

中断函数可以在开始文件中寻找
在这里插入图片描述

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

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

相关文章

Cambalache in Ubuntu

文章目录 前言apt install flatpak这很ok快捷方式后记 前言 gtkmm4相比gtkmm3有很多改革, 代码也干净了许多, 但在windows上开发 有ui设计器那自然方便很多, 但glade又不支持gtkmm4, windows上装Cambalache很是困难. 各种问题都找不到答案.于是 我用VMware虚拟机Ubuntu20.xx安…

探索智慧文旅:科技如何提升游客体验

随着科技的迅猛发展,智慧文旅已成为旅游业的重要发展方向。通过运用先进的信息技术,智慧文旅不仅改变了传统旅游业的运营模式,更在提升游客体验方面取得了显著成效。本文将深入探讨科技如何助力智慧文旅提升游客体验。 一、智慧文旅的兴起与…

React详解

前言 React是一个用于构建用户界面的javaScript库,起源于facebook的内部项目,在13年f进行开源 17版本官网:React – A JavaScript library for building user interfaces 18版本官网:React 官方中文文档 特点: 声…

项目中使用sonar扫码代码

1.在maven的settings.xml配置 org.sonarsource.scanner.maven <profiles> <profile><id>sonar</id><activation><activeByDefault>true</activeByDefault></activation><properties><!-- Optional URL to server. D…

ubuntu20配置mysql8

首先更新软件包索引运行 sudo apt update命令。然后运行 sudo apt install mysql-server安装MySQL服务器。 安装完成后&#xff0c;MySQL服务将作为systemd服务自动启动。你可以运行 sudo systemctl status mysql命令验证MySQL服务器是否正在运行。 连接MySQL 当MySQL安装…

MySQL进阶45讲【10】MySQL为什么有时候会选错索引?

1 前言 前面我们介绍过索引&#xff0c;在MySQL中一张表其实是可以支持多个索引的。但是&#xff0c;写SQL语句的时候&#xff0c;并没有主动指定使用哪个索引。也就是说&#xff0c;使用哪个索引是由MySQL来确定的。 大家有没有碰到过这种情况&#xff0c;一条本来可以执行得…

【服务器】RAID(独立磁盘冗余阵列)

RAID&#xff08;独立磁盘冗余阵列&#xff09; 一、RAID的介绍二、RAID的分类#2-1 RAID 02-2 RAID 1#2-3 RAID 32-4 RAID 52-5 RAID 62-6 RAID 10(先做镜像&#xff0c;再做条带化)2-7 RAID 01&#xff08;先做条带&#xff0c;再做镜像&#xff09;2-8 RAID比较 三、磁盘阵列…

FANUC机器人示教器的菜单变成了图标,如何改成列表的形式?

FANUC机器人示教器的菜单变成了图标&#xff0c;如何改成列表的形式&#xff1f; 如下图所示&#xff0c;开机后按下MENU菜单键时&#xff0c;发现原来的列表形式变成了菜单图标的形式&#xff0c;同时在按F1-F5键时&#xff0c;提示&#xff1a;HMI模式-键不可用&#xff0c; …

蓝桥杯备战——12.超声波与测频代码优化

1.优化分析 昨天我在看原理图的发现超声波模块的反馈引脚P11刚好可以使用PCA模块0的捕获功能&#xff0c;我就想着把PCA功能留给超声波&#xff0c;然后测频功能还是改成定时器0来完成&#xff0c;然后前后台功能改成定时器1。 至于我为什么要这么改呢&#xff0c;看一下我原…

uniapp 高德地图显示

1. uniapp 高德地图显示 使用前需到**高德开放平台&#xff08;https://lbs.amap.com/&#xff09;**创建应用并申请Key   登录 高德开放平台&#xff0c;进入“控制台”&#xff0c;如果没有注册账号请先根据页面提示注册账号   打开 “应用管理” -> “我的应用”页面…

【Mysql】整理

Mysql整理与总结 整理Mysql的基本内容供回顾。 参考&#xff1a; [1]. 掘金.MySQL三大日志(binlog,redolog,undolog)详解 [2]. Javaguide.MySQL三大日志(binlog、redo log和undo log)详解

陶哲轩如何用 GPT-4 辅助数学研究

关于陶哲轩&#xff08;Terence Tao&#xff09;用 GPT-4 进行数学研究的话题始于陶本人在 微软 Unlocked 上发表的 Embracing Change and Resetting Expectations 一文。文中提到&#xff1a; …… I could feed GPT-4 the first few PDF pages of a recent math preprint and…

Zookeeper服务注册与发现实战

目录 设计思路 Zookeeper注册中心的优缺点 SpringCloudZookeeper实现微服务注册中心 第一步&#xff1a;在父pom文件中指定Spring Cloud版本 第二步&#xff1a;微服务pom文件中引入Spring Cloud Zookeeper注册中心依赖 第三步&#xff1a; 微服务配置文件application.y…

47 mmap 的实现

前言 mmap 函数经常是和 普通的 bio 进行一个参照对比 mmap 相比于 bio 减少了一次 系统空间 到 用户空间 的拷贝操作 普通的 bio 的流程可以参见这里 从磁盘读取数据到内存的调试 这里 我们来看一下 mmap 测试用例 测试用例如下, 仅仅是一个 mmap 的一个简单的使用 …

k8s之安装部署及kuboard发布应用

目录 环境准备 系统规划 配置免密 将桥接的IPv4流量传递到iptables的链 系统基础配置 安装docker 安装docker及基础依赖 配置docker的仓库下载地址 部署k8s 添加阿里云的k8s源 安装kubeadm&#xff0c;kubelet和kubectl 初始化masteer节点 部署node节点 部署flanne…

Java设计模式 – 四大类型

设计模式 – 四大类型 创建型模式结构型模式行为型模式J2EE模式 设计模式&#xff08;Design pattern&#xff09;是重构解决方案 根据书Design Patterns – Elements of Reusable Object-Oriented Software&#xff08;中文译名&#xff1a;设计模式 – 可复用的面向对象软件元…

2024美赛数学建模E题思路源码

赛题目的 可以将其拆解为以下主要问题&#xff0c;并为每个问题提出解决方案&#xff1a; 如何在极端天气事件越来越多的地区部署财产保险&#xff1f;保险公司应在何时何地承保保单&#xff1f;业主如何影响保险公司的承保决定&#xff1f;如何建立能够评估未来房地产决策的…

在windows和Linux中的安装 boost 以及 安装 muduo 和 mysql

一、CMake安装 Ubuntu Linux 下安装和卸载cmake 3.28.2版本-CSDN博客https://blog.csdn.net/weixin_41987016/article/details/135960115?spm1001.2014.3001.5501二、安装boost boost官网&#xff1a;boost官网 我下载的boost版本&#xff1a; windows:boost_1_84_0.zipli…

如何计算两个指定日期相差几年几月几日

一、题目要求 假定给出两个日期&#xff0c;让你计算两个日期之间相差多少年&#xff0c;多少月&#xff0c;多少天&#xff0c;应该如何操作呢&#xff1f; 本文提供网页、ChatGPT法、VBA法和Python法等四种不同的解法。 二、解决办法 1. 网页计算法 这种方法是利用网站给…

vscode debug无法直接查看eigen变量的问题(解决方法)

主要是给gdb添加一个Eigen相关的printer即可, 网上其他教程都搞太复杂了, 我整理成了一个仓库, 把仓库克隆下来直接运行 ./setup.sh脚本即可配置好 git clone gitgithub.com:fandesfyf/EigenGdb.git cd EigenGdb ./setup.sh 然后在vscode中重新debug即可。 效果 …