当前位置: 首页 > news >正文

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

相关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_Hextern void CountSensor_Init(void);
extern uint16_t CountSensor_Get(void);#endif
CountSensor.c
#include "stm32f10x.h"                  // Device headeruint16_t CountSensor_Count;void CountSensor_Init(void)
{//第一步:配置RCC时钟,把涉及外设的时钟都打开//第二步:配置GPIO,设置为输入模式//第三步:配置AFIO,选择某个GPIO口连接到EXTI(边缘检测及控制器)//第四步:配置EXTI(不需要开启时钟,原因不详),选择边沿触发方式和触发响应方式//边沿触发方式:上升沿、下降沿、或者双边沿,触发响应方式:中断响应和事件响应//第五步:配置NVIC(内核的外设,不需要开启时钟),给中断选择一个合适的优先级//对射式红外传感器:B14RCC_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-3NVIC_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 到后面的 EXTIGPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);    // PB0 -> EXTI0GPIO_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~3NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;         // 响应优先级: 0~3NVIC_Init(&NVIC_InitStruct);// 配置 NVIC, 给 中断选择一个合适的优先级, 最终外部中断信号就能进入 CPU 了NVIC_InitStruct.NVIC_IRQChannel = EXTI1_IRQn;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;            // 通道使能NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;  // 抢占优先级: 0~3NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;         // 响应优先级: 0~3NVIC_Init(&NVIC_InitStruct);
}void EXTI0_IRQHandler(void)    
{ITStatus res = EXTI_GetITStatus(EXTI_Line0);           // 判断是否是 EXIT0if(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);           // 判断是否是 EXIT1if(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_Hextern 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);}
}

相关文章:

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

相关API介绍 EXT配置API(stm32f10x exti.h) NVIC 配置API (misc.h) 初始化的中断的步骤 第一步:配置RCC时钟,把涉及外设的时钟都打开 第二步:配置GPIO,设置为输入模式 第三步:配置AFIO&#xff0…...

one-hot是什么

“one-hot” 是一种编码技术,通常用于机器学习和数据处理中,用来表示分类数据或离散变量。它的目的是将一个分类变量转换成二进制向量,其中只有一个元素是 “hot”(值为1),而其他元素都是 “cold”&#xf…...

基于阿基米德优化优化的BP神经网络(分类应用) - 附代码

基于阿基米德优化优化的BP神经网络(分类应用) - 附代码 文章目录 基于阿基米德优化优化的BP神经网络(分类应用) - 附代码1.鸢尾花iris数据介绍2.数据集整理3.阿基米德优化优化BP神经网络3.1 BP神经网络参数设置3.2 阿基米德优化算…...

ubuntu20.04配置阿里的kubernetes源

不仅适用于kubernetes软件源的配置,同样适用于其他软件源 1、安装依赖 sudo apt-get update # apt-transport-https may be a dummy package; if so, you can skip that package sudo apt-get install -y apt-transport-https ca-certificates curl 2、配置gpg签名…...

【运维】一些团队开发相关的软件安装。

gitlab 安装步骤 (1) 下载镜像,并且上传到服务器 https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-16.2.8-ce.0.el7.x86_64.rpm (2)rpm -i gitlab-ce-16.2.8-ce.0.el7.x86_64.rpm (3)安装成功后…...

互联网Java工程师面试题·Java 并发编程篇·第七弹

目录 16、CAS 的问题 17、什么是 Future? 18、什么是 AQS 19、AQS 支持两种同步方式: 20、ReadWriteLock 是什么 21、FutureTask 是什么 22、synchronized 和 ReentrantLock 的区别 23、什么是乐观锁和悲观锁 24、线程 B 怎么知道线程 A 修改了…...

SQL语句常见分类

SQL是Structured Query Language(结构化查询语言)的简写。 Structured发音 SQL 是关系型数据库管理系统的标准语言,如Oracle、MySQL、Microsoft SQL Server。 DDL DDL是Data Definition Language(数据定义语言)的简…...

SpringBoot通过配置切换注册中心(多注册中心nacos和eureka)

场景: 因项目需要,一个springcloud微服务工程需要同时部署到A,B两个项目使用,但A项目使用Eureka注册中心,B项目使用Nacos注册中心,现在需要通过部署时修改配置来实现多注册中心的切换。 解决思路: 如果同时…...

自动驾驶学习笔记(三)——场景设计

#Apollo开发者# 学习课程的传送门如下,当您也准备学习自动驾驶时,可以和我一同前往: 《自动驾驶新人之旅》免费课程—> 传送门 《2023星火培训【感知专项营】》免费课程—>传送门 文章目录 前言 场景设计平台 场景地图 场景基本…...

第 115 场 LeetCode 双周赛题解

A 上一个遍历的整数 模拟 class Solution { public:vector<int> lastVisitedIntegers(vector<string> &words) {vector<int> res;vector<int> li;for (int i 0, n words.size(); i < n;) {if (words[i] ! "prev")li.push_back(stoi…...

【IDE插件教学】华为云应用中间件系列—Redis实现(电商游戏应用)排行榜示例

云服务、API、SDK&#xff0c;调试&#xff0c;查看&#xff0c;我都行 阅读短文您可以学习到&#xff1a;应用中间件系列之Redis实现&#xff08;电商游戏应用&#xff09;排行榜示例 1 什么是DEVKIT 华为云开发者插件&#xff08;Huawei Cloud Toolkit&#xff09;&a…...

Linux:mongodb数据库源码包安装(4.4.25版本)

环境 系统&#xff1a;centos7 本机ip&#xff1a;192.168.254.1 准备的mongodb包 版本 &#xff1a; 4.4.25 全名称&#xff1a;mongodb-linux-x86_64-rhel70-4.4.25.tgz 下载源码包 Download MongoDB Community Server | MongoDBhttps://www.mongodb.com/try/downloa…...

pdf怎么合并在一起?

pdf怎么合并在一起&#xff1f;对于pdf合并这个问题&#xff0c;有的小伙伴想很简单&#xff0c;只需要将文件直接复制再其中的一个后面不就完事了吗。其实不然&#xff0c;因为我们如果要是需要将很多文件进行合并的话&#xff0c;就会产生很多问题的。总之&#xff0c;在现在…...

杀死僵尸进程ZooKeeperMain

关闭Hadoop后jps发现还有个进程ZooKeeperMain没有关闭&#xff0c;使用kill -9 <>也没有用&#xff0c;这种就是僵尸进程&#xff0c;需要用父进程ID来杀死 解决方法 话不多说&#xff0c;直接上解决方案&#xff0c; 1. 第一步 清楚需要关闭的进程ID&#xff0c;我…...

JavaScript class和function的区别

待整理&#xff1a; 一 二 Class 组件和 Function 组件是 React 中创建组件的两种主要方式。他们在语法和功能上有一些不同。以下分点是 Class 组件和 Function 组件在不同方面的对比&#xff1a; 1. 语法结构 Class 组件&#xff1a; import React, { Component } from …...

MySQL8.0修改mysql允许远程连接

1、连接服务器: mysql -u root -p2、看当前所有数据库&#xff1a;show databases; 3、进入mysql数据库&#xff1a;use mysql; 4、查看mysql数据库中所有的表&#xff1a;show tables; 5、查看user表中的数据&#xff1a;select Host, User,Password from user; 6、修改us…...

【算法训练-排序算法 二】【手撕排序】快速排序、堆排序、归并排序

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是【手撕排序系列】&#xff0c;使用【数组】这个基本的数据结构来实现&#xff0c;这个高频题的站点是&#xff1a;CodeTop&#xff0c;筛选条件为&…...

C# RestoreFormer 图像修复

效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Windows.Forms;namespace 图像修复 {pu…...

yolov5+车辆重识别【附代码】

本篇文章主要是实现的yolov5和reid结合的车辆重识别项目。是在我之前实现的yolov5_reid行人重识别的代码上修改实现的baseline模型。 目录 相关参考资料 数据集说明 环境说明 项目使用说明 vehicle reid训练 yolov5车辆重识别 从视频中获取想要检测的车(待检测车辆) 车…...

C语言练习百题之#ifdef和#ifndef的应用

#if, #ifdef, 和 #ifndef 是C语言预处理指令&#xff0c;它们可以用于条件编译&#xff0c;帮助控制程序的编译过程。以下是各种应用场景以及一些注意事项&#xff1a; 1. 使用 #ifdef 和 #ifndef 检查宏是否定义&#xff1a; 应用场景: 检查宏是否已经在代码中定义&#xf…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...