5.2 对射式红外传感器旋转编码器计次

news2024/11/29 10:47:24
  1. 对射式红外传感器

1.1 接线图

VCC GND分别接电源的正负极

DO数字输出端,随意选择一个GPIO口

1.2 硬件原理

当挡光片或者编码盘在对射式红外传感器中间经过时,DO就会输出电平变化信号,电平跳变信号触发STM32 PB14号口中断,在中断函数中执行变量++程序,并在主循环里调用OLED中显示变量。

1.3 设计思路

  • 本次设计采用模块化编程,分为CountSensor.c、CountSensor.h、main.c三部分。

  • 先进行初始化

EXTI(中断)配置

1. 第⼀步,配置RCC,把所涉及到的外设时钟都打开 (GPIOB,AFIO(NVIC,EXTI无需打开)) 2. 第⼆步,配置GPIO,选择端口为输⼊模式 3. 第三步,配置AFIO,选择使⽤的⼀路GPIO,连接到EXTI 4. 第四步,配置EXTI,选择边沿触发⽅式,选择触发响应⽅式 5. 第五步,配置NVIC,给中断选择⼀个合适的优先级

最后通过NVIC,外部中断信号进入CPU,CPU收到中断信号,跳转到中断函数里执行中断程序。

EXTI和NVIC时钟默认是打开的,NVIC是内核的外设,内核的外设都不需要开启时钟,RCC 管的都是内核外的外设

1.4 知识储备 AFIO

  • 复位AFIO外设

void GPIO_AFIODeInit(void);
  • 锁定GPIO配置函数

锁定引脚的配置,防⽌意外更改

void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin);
  • 配置AFIO的事件输出功能函数

void GPIO_EventOutputConfig(uint8_t GPIO_PortSource,uint8_tGPIO_PinSource);
void GPIO_EventOutputCmd(FunctionalState NewState);
  • 引脚重映射函数

void GPIO_PinRemapConfig(uint32_t GPIO_Remap,FunctionalStateNewState);
  • 配置AFIO的数据选择器

通过配置AFIO数据选择器,选择中断引脚。

void GPIO_EXTILineConfig(uint8_t GPIO_PortSource,uint8_tGPIO_PinSource);
  • 恢复上电默认的状态函数

void EXTI_DeInit(void);

1.5 知识储备EXTI

  • 清除EXTI配置,恢复上电默认的状态函数

void EXTI_DeInit(void);
  • 根据结构体配置EXTI外设函数

void EXTI_Init(EXTI_InitTypedef* EXTI_InitStruct);
  • 给传⼊的结构体参数赋⼀个默认值函数

void EXTI_StructInit(EXTI_InitTypedef* EXTI_InitStruct);
  • 软件触发外部中断函数

调用函数,参数给⼀个指定的中断线,就能软件触发⼀次这个外部中断

void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);

下面四个是库函数的模板函数

在主程序里查看和清除标志位用下面两个函数

  • 获取指定的标志位是否被置1

FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);
  • 对置1的标志位进⾏清除函数

void EXTI_ClearFlag(uint32_t EXTI_Line);

在中断函数里查看和清除标志位用下面两个

  • 在中断函数中获取标志位函数

ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
  • 清除中断挂起标志位函数

void EXTI_ClearITPendingBit(uint32_t EXTI_Line);

1.6 知识储备NVIC

  • 中断分组函数

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
  • 根据结构体⾥⾯的参数初始化NVIC函数

void NVIC_Init(NVIC_InitTypedef* NVIC_InitStruct);
  • 设置中断向量表函数

NVIC_SetVectorTable函数的功能是设置向量表的位置和偏移。其中输⼊参数中,对于32位 的OFFSET向量表基地址的偏移量对于FLASH,参数值必须⾼于0x08000100,对于RAM必 须⾼于0X100

void NVIC_SetVectorTable(uint8_t NVIC_VectTab,uint32_t Offset);
  • 系统低功耗配置函数

void NVIC_SystemLPConfig(uint8_t LowPowerMode,FunctionalStateNewState)

注意:中断函数要简短快速,不要在中断中执⾏Delay

1.7 程序设计

CountSensor.c

#include "stm32f10x.h"                  // Device header

uint16_t CountSensor_Count;

void CountSensor_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//开启GPIOB的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//开启AFIO的时钟
    //配置GPIO
    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);//配置AFIO外部中断引脚选择
    //配置EXTI
    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结构体
    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)//中断标志位判断是否为1
    {
        /*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/
        if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0)
        {
            CountSensor_Count ++;//统计中断返回次数
        }
        EXTI_ClearITPendingBit(EXTI_Line14);//清除中断标志位
    }
}

CountSensor.h

#ifndef __COUNT_SENSOR_H
#define __COUNT_SENSOR_H

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

#endif

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:");/1行1列显示Count:
    
    while (1)
    {
        OLED_ShowNum(1, 7, CountSensor_Get(), 5);//一行七列显示返回次数,长度为5
    }
}

2. 旋转编码器计次

2.1 接线图

VCC GND接正负极,A,B相输出引脚,接到STM32的PB0和PB1引脚。

2.2 设计思路

本设计采用模块化编程,分为Encoder.c、Encoder.h、mian.c三部分。

2.3 程序设计

Encoder.c

#include "stm32f10x.h"                  // Device header

int16_t Encoder_Count;

void CountSensor_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//开启GPIOB的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//开启AFIO的时钟
    //配置GPIO
    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);//配置AFIO外部中断引脚选择
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1); 
    //配置EXTI
    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结构体
    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;//定义临时变量,方便Count清零
    Temp = Encoder_Count;
    Encoder_Count = 0;
    return Temp;
}

void EXTI0_IRQHandler(void)
{
    if (EXTI_GetITStatus(EXTI_Line14) == SET)//中断标志位判断是否为1
    {
        /*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/
        if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0)//读取输入高低电平
        {
            if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
            {
                Encoder_Count --;
            }
        }
        EXTI_ClearITPendingBit(EXTI_Line14);//清除中断标志位
    }
}

void EXTI1_IRQHandler(void)//线路1中断函数
{
    if (EXTI_GetITStatus(EXTI_Line14) == SET)//中断标志位判断是否为1
    {
        /*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/
        if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)//读取输⼊⾼低电平
        {
            if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0)
            {
                Encoder_Count ++;
            }
        }
        EXTI_ClearITPendingBit(EXTI_Line14);//清除中断标志位
    }
}

Encoder.h

#ifndef __ENCODER_H
#define __ENCODER_H

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

#endif

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

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

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

相关文章

01: 新手学SpringCloud前需知道的5点

目录 第一点: 什么是微服务架构 第二点:为什么需要学习Spring Cloud 第三点: Spring Cloud 是什么 第四点: SpringCloud的优缺点 1、SpringCloud优点 2、SpringCloud缺点 第五点: SpringCloud由什么组成 1&…

数据结构——链表OJ题目讲解(2)

作者:几冬雪来 时间:2023年3月10日 内容:数据结构链表OJ题目讲解 来源:牛客网和力扣 目录 前言: 刷题: 1.反转链表: 1.改变指向的解法: 2.取头结点插入到新链表: …

参考 | 辨别真假笔记本三星内存条 (ddr4)

参考 | 辨别真假笔记本三星内存条 (ddr4) 文章目录参考 | 辨别真假笔记本三星内存条 (ddr4)1. 三星内存条标签纸上编码的含义2. 三星内存颗粒上编码的含义3. 辨别内容参考1. 三星内存条标签纸上编码的含义 内存条贴张上面有两串值得注意的编码, 其中编码的具体意义参考三星官方…

docker-compress 配置

文章目录docker-compress下载安装常用命令Docker Compose配置常用字段docker compose案例yml 配置指令参考versionbuildcap_add,cap_dropcgroup_parentcommandcontainer_namedepends_ondeploydevicesdnsdns_searchentrypointenv_fileenvironmentexposeextra_hostshe…

【3.10】操作系统进程管理、KMP算法

多线程冲突了怎么办? 由于多线程执行操作共享变量可能会导致竞争状态,因此我们将此段代码称为临界区(*critical section*),它是访问共享资源的代码片段,一定不能给多线程同时执行。 我们希望这段代码是互斥…

cadence skill 记录FPM不能保存问题

;FPM skill by Richard L. version0.08 fpmontrealgmail.com;Tree:杂项(Chinese)/简单范例;Desc:范例如何建立一个简单的二极管封装;Vendor:Richard L.;Count:1;CVG64:示意图字段(测试中);Datasheet:pL12.7 ;引脚间距pA7.6 pB3.5 pH3.5 ;长宽高pPad2.0 pHole1.2 ;焊盘直径和孔径…

论文阅读《Block-NeRF: Scalable Large Scene Neural View Synthesis》

论文地址:https://arxiv.org/pdf/2202.05263.pdf 复现源码:https://github.com/dvlab-research/BlockNeRFPytorch 概述 Block-NeRF是一种能够表示大规模环境的神经辐射场(Neural Radiance Fields)的变体,将 NeRF 扩展到…

渗透测试——信息收集(详细)

信息收集:前言:信息收集是渗透测试除了授权之外的第一步,也是关键的一步,尽量多的收集目标的信息会给后续的渗透事半功倍。收集信息的思路有很多,例如:页面信息收集、域名信息收集、敏感信息收集、子域名收…

Redis学习【12】之Redis 缓存

文章目录前言一 Jedis 简介二 使用 Jedis2.1 测试代码2.2 使用 JedisPool2.3 使用 JedisPooled2.4 连接 Sentinel 高可用集群2.5 连接分布式系统2.6 操作事务三 Spring Boot整合Redis3.1 创建工程3.2 定义 pom 文件3.3 完整代码3.4 总结四 高并发问题4.1 缓存穿透4.2 缓存击穿4…

全方位解读智能中控屏发展趋势!亚马逊Alexa语音+Matter能力成必备

随着智能家居行业逐步从碎片化的智能单品阶段,迈向体验更完整的全屋互联阶段,智能中控屏作为智能家居最佳的入口之一,在年轻人青睐全屋智能装修的风潮下,市场潜力彻底被引爆。 一、为什么是智能中控屏? 在智能音箱增…

诗一样的代码命名规范

有文化:落霞与孤鹜齐飞,秋水共长天一色;没文化:太阳落山的时候,看见一只鸟在水上飞;日常编码中,代码的命名是个大的学问。能快速的看懂开源软件的代码结构和意图,也是一项必备的能力…

Docker入门建议收藏 第二部分

二、Docker 容器技术与虚拟机的区别 Docker 到底是个什么东西呢?我们在理解 Docker 之前,首先得先区分清楚两个概念,容器和虚拟机。 虚拟机 虚拟机(Virtual Machine)指通过软件模拟的具有完整硬件系统功能的、运行在…

单链表的头插,尾插,头删,尾删等操作

前言顺序表要求是具有连续的物理空间,并且数据的话是在这些空间当中是连续的存储。但这样会带来很多问题,比如说在头部或者说中间插入的话,效率不是很高;并且申请空间可能需要扩容,并且越往后一般来说都是异地扩容&…

优思学院|精益生产中的“单件流”真的能够做到吗?

精益生产中提到的“一个流”(One Piece Flow)是一种生产方式,它的核心理念是通过合理配置作业场地、人员和设备,使产品从投入到成品产出的整个制造加工过程中始终处于不停滞、不堆积、不超越,按节拍一个一个地流动。 …

Idea+maven+spring-cloud项目搭建系列--11 整合dubbo

前言: 微服务之间通信框架dubbo,使用netty (NIO 模型)完成RPC 接口调用; 1 dubbo 介绍: Apache Dubbo 是一款 RPC 服务开发框架,用于解决微服务架构下的服务治理与通信问题,官方提…

渲染十万条数据就把你难住了?不存在的!

虚拟列表的使用场景如果我想要在网页中放大量的列表项,纯渲染的话,对于浏览器性能将会是个极大的挑战,会造成滚动卡顿,整体体验非常不好,主要有以下问题:页面等待时间极长,用户体验差CPU计算能力…

pyqt5(二) 标签(QLabel)组件的属性说明及示例

使用语法 widget QLable() widget.function(parameter) widget:实例化QLablefunction:QLable里的函数parameter:函数需要用到的参数 参数说明: 参数说明参数解释 setText() 配置文本内容 setPixmap() 添加图片 setFixedSize(…

蓝桥杯--等差素数列

等差素数列 技巧 这里的等差数列–首项需要枚举列出 公差也需要枚举列出 在公差为1开始&#xff0c;对n-1也进行枚举 //重要代码段 判断一个数是否为素数 int check(int n) { for(int i2;i<n;i){if(n%i0){return 0 } return 1; } }这道题不是很简单 本题为填空题&#xff0…

Webstorm使用、nginx启动、FinalShell使用

文章目录 主题设置FinalShellFinalShell nginx 启动历史命令Nginx页面发布配置Webstorm的一些常用快捷键代码生成字体大小修改Webstorm - gitCode 代码拉取webstorm 汉化webstorm导致CPU占用率高方法一 【忽略node_modules】方法二 【设置 - 代码编辑 - 快速预览文档 - 关闭】主…

Linux 练习七 (IPC 共享内存)

文章目录System V 共享内存机制&#xff1a;shmget shmat shmdt shmctl案例一&#xff1a;有亲缘关系的进程通信案例二&#xff1a;非亲缘关系的进程通信内存写端write1.c内存读端read1.c案例三&#xff1a;不同程序之间的进程通信程序一&#xff0c;写者shmwr.c程序二&#xf…