51单片机学习--红外遥控(外部中断)

在这里插入图片描述


需要利用下面这个红外接收头,OUT口会发出红外信号对应的高低电平,由于发送的速度很快,所以需要把OUT引脚接在外部中断引脚上,当OUT一旦产生下降沿,马上进中断,这样响应会更及时。
在这里插入图片描述


在这里插入图片描述
在这里插入图片描述
外部中断引脚位于P3_2和P3_3,我的开发板把OUT接在了P3_2,利用的是下降沿触发。
外部中断比定时器中断和串口中断要简洁一些,这里使用外部中断0(Int0),当IT0=1就是下降沿触发,IT0=0就是低电平触发。
IE0为中断标志位,EX0为此中断的使能,EA为所有中断的使能,PX0设置优先级。
外部中断1(Int1)也是同理。
图中红框框出的才是控制外部中断的。

在这里插入图片描述
首先来配置外部中断:

void Int0_Init(void)
{//配置外部中断IT0 = 1;      //选择下降沿触发IE0 = 0;      //中断标志位EX0 = 1;      //外部中断0使能EA = 1;       //中断使能PX0 = 1;      //优先级
}/* @brief 外部中断函数
void Int0_Routine(void) interrupt 0
{}
*/


在这里插入图片描述


高低电平的组合、持续时长构成了NEC编码:下面的波形就是OUT口会输出的波形。
Data中的反码可以进行数据验证。
在遥控器上按下一个按键之后,先发送一个start波形,然后发送Data,如果按住按键一直不放手,每过110ms就会发送一次repeat,相当于连续按键功能。

在这里插入图片描述
这里遥控器按键的命令码如下:
在这里插入图片描述


接下来编写红外解码的程序,主要的思路是:
建立一个IR.c红外解码模块,这个模块中利用Int0.c和Timer0.c来进行解码。
具体的解码方式:
首先定义一个变量表示当前的状态,用0来表示空闲状态,当收到下降沿时,转为1状态(1状态定义为:分辨是start还是repeat)并将定时器打开,当1状态又收到一个下降沿时,读出定时器的时长判断是start还是repeat。
如果判断为start,转为2状态(2状态定义为:开始解码32bit的Data)2状态会执行32次,数据读完之后回到0状态
如果判断为repeat,则把重发标志位的变量置1并转回0状态



所以首先要对之前写的Timer0模块进行一些改写。这次的目的不是让定时器计数进中断了,而是让它单纯的计时,下面就是改写后的Timer0.c,可以设定计时器的初始值,返回计时器的实时值,以及控制计时器的开关,计时器的返回值每多1就代表多走过了1us

#include <REGX52.H>void Timer0_Init(void)		//1毫秒@11.0592MHz
{TMOD &= 0xF0;		//设置定时器模式TMOD |= 0x01;		//设置定时器模式TL0 = 0x66;		//设置定时初值TH0 = 0xFC;		//设置定时初值TF0 = 0;		//清除TF0标志TR0 = 0;		//定时器0不计时
}//把16位值放入计数器
void Timer0_SetCounter(unsigned int Value)
{TH0 = Value/256;TL0 = Value%256;
}//返回计数器的值
unsigned int Timer0_GetCounter(void)
{return (TH0<<8) | TL0;
}//选择计时器是否启动,Flag为1则启动
void Timer0_Run(unsigned char Flag)
{TR0 = Flag;
}


接下来就可以编写IR.c了,要注意IR.c中包含了Int0的外部中断函数:
参考之前说的具体的解码方式:
首先定义一个变量表示当前的状态,用0来表示空闲状态,当收到下降沿时,转为1状态(1状态定义为:分辨是start还是repeat)并将定时器打开,当1状态又收到一个下降沿时,读出定时器的时长判断是start还是repeat。
如果判断为start,转为2状态(2状态定义为:开始解码32bit的Data)2状态会执行32次,数据读完之后回到0状态
如果判断为repeat,则把重发标志位的变量置1并转回0状态

#include <REGX52.H>
#include "Timer0.h"
#include "Int0.h"unsigned int IR_Time;  //计时时长
unsigned char IR_State; //状态unsigned char IR_Data[4]; //分别表示Data的四个字节
unsigned char IR_pData;   //代表每个个字节的对应位 0~31unsigned char IR_DataFlag; //数据接收完成标志位
unsigned char IR_RepeatFlag; //重发标志位
unsigned char IR_Address;
unsigned char IR_Command;void IR_Init(void)
{Timer0_Init();Int0_Init();
}unsigned char IR_GetDataFlag(void)
{if(IR_DataFlag){IR_DataFlag = 0;return 1;}else return 0;
}unsigned char IR_GetRepeatFlag(void)
{if(IR_RepeatFlag){IR_RepeatFlag = 0;return 1;}else return 0;
}unsigned char IR_GetAddress(void)
{return IR_Address;
}unsigned char IR_GetCommand(void)
{return IR_Command;
}void Int0_Routine(void) interrupt 0
{if(IR_State == 0) //空闲{Timer0_SetCounter(0);Timer0_Run(1);IR_State = 1;}else if(IR_State == 1) //判断是start/repeat{IR_Time = Timer0_GetCounter();Timer0_SetCounter(0);if(IR_Time > 13500-500 && IR_Time < 13500+500){//startIR_State = 2;}else if(IR_Time > 11250-500 && IR_Time < 11250+500){//repeatIR_RepeatFlag = 1;Timer0_Run(0);IR_State = 0;}}else if(IR_State == 2) //读取Data{IR_Time = Timer0_GetCounter();Timer0_SetCounter(0);if(IR_Time > 1120-500 && IR_Time < 1120+500){//对应位为0IR_Data[(IR_pData/8)] &= ~(0x01<<(IR_pData%8));IR_pData ++;}else if(IR_Time > 2250-500 && IR_Time < 2250+500){//对应位为1IR_Data[IR_pData/8] |= (0x01<<(IR_pData%8));IR_pData ++;}else{//接收到错误信号则重新接收IR_pData = 0;IR_State = 1;}if(IR_pData >= 32){//Data已收完IR_pData = 0;//验证数据的正确性if((IR_Data[0] == ~ IR_Data[1]) && (IR_Data[2] == ~ IR_Data[3])){IR_Address = IR_Data[0];IR_Command = IR_Data[2];IR_DataFlag = 1;}Timer0_Run(0);IR_State = 0;}}}

Command和Address要想在main中调用,就得封装成相应的Get函数,然后对应红外遥控器按键的键码可以用宏定义,IR.h如下:

#ifndef __IR_H__
#define __IR_H__#define IR_POWER        0x45
#define IR_MODE         0x46
#define IR_MUTE         0x47
#define IR_START_STOP   0x44
#define IR_PREVIOUS     0x40
#define IR_NEXT         0x43
#define IR_EQ           0x07
#define IR_VOL_MINUS    0x15
#define IR_VOL_ADD      0x09
#define IR_0            0x16
#define IR_RPT          0x19
#define IR_USD          0x0D
#define IR_1            0x0C
#define IR_2            0x18
#define IR_3            0x5E
#define IR_4            0x08
#define IR_5            0x1C
#define IR_6            0x5A
#define IR_7            0x42
#define IR_8            0x52
#define IR_9            0x4Avoid IR_Init(void);
unsigned char IR_GetDataFlag(void);
unsigned char IR_GetRepeatFlag(void);
unsigned char IR_GetAddress(void);
unsigned char IR_GetCommand(void);#endif


最后在main.c中调用这些函数即可,

#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "IR.h"unsigned char Num;
unsigned char Address, Command;void main()
{LCD_Init();LCD_ShowString(1, 1, "ADDR  CMD  NUM");LCD_ShowString(2, 1, "00  00  000");IR_Init();while(1){if(IR_GetDataFlag() || IR_GetRepeatFlag()){Address = IR_GetAddress();Command = IR_GetCommand();LCD_ShowHexNum(2, 1, Address, 2);LCD_ShowHexNum(2, 7, Command, 2);if(Command == IR_VOL_MINUS) Num --;if(Command == IR_VOL_ADD) Num ++;LCD_ShowNum(2, 12, Num, 3);}}
}

在这里插入图片描述

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

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

相关文章

全球八分之一的河流受到缺氧影响

一项全球研究发现&#xff0c;世界各地河流中的溶解氧含量低得危险。缺氧的真实发生率可能更高。 小型、低梯度的城市河流&#xff0c;例如图中北卡罗来纳州的那条河流&#xff0c;是最容易缺氧的河流之一。图片来源&#xff1a;乔安娜布拉扎克 2023 年 3 月&#xff0c;《卫报…

大脑营行|“福安市华龙教育基金”支持家乡教育事业发展

8月8日&#xff0c;福安市松罗中学举行“福安市华龙教育基金”中考奖学金颁发仪式。福安市松罗乡党委书记钟文、乡长郑仁寿、福安市人民政府教育督导室副科级督导员&#xff08;片区领导&#xff09;陈秦、校长张明亮、各村支部书记、家长代表、受奖学生&#xff0c;校领导班子…

@RequestHeader使用

RequestHeader 请求头参数的设置 GetMapping("paramTest/requestHeader")public String requestHeaderTest(RequestHeader("name") String name){return name;} 在Postman的Headers中添加请求头参数&#xff0c;不过貌似不能加中文

百川智能发布首个530亿参数闭源大模型,今年追上GPT-3.5

4月官宣创业&#xff0c;6月15日发布第一款7B开源模型&#xff0c;7月11日发布第二款13B、130亿参数开源模型。 平均保持2个月一个版本发布速度&#xff0c;8月8日&#xff0c;百川智能发布了创业以来的首个530亿参数闭源大模型——Baichuan-53B&#xff08;以下简称“53B”&a…

LeetCode 热题 100 JavaScript -- 74. 搜索二维矩阵

给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a; 每行中的整数从左到右按非递减顺序排列。 每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target &#xff0c;如果 target 在矩阵中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 …

无涯教程-Perl - glob函数

描述 此函数返回与EXPR匹配的文件的列表,这些文件将由标准Bourne shell进行扩展。如果EXPR未指定路径,请使用当前目录。如果省略EXPR,则使用$_的值。 从Perl 5.6开始,扩展是在内部完成的,而不是使用外部脚本。扩展遵循csh(以及任何派生形式,包括tcsh和bash)的扩展方式,其翻译…

【STM32】小电流FOC驱控一体板(开源)

FOC驱控一体板http://链接: https://pan.baidu.com/s/12HoV9yDlMC5QVGNCJ5tK0w 提取码: 1111 主控芯片stm32f103c8t6 驱动芯片drv8313 三相电流采样 根据B站一个UP主的改的&#xff08;【【自制】年轻人的第一块FOC驱动器】&#xff09;&#xff0c;大多数元器件是0805&…

Java SpringBoot 加载 yml 配置文件中字典项

实际项目中&#xff0c;如果将该类信息放配置文件中的话&#xff0c;一般会结合Nocas一起使用 将字典数据&#xff0c;配置在 yml 文件中&#xff0c;通过加载yml将数据加载到 Map中 Spring Boot 中 yml 配置、引用其它 yml 中的配置。# 在配置文件目录&#xff08;如&#xff…

ArcGIS Pro实践技术应用——暨基础入门、制图、空间分析、影像分析、三维建模、空间统计分析与建模、python融合、案例应用全流程科研能力提升

查看原文>>>ArcGIS Pro实践技术应用——暨基础入门、制图、空间分析、影像分析、三维建模、空间统计分析与建模、python融合能力 本文将利用ArcGIS Pro 将您的 GIS 工作组织到工程中&#xff0c;您可以使用 ArcGIS Pro 映射 2D 和 3D 数据。借助 ArcGIS Pro&#xff…

阿里云FRP内网穿透挂载多台服务器

1. FRP介绍 FRP (Fast Reverse Proxy) 是比较流行的一款。FRP 是一个免费开源的用于内网穿透的反向代理应用&#xff0c;它支持 TCP、UDP 协议&#xff0c; 也为 http 和 https 协议提供了额外的支持。你可以粗略理解它是一个中转站&#xff0c; 帮你实现 公网 ←→ FRP(服务器…

全国各地区数字经济工具变量-文本词频统计(2002-2023年)

数据简介&#xff1a;本数据使用全国各省工作报告&#xff0c;对其中数字经济相关的词汇进行词频统计&#xff0c;从而构建数字经济相关的工具变量。凭借数字经济政策供给与数字经济发展水平的相关系数的显著性作为二者匹配程度的划分依据&#xff0c;一定程度上规避了数字经济…

构建之法 - 软件工程实践教学:每天都向前推进一点点

作者&#xff1a;福州⼤学 汪璟玢⽼师 汪老师&#xff1a;每次都向前推进一点点&#xff0c;哪怕只有一点点&#xff0c;也好过什么都不做。 ​邹老师&#xff1a;对&#xff0c;几个学期下来&#xff0c;就已经超过那些“空想”的团队很远了。坚持下去&#xff01; 汪老师&…

【变形金刚02】注意机制以及BERT 和 GPT

一、说明 我已经解释了什么是注意力机制&#xff0c;以及与转换器相关的一些重要关键字和块&#xff0c;例如自我注意、查询、键和值以及多头注意力。在这一部分中&#xff0c;我将解释这些注意力块如何帮助创建转换器网络&#xff0c;注意、自我注意、多头注意、蒙面多头注意力…

ceph相关概念和部署

Ceph 可用于向云提供 Ceph 对象存储 平台和 Ceph 可用于提供 Ceph 块设备服务 到云平台。Ceph 可用于部署 Ceph 文件 系统。所有 Ceph 存储集群部署都从设置 每个 Ceph 节点&#xff0c;然后设置网络。 Ceph 存储集群需要满足以下条件&#xff1a;至少一个 Ceph 监控器&#x…

Three.js 设置模型材质纹理贴图和修改材质颜色,材质透明度,材质网格

相关API的使用&#xff1a; 1 traverse &#xff08;模型循环遍历方法&#xff09; 2. THREE.TextureLoader&#xff08;用于加载和处理图片纹理&#xff09; 3. THREE.MeshLambertMaterial&#xff08;用于创建材质&#xff09; 4. getObjectByProperty&#xff08;通过材…

深度学习常用的python库学习笔记

文章目录 数据分析四剑客Numpyndarray数组和标量之间的运算基本的索引和切片数学和统计方法线性代数 PandasMatplotlibPIL 数据分析四剑客 Numpy Numpy中文网 ndarray 数组和标量之间的运算 基本的索引和切片 数学和统计方法 线性代数 Pandas Pandas中文网 Matplotlib Mat…

分布式协调组件Zookeeper

Zookeeper介绍 什么是Zookeeper ZooKeeper 是⼀种分布式协调组件&#xff0c;用于管理大型主机。在分布式环境中协调和管理服务是一个复杂的过程。ZooKeeper 通过其简单的架构和 API 解决了这个问题。ZooKeeper 允许开发人员专注于核心应用程序逻辑&#xff0c;而不必担心应用…

【解密算法:时间与空间的博弈】

本章重点 ​​什么是数据结构&#xff1f; 什么是算法&#xff1f; 算法效率 时间复杂度 空间复杂度 常见复杂度对比 复杂度oj练习 1. 什么是数据结构&#xff1f; 数据结构(Data Structure)是计算机存储、组织数据的方式&#xff0c;指相互之间存在一种或多种特定关系的…

uniapp项目如何运行在微信小程序模拟器上

在HbuilderX中的小程序写完后自己一定要保存&#xff0c;否则会出不来效果 那么怎么让uniapp项目运行在微信小程序开发工具中呢 1 在hbuilderx中点击运行到小程序模拟器 2 然后在项目目录中会生成一个文件夹 在微信小程序开发软件中的工具>安全设置>打开端口 或者在微…

分类预测 | Matlab实现基于TSOA-CNN-GRU-Attention的数据分类预测

分类预测 | Matlab实现基于TSOA-CNN-GRU-Attention的数据分类预测 目录 分类预测 | Matlab实现基于TSOA-CNN-GRU-Attention的数据分类预测效果一览基本介绍研究内容程序设计参考资料 效果一览 基本介绍 Matlab实现分类预测 | Matlab实现基于TSOA-CNN-GRU-Attention的数据分类预…