stm32学习笔记:中断的应用:对射式红外传感器计次旋转编码器计次

news2025/9/21 12:49:15

相关API介绍

EXT配置API(stm32f10x exti.h)

NVIC 配置API (misc.h)

 初始化的中断的步骤

    第一步:配置RCC时钟,把涉及外设的时钟都打开
    第二步:配置GPIO,设置为输入模式
    第三步:配置AFIO,选择某个GPIO口连接到EXTI(边缘检测及控制器)
    第四步:配置EXTI(不需要开启时钟,原因不详),选择边沿触发方式和触发响应方式
    边沿触发方式:上升沿、下降沿、或者双边沿,触发响应方式:中断响应和事件响应
    第五步:配置NVIC(内核的外设,不需要开启时钟),给中断选择一个合适的优先级

 

 对射式红外传感器计次

CountSensor.h

#ifndef __COUNT_SENEOR_H
#define __COUNT_SENEOR_H

extern void CountSensor_Init(void);
extern uint16_t CountSensor_Get(void);

#endif
CountSensor.c
#include "stm32f10x.h"                  // Device header
 
uint16_t CountSensor_Count;
 
void CountSensor_Init(void)
{
	//第一步:配置RCC时钟,把涉及外设的时钟都打开
	//第二步:配置GPIO,设置为输入模式
	//第三步:配置AFIO,选择某个GPIO口连接到EXTI(边缘检测及控制器)
	//第四步:配置EXTI(不需要开启时钟,原因不详),选择边沿触发方式和触发响应方式
	//边沿触发方式:上升沿、下降沿、或者双边沿,触发响应方式:中断响应和事件响应
	//第五步:配置NVIC(内核的外设,不需要开启时钟),给中断选择一个合适的优先级
	
	//对射式红外传感器:B14
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	//参考手册中文版中,第八章GPIO有说明说明外设设置什么格式
	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;
	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);
	
	//5种分组方式选择其中的一种
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	//在stm32f10x.h中选择,该芯片是MD中等密度的,锁选择STM32F10X_MD即可
	//stm32的EXTI10到EXTI15都是合并到EXTI15_10_IRQn通道的
	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;//指定通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	//在misc文件中查找NVIC_Priority_Table,查的分组2的抢占优先级和响应优先级的取值范围均为0-3
	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)	//中断函数的名字都是固定的
{
	//因为10-15通道都可以进来,故要判断是不是想要的14通道进来
	if (EXTI_GetITStatus(EXTI_Line14) == SET)
	{
		/*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/
		if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0)
		{
			CountSensor_Count ++;
		}
		//中断程序结束后,一定要再调用一下清楚中断标志位的函数,
		//只有中断标志位置1,程序就会跳转到中断函数
		//如果不清除中断标志位,就会一直申请中断,
		//这样程序就会不断响应中断,执行中断函数,程序就会卡死在中断函数中
		EXTI_ClearITPendingBit(EXTI_Line14);
	}
}

 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)
	{
		//从第一行第7列开始写
		OLED_ShowNum(1, 7, CountSensor_Get(), 5);
	}
}

 旋转编码器计次

Encoder.c

如果把A相的下降沿用作触发中断,在中断时刻读取B相的电平
则正转是高电平,反转是低电平
正转时,A相先出现下降沿,所以刚开始动,就进中断了
反转后,A相先出现下降沿,转到位了,才进入中断

故该实验:A、B相都触发中断
正转:B相下降沿、A相低电平
反转:A相下降沿、B相低电平
这样保证正转和反转都是转到位,才执行数字加减的操作

#include "stm32f10x.h"                  // Device header
#include "Delay.h"

int16_t EncoderCount = 0;

void Encoder_Init(void)
{
	// 配置RCC, 将涉及到的外设全部打开, 不打开时钟外设无法工作
	// EXTI 和 NVIC 的时钟是一直打开的, 不需要再开启时钟了, 因为 NVIC 是内核的外设
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);    // 开启 GPIOB 的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);     // 开启 AFIO  的时钟
	
	// 配置 GPIO_Pin_B0 | GPIO_Pin_B1, 设置端口为输入模式
	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 到后面的 EXTI
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);    // PB0 -> EXTI0
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);    // PB1 -> EXTI1

	// 配置 EXTI: 将EXTI的第0、1个线路配置为中断模式、下降沿触发、然后开启中断
	EXTI_InitTypeDef EXTI_InitStruct;
	EXTI_InitStruct.EXTI_Line = EXTI_Line0 | EXTI_Line1;    // 选择PB0 所在的第0个线路、选择 PB1 所在的第1个线路
	EXTI_InitStruct.EXTI_LineCmd = ENABLE;                  // 开启中断
	EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;        // 中断模式 或 事件模式
	EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;    // 下降沿触发                     
	EXTI_Init(&EXTI_InitStruct);
	
	// 配置 NVIC, 给 EXTI0 中断选择一个合适的优先级, 最终外部中断信号就能进入 CPU 了
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);         // 2位抢占, 2位响应, 整个工程需要设置成一致的.
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;       // 选择进入 NVIC 的通道 
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;            // 通道使能
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;  // 抢占优先级: 0~3
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;         // 响应优先级: 0~3
	NVIC_Init(&NVIC_InitStruct);
	
	// 配置 NVIC, 给 中断选择一个合适的优先级, 最终外部中断信号就能进入 CPU 了
	NVIC_InitStruct.NVIC_IRQChannel = EXTI1_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;            // 通道使能
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;  // 抢占优先级: 0~3
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;         // 响应优先级: 0~3
	NVIC_Init(&NVIC_InitStruct);
}

void EXTI0_IRQHandler(void)    
{
	ITStatus res = EXTI_GetITStatus(EXTI_Line0);           // 判断是否是 EXIT0
	if(SET == res) 
	{
		// 抖动延时下 
		Delay_ms(3);
		if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0 && GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)  // 正转
		{
			EncoderCount--;
		}
		
		EXTI_ClearITPendingBit(EXTI_Line0);                // 清除中断标志位
	}	
}

void EXTI1_IRQHandler(void)    
{
	ITStatus res = EXTI_GetITStatus(EXTI_Line1);           // 判断是否是 EXIT1
	if(SET == res) 
	{
		// 抖动延时下 
		Delay_ms(3);
		if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0 && GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0)  // 反转
		{
			EncoderCount++;
		}
		
		EXTI_ClearITPendingBit(EXTI_Line1);                // 清除中断标志位
	}	
}

int16_t Encoder_Get(void)
{
	int16_t Temp = EncoderCount;
	EncoderCount = 0;
	return Temp;
}

 Encoder.h

#ifndef __ENCODER_H
#define __ENCODER_H

extern void Encoder_Init(void);
extern int16_t Encoder_Get(void);

#endif

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "oled.h"
#include "encoder.h"

static int16_t Num = 0;

int main(void)
{				
	OLED_Init();
	Encoder_Init();
	OLED_ShowString(1, 1, "Num:");
 	while(1)	
	{
		Num += Encoder_Get();
		OLED_ShowSignedNum(1, 5, Num, 5);
	}
}

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

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

相关文章

JFLASH基本使用总结

注意,不同版本的操作略有不同,本教程以J-Flash V5.12f为例。 烧录文件 如果是刚打开J-Flash,会弹出这样的一个工程选择界面,可以选择已有工程,或者创建新的工程,我们这里选择创建新工程。 注意&#xff0…

软件设计师学习笔记12-数据库的基本概念+数据库的设计过程+概念设计+逻辑设计

1.数据库的基本概念 1.1数据库的体系结构 1.1.1常见数据库 ①集中式数据库 数据是集中的;数据管理是集中的 ②C/S结构 客户端负责数据表服务;服务器负责数据库服务;系统分前后端;ODBC、JDBC ③分布式数据库 物理上分布、逻…

Windows-C盘清理

//1.常用软件: Chrome: C:\Users\Administrator\AppData\Local\Google\Chrome\User Data\Default\Code Cache\js C:\Program Files\Google\Chrome\Application\ //2.系统缓存 远程桌面缓存 C:\Users\Administrator\AppData\Local\Microsoft\Termin…

2023年电工(初级)证考试题库及电工(初级)试题解析

题库来源:安全生产模拟考试一点通公众号小程序 2023年电工(初级)证考试题库及电工(初级)试题解析是安全生产模拟考试一点通结合(安监局)特种作业人员操作证考试大纲和(质检局&#…

C-Pack: Packaged Resources To Advance General Chinese Embedding

简介 论文提出了一个C-pack资源集合,其中包括三个主要的部分: C-MTEB一个中文综合基准集合,包括6个任务和35个数据集合。C-MTP一个中文embedding数据集合,包括unlabeled和labeled两种数据。C-TEM一个embedding模型家族&#xff0…

C语言水平测试题 过关斩将(1)C语言的那些坑题,你可知道❓

我的个人主页:☆光之梦☆的博客_CSDN博客-C语言基础语法(超详细)领域博主 欢迎各位 👍点赞 ⭐收藏 📝评论 我的专栏:C语言基础语法(超详细)_☆光之梦☆的博客-CSDN博客(这…

C# 使用 RSA 加密算法生成证书签名产生“The system cannot find the file specified”异常

使用 C# 中 RSA(System.Security.Cryptography.RSA) 加密算法生成证书签名进行身份验证,在 VS2022 开发工具本地运行应用程序一切正常。 但将应用程序部署到远程服务器(如:Azure App Services)&#xff0c…

自动化测试的执行策略详解

前言 自动化测试的执行策略是指在自动化测试过程中,为了达到测试目标和要求,所采用的测试执行方案和策略。 执行策略涉及到测试用例的执行顺序、方式、环境、频率等方面的决策。 同时,我也准备了一份软件测试视频教程(含接口、…

【技术干货】如何快速创建商用照明 OEM APP?

本文介绍了如何在涂鸦 IoT 平台的 App 工作台上创建一款体验版商照 App、正式版 OEM App、上架 App、以及完成通用配置。 OEM App 开发 创建 App 登录 涂鸦 IoT 平台的 App 页面。 单击 创建APP,选择 商照 APP 进行创建。 在提示框里,完善 App 信息…

SpringBoot 接口 字节数组直接显示为图片

源码: import java.io.ByteArrayOutputStream; import javax.imageio.ImageIO; import org.springframework.web.bind.annotation.RequestMapping;/*** 获取二维码图像* 二维码支付** param price 金额* return 二维码图像* throws IOException IOException*/ Requ…

掌动智能:UI自动化测试工具几点优势

UI自动化测试工具在现代软件开发中扮演着重要的角色,它们能够有效地验证应用程序的用户界面,确保其在不同平台和设备上的正常运行。本文将介绍掌动智能UI自动化测试工具的优势有哪些! 掌动智能UI自动化测试工具优势 1、零成本入门 自然语言编写&#xff…

单目标应用:墨西哥蝾螈优化算法(Mexican Axolotl Optimization,MAO)求解微电网优化--MATLAB代码

一、微网系统运行优化模型 微电网优化模型介绍: 微电网多目标优化调度模型简介_IT猿手的博客-CSDN博客 二、墨西哥蝾螈优化算法MAO 墨西哥蝾螈优化算法(Mexican Axolotl Optimization,MAO)由Yenny Villuendas-Rey 1等人于2021…

代码随想录算法训练营第23期day20| 530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先

目录 一、(leetcode 530)二叉搜索树的最小绝对差 二、(leetcode 501)二叉搜索树中的众数 1.二叉搜索树 2.非二叉搜索树 思路 三、(leetcode 236)二叉树的最近公共祖先 一、(leetcode 530&…

v-model 原理

v-model 原理 : 对应的是 v-bind 对应额是 v-on 创建 工程: H:\java_work\java_springboot\vue_study ctrl按住不放 右键 悬着 powershell H:\java_work\java_springboot\js_study\Vue2_3入门到实战-配套资料\01-随堂代码素材\day04\准备代码\10-…

Tomcat和HPPT协议

1.介绍 1.Java EE 规范 JavaEE(java Enterprise Edition):java企业版 JavaEE 规范是很多的java开发技术的总称。这些技术规范都是沿用自J2EE的。一共包括了13个技术规范 2.WEB概述 WEB在计算机领域中代表的是网络 像我们之前所用的WWW&…

JS VUE 用 canvas 给图片加水印

最近写需求,遇到要给图片加水印的需求。 刚开始想的方案是给图片上覆盖一层水印照片,但是这样的话用户直接下载图片水印也会消失。 后来查资料发现用 canvas 就可以给图片加水印,下面是处理过程。 首先我们要确认图片的格式,我们通…

【Java 进阶篇】JavaScript三元运算符详解

JavaScript是一门广泛用于前端和后端开发的编程语言,具备强大的表达式和运算符。本篇博客将重点介绍JavaScript中的三元运算符,解释其语法、用法和示例。如果您是JavaScript初学者,或者希望更深入了解这门语言的运算符,那么这篇博…

mysql面试题44:MySQL数据库cpu飙升的话,要怎么处理?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:MySQL数据库cpu飙升的话,要怎么处理呢? 当MySQL数据库的CPU使用率飙升时,可能表示数据库负载过重或存在性能问题。以下是处理MySQL数据库CPU飙…

VSS、VDD、VBAT、VSSA

引言 在学习设计TM32时,发现芯片除了GPIO引脚外还会引出许多引脚,以STM32F407ZGT6为例除了GPIO引脚还会有以下引脚 如VSS、VDD、VBAT、VSSA、NRST、VREF、VDDA、VCAP_1、VCAP_2、PDR_ON这些引脚。他们有何作用,电路设计中应如何连接&#x…

【SCS-CN】SCS-CN模型中CN值的确定

目录 一、说明二、SWAT三、HEC-HMS四、CN值转换公式五、确定CN25.1 ArcSWAT 2009用户指南5.2 SWAT plus Document5.3 National Engineering Handbook5.4 HEC-HMS水文建模系统原理方法应用5.5 Technical Release 55 (TR-55) 六、确定水文土壤单元(HSG)6.1…