STM32单片机(五)第二节:EXTI外部中断练习(对射式红外传感器计次和旋转编码器计次)

news2025/2/6 20:10:42

❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。
☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋。
🌙专栏目标:实现从零基础入门51单片机和STM32单片机,力求在玩好单片机的同时,能够了解一些计算机的基本概念,了解电路及其元器件的基本理论等。

⭐️ 专栏主要内容: 主要学习STM32单片机的功能、各个模块、单片机的外设、驱动等,最终玩好单片机和单片机的外设,全程手敲代码,实现我们所要实现的功能。
🌴 专栏说明 :如果文章知识点有错误的地方,欢迎大家随时在文章下面评论,我会第一时间改正。让我们一起学习,一起进步。
💑专栏主页:http://t.csdn.cn/HCD8v

本学习过程参考:https://space.bilibili.com/383400717

STM3单片机安装软件、各种资料以及源码的路径:
链接:https://pan.baidu.com/s/1snD0uuTfMhchFqOMWvAiHA?pwd=asdf#list/path=%2F
提取码:asdf

链接里压缩包的解压密码:32

本大节主要学习STM32的中断系统和外部中断,包含两部分,第一小节主要学习中断系统的基础知识,第二小节是写两个程序进行练习,即对射式红外传感器计次和旋转编码器计次,最终附上所有的源代码;
本小节主要是对上一节学习的EXTI外部中断进行实战练习,编写两个程序进行练习,分别实现对射式红外传感器计次和旋转编码器计次等,并附上程序源码;

文章目录

  • 一、本节目标
  • 二、设备介绍
    • 2.1 设备介绍
    • 2.1.1 旋转编码器介绍
    • 2.1.2 旋转编码器硬件电路
  • 三、对射式红外传感器计次源码
    • 3.1 接线图
    • 3.2 代码
      • 3.2.1 代码逻辑:
      • 3.2.2 代码解释:
      • 3.2.3 完整代码
  • 四、旋转编码器计次源码
    • 4.1 接线图
    • 4.2 代码

一、本节目标

目标1:对射式红外传感器计次

实现OLED显示屏上实时显示红外传感器被挡光的次数。
过程是我们对红外传感器进行挡光,随后把手拿开;这样挡光–拿开的过程,每进行一次,OLED上显示的次数加1;如下图所示:

在这里插入图片描述

目标2:旋转编码器计次

转动“旋转编码器”时,OLED屏幕上的数字也跟着变化;例如当向右转动旋转编码器时,屏幕上的数字变大,向左转动旋转编码器时,屏幕上的数字变小,如下图所示,初始数字为0

在这里插入图片描述
当向右旋转时,数字逐渐变大:
在这里插入图片描述

向左旋转时,数字变小
在这里插入图片描述

二、设备介绍

2.1 设备介绍

2.1.1 旋转编码器介绍

在这里插入图片描述

  • 第一个图的旋转编码器只能测位置和速度,不能测方向
  • 第二个图是本课程使用的旋转编码器,第三张图是其内部拆解;既可以测位置和速度,也可以测方向;

2.1.2 旋转编码器硬件电路

在这里插入图片描述

三、对射式红外传感器计次源码

3.1 接线图

在这里插入图片描述
对射式红外传感器模块,VCC、GND分别接电源的正负极,DO数字输出端,随意选择一个GPIO口接上就行,在这里我接到了B14端口;

硬件接线图如下所示:

在这里插入图片描述

程序逻辑:
当我们的挡光片或者编码盘在这个对射式红外传感器模块中间经过时,这个DO就会输出电平变化的信号,然后这个电平跳变的信号触发STM32 PB14号口的中断,我们在中断函数里执行变量++的程序,并最终输出在OLED上即可。

3.2 代码

代码路径:\STM32入门教程资料\STM32入门教程资料\程序源码\程序源码\STM32Project\5-1 对射式红外传感器计次\User

3.2.1 代码逻辑:

在这里插入图片描述

  • 第一步,配置RCC,把涉及到的外设的时钟都打开,一定要谨记,不打开时钟,外设是没法工作的;
  • 第二步,配置GPIO,选择我们的端口为输入模式
  • 第三步,配置AFIO,选择我们用哦的这一路GPIO,连接到后面的EXTI
  • 第四步,配置边沿触发方式,比如上升沿、下降沿或者双边沿;还有选择触发响应方式,可以选择中断响应和事件响应;
  • 第五步,配置NVIC,给我们这个中断选择一个合适的优先级;
  • 最后,通过NVIC,外部中断信号就能进入CPU了,这样CPU才能收到中断信号,才能跳转到中断函数里执行中断程序;

以上就是外部中断的配置流程,涉及到的外设包括RCC、GPIO、AFIO、EXTI、NVIC。

3.2.2 代码解释:

第一步开启时钟:
开启GPIOB和AFIO的时钟:
在这里插入图片描述
EXTI、NVIC的时钟默认是开启的,所以不需要程序开启;

第二步配置GPIO为输入模式:
在这里插入图片描述
第三步,配置AFIO外设:
在这里插入图片描述
选择GPIOB,连接PB14号口的第14个中断线路;

第四步,配置EXTI:

EXTI的所有库函数如下,
在这里插入图片描述
EXTI初始化:
在这里插入图片描述
将EXTI的第14个线路配置位中断模式,下降沿触发;

第五步:配置NVIC:

NVIC库函数:

在这里插入图片描述
在这里插入图片描述

3.2.3 完整代码

#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)
	{
		OLED_ShowNum(1, 7, CountSensor_Get(), 5);
	}
}

CountSensor.c

#include "stm32f10x.h"                  // Device header

uint16_t CountSensor_Count;

void CountSensor_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);
	
	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);
	
	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)
	{
		/*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/
		if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0)
		{
			CountSensor_Count ++;
		}
		EXTI_ClearITPendingBit(EXTI_Line14);
	}
}

四、旋转编码器计次源码

代码路径:\STM32入门教程资料\STM32入门教程资料\程序源码\程序源码\STM32Project\5-2 旋转编码器计次\User

4.1 接线图

在这里插入图片描述
左边旋转编码器模块,上面VCC和GND接正负极,下面这两个A,B相输出引脚,分别接到STM32的PB0和PB1两个引脚;

实物接线图如下所示:

在这里插入图片描述

4.2 代码

#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(1, 5, Num, 5);
	}
}

Encoder.c:

#include "stm32f10x.h"                  // Device header

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 (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 (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
		{
			if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0)
			{
				Encoder_Count ++;
			}
		}
		EXTI_ClearITPendingBit(EXTI_Line1);
	}
}

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

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

相关文章

深入学习 Linux 操作系统的存储 IO 堆栈

一、Linux 存储堆栈图 当使用 read() 和 write() 系统调用向内核提交读写 I/O 请求操作时需要经历的步骤: 1)首先,请求经过虚拟文件系统,虚拟文件系统提供了统一的文件和文件系统的相关接口,屏蔽了不同文件系统的差异…

Applied soft computing期刊投稿流程

爱斯唯尔账户注册问题: 账号所属作者即默认通讯作者 刚开始应该会进入这个页面,这里的用户名和密码一般是导师(通讯作者)的账号密码,可以询问老师,然后点击author login登陆就好。 注册里面强调一点,这里面的Title 一般是职称的意思,如果是学生可以填Mr.或者Mrs. 投…

Python 网络舆情分析系统,舆论可视化界面

1 简介 舆情管理系统,这不仅仅可以帮助当地的管理人员迅速的排查跟本地有关的负面言论,还可以避免网民因为本身意识不到位而评论或发布一些不好的观点的情况,最终的目的就是帮助社会更好的发展。 2 技术栈 说明技术栈备注后台Python前端HT…

多线程:Lamda表达式

Lamda表达式 希腊字母表中第十一个字母,英文名字为lambda避免匿名内部类定义过多其实质是函数类编程的概念new Thread (() -->System.out.println(“多线程的学习…”)).start();为什么要使用Lamda表达式? 1、避免匿名内部类定义过多 2、可以让你的代…

Vue中如何进行移动端适配与响应式布局?

Vue中如何进行移动端适配与响应式布局? 如今,移动端适配与响应式布局已经成为Web开发中不可或缺的一部分。Vue.js作为一款流行的JavaScript框架,也提供了许多有用的工具和技术来实现移动端适配和响应式布局。在这篇文章中,我们将…

阿里云服务器ESSD PL-0云盘与ESSD PL-1云盘区别及选择参考

在我们选购阿里云服务器的时候,通常系统盘与数据盘类型都是ESSD云盘,而云盘的性能又分为PL-0和PL-1,虽然都属于ESSD云盘,但是它们之间的性能是有区别的,收费标准也不一样,本文为大家介绍一下阿里云服务器ES…

26岁,大学肄业,家里蹲5年,这位失业青年的求救,牵动百万网友的心……

近期,知乎上有一个求救贴火了,浏览量一度飙升到480多万,近千名网友在帖子下留言,纷纷表达自己的看法。 帖子是这样的。题主26岁,大学肄业。最长只上过12天的班,每次出门面试找工作就会非常害怕&#xff0c…

win11 idea shift+F6快捷键失效问题

1.结论 win11微软输入发最新版问题,使用以前版本即可 2.排查问题过程 最近一直没用shiftF6,当今天要使用时候,突然发现失效了,开始了以下排查过程 2.1 软件快捷键冲突 刚开始以为和其他软件或diea内部快捷键冲突,做了…

计算机组成原理 | 深入理解ELF格式和静态链接

深入解析C语言代码到机器码的过程 #mermaid-svg-UhCa4aLgwtwtM4hS {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-UhCa4aLgwtwtM4hS .error-icon{fill:#552222;}#mermaid-svg-UhCa4aLgwtwtM4hS .error-text{fill:#5…

whatsapp如何开发国外客户

WhatsApp可以说是目前2023年最火的社交营销方式之一,目前全球活跃人数大概在10亿,每日发送消息超过650亿条,语音和通话的时长超过20亿分钟,全球三分之一的人在用WhatsApp的,所有做外贸,WhatsApp是必不可少的…

ESXi 7.0 U3m Fujitsu (富士通) 定制版 OEM Custom Installer CD

VMware ESXi 7.0 Update 3m - 领先的裸机 Hypervisor (All OEM Customized Installer CDs) ESXi 7.0 U3m Standard (标准版) ESXi 7.0 U3m Dell (戴尔) 定制版 OEM Custom Installer CD ESXi 7.0 U3m HPE (慧与) 定制版 OEM Custom Installer CD ESXi 7.0 U3m Lenovo (联想) 定…

AIGC + RTE,一个实时互动的应用实践

一夜之间,区块链、元宇宙、Web3、VR等风口似乎都消散了,似乎只有 AI 才是C位。声网 RTC 云市场各类插件 AIGC,会迸发出什么样的火花呢? 最近,声网内部组织了一次黑客松,经过激烈的角逐,我们团…

【华为OD机试真题2023B卷 JAVAJS】完全二叉树非叶子部分后序遍历

华为OD2023(B卷)机试题库全覆盖,刷题指南点这里 完全二叉树非叶子部分后序遍历 知识点数组树递归 时间限制:1s 空间限制:256MB 限定语言:不限 题目描述: 给定一个以顺序储存结构存储整数值的完全二叉树序列(最多1000个整数),请找出此完全二叉树的所有非叶子节点部分,…

成功邀请媒体采访的关键步骤,媒介易助你成为媒体热门

在企业品牌推广和宣传中,与媒体建立合作关系,并邀请媒体进行采访是非常重要的环节。通过媒体的报道和宣传,企业可以扩大品牌的曝光度,提升品牌形象和知名度。然而,成功的媒体邀约并非易事,需要一定的策略和…

启动QT Linux应用程序后黑屏闪烁?

启动QT Linux应用程序后黑屏闪烁? 提问 问 4 年, 3 个月 前 修改于 3 个月前 点击833次 1 我将嵌入式Linux(imx6q)与eglfs一起使用。 帧缓冲在启动Qt应用程序时正在绘制黑屏。 简单的应用程序是黑色的1秒下。重度施用4~5秒。 这仅…

如何关闭A770显卡的灯效

A770的灯效看起来是不错,但对于我这样的实用主义者来说,他没啥用。所以想着怎么样能把他给关了。 查了一下,intel光放给出的办法如下: 如何使用英特尔 RGB 控制器配置英特尔 Arc™ A770 显卡有限版卡上 LED 的外观和行为。 英特…

java读取文件内容

直接上代码,两个类:一个工具类,一个测试类 工具类代码: package org.example.study.util;import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils;import java.io.*; import java.nio.charset.Charset…

FMC子卡设计资料原理图:FMC210-1路1Gsps AD、1路2.5Gsps DA的FMC子卡

FMC210-1路1Gsps AD、1路2.5Gsps DA的FMC子卡 一、板卡概述 FMC-1AD2DA是我司自主研发的一款1路1G AD采集、1路2.5G DA回放的FMC子卡。板卡采用标准FMC子卡架构,可方便的与其他FMC板卡实现高速互联,可广泛用于高频模拟信号采集、雷达系统测试等场…

【ChatGPT-工具篇 2】采用预置命令进行Prompt的输入

采用预置命令向ChatGPT输入命令 案例如下: {"ai_tutor":{"Author":"Andy.L","name":"JavaTutor","version":"1.0","features":{"personalization":{"depth"…

最值得推荐收藏的10个PPT文件误删恢复软件

PowerPoint 是一种非常流行的软件应用程序,专业人士和学生广泛使用它来制作演示文稿。它是 Microsoft Office 套件的一部分,Microsoft Office 套件是一组在世界各地的办公室、家庭和学校中使用的生产力工具。PowerPoint 演示文稿可以包含图像、视频、图表…