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

news2024/9/21 18:59:27

文章目录

  • 一、介绍部分
    • 简介中断系统
    • 中断执行流程
    • 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){
			// 计数器+1
			Count++;
		}
		// 清除中断
		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 header

uint16_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.coloradmin.cn/o/1431397.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

清华系2B模型杀出,性能吊打LLaMA-13B

2 月 1 日,面壁智能与清华大学自然语言处理实验室共同开源了系列端侧语言大模型 MiniCPM,主体语言模型 MiniCPM-2B 仅有 24 亿(2.4B)的非词嵌入参数量。 在综合性榜单上与 Mistral-7B 相近,在中文、数学、代码能力表现…

怎么把物品信息图片批量生成二维码?每张图片单独生码的制作技巧

现在通过扫码来查看人员或者物品信息的方式越来越常见,在合适的位置放置对应的二维码内容,让其他人通过扫码来获取图片信息。那么如果我们将每个信息做成一张图片后,需要将图片生成二维码时,有能够批量生成二维码的方法可以快速处…

天地伟业接入视频汇聚/云存储平台EasyCVR详细步骤

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

基于深度卷积神经网络的图像配准(DeepSlice)

文章目录 一、基于DeepSlice的切片配准1.1、研究现状1.2、网络模型(DeepSlice)1.3、优化策略1.3.1、开发了一个基准数据集(GT)1.3.2、构建了阶段二的训练数据集(增强训练)1.3.3、角度集成 切割索引&#x…

[ChatGPT们】ChatGPT 如何辅助编程初探

主页:元存储的博客 全文 9000 字, 原创请勿转载。 我没有写过诗,但有人说我的代码像诗一样优雅 -- 雷军 图片来源:https://www.bilibili.com/video/BV1zL411X7oS/ 1. 引言 作为一个程序员,我们不仅要熟悉各种编程语…

ctfshow web入门 1-2 +密码签到

web1 F12源代码 web2 ctrlu cypto 签到 a}wohs.ftc{galf print(a[::-1])

使用 LoRA 在 vi​​ggo 数据集上微调 Microsoft phi-2 小语言模型

一、说明 Microsoft 的基于 Transformer 的小语言模型。它可以根据 MIT 许可在HuggingFace上使用。 它在 96 个 A100 GPU 上使用 1.4T 令牌进行了 14 天的训练。Phi-2 是一个 27 亿个参数的预训练 Transformer,不使用 RLHF 或指示微调。它进行下一个标记预测&#x…

RNN(神经网络)

目录 介绍: 数据: 模型: 预测: 介绍: RNN,全称为循环神经网络(Recurrent Neural Network),是一种深度学习模型,它主要用于处理和分析序列数据。与传统…

Python入门:生成器迭代器

一、列表生成式 现在有个需求,列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],要求你把列表里的每个值加1,怎么实现?你可能会想到2种方式 二逼青年版 1 2 3 4 a [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] b [] for i in a:b.append(i1) print(b) …

如果通过浏览器调试?

背景:博主是一个有丰富经验的后端开发人员,在前端开发中感觉总是有种力不从心的感觉,因为没有后端debug调试的清晰感。 解决办法:掌握chorm浏览器调试技巧。 F12, F5 打上断点之后,这不就是梦寐之中的调试…

Linux驱动 SPI子系统

1、SPI协议 SPI(Serial Peripheral Interface)是一种同步串行数据通信协议,通常用于连接微控制器和外部设备,如传感器、存储器、显示器等。SPI协议使用四根线进行通信,包括时钟线(SCLK)、数据输…

第十二篇【传奇开心果系列】Python的OpenCV技术点案例示例:视频流处理

传奇开心果短博文系列 系列短博文目录Python的OpenCV技术点案例示例短博文系列短博文目录一、前言二、视频流处理介绍三、实时视频流处理示例代码四、视频流分析示例代码五、归纳总结系列短博文目录 Python的OpenCV技术点案例示例短博文系列 短博文目录 一、前言 OpenCV视频…

【面试官问】Redis 持久化

目录 【面试官问】Redis 持久化 Redis 持久化的方式RDB(Redis DataBase)AOF(Append Only File)混合持久化:RDB + AOF 混合方式的持久化持久化最佳方式控制持久化开关主从部署使用混合持久化使用配置更高的机器参考文章所属专区

OfficeWeb365 Readfile 任意文件读取漏洞

免责声明:文章来源互联网收集整理,请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该…

Qt|实现时间选择小功能

在软件开发过程中,QtDesigner系统给出的控件很多时候都无法满足炫酷的效果,前一段时间需要用Qt实现选择时间的小功能,今天为大家分享一下! 首先看一下时间效果吧! 如果有需要继续往下看下去哟~ 功能 1:开…

池化技术的总结

文章目录 1.什么是池化技术2.池化技术的应用一、连接池二、线程池三、内存池 3.池化技术的总结 1.什么是池化技术 池化技术指的是提前准备一些资源,在需要时可以重复使用这些预先准备的资源。 在系统开发过程中,我们经常会用到池化技术。通俗的讲&am…

xlsx xlsx-style 使用和坑记录

1 安装之后报错 npm install xlsx --savenpm install xlsx-style --save Umi运行会报错 自己代码 import XLSX from "xlsx"; import XLSXStyle from "xlsx-style";const data [["demo1","demo2","demo3","demo4&quo…

电路设计(9)——八路智力抢答器的proteus仿真

1.设计要求 运用模拟电路、数字电路知识,设计、制作一个8路智力竞赛抢答器,要求有优先锁存、数显、声响及复位电路。 主要元器件:CD4511,IN4148,共阴数码管,NPN三极管9013,NE555,喇叭…

在工业制造方面,如何更好地实现数字化转型?

实现工业制造的数字化转型涉及利用数字技术来增强流程、提高效率并推动创新。以下是工业制造领域更好实现数字化转型的几个关键步骤: 1.定义明确的目标: 清楚地概述您的数字化转型目标。确定需要改进的领域,例如运营效率、产品质量或供应链…

[SWPUCTF 2021 新生赛]Do_you_know_http

我们看到它让我们用WLLM浏览器登录 那我们修改User-Agent的值即可 发现有一个a.php的我们进入该目录 它提示我们不在本地服务器上 发现有一个/secretttt.php的目录 我进入即可获得flag