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.rhkb.cn/news/87538.html

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

相关文章

实例 -- Loadrunner实现Android / IOS 手机APP压力测试

随着手机APP用户量的增大&#xff0c;大的手机APP一般都需要进行压力测试&#xff0c;这几天用了Loadrunner 12进行了手机APP的压力测试&#xff0c;整理了下&#xff0c;大家可以参考参考怎样给Andorid / IOS手机APP进行压力测试&#xff0c;以下是操作实例。 先前我的一个帖…

数据通信——VRRP

引言 之前把实验做了&#xff0c;结果发现我好像没有写过VRRP的文章&#xff0c;连笔记都没记过。可能是因为对STP的记忆&#xff0c;导致现在都没忘太多。 一&#xff0c;什么是VRRP VRRP全名是虚拟路由冗余协议&#xff0c;虚拟路由&#xff0c;看名字就知道这是运行在三层接…

【Linux命令详解 | chmod命令】 chmod命令用于修改文件或目录的权限,保护文件安全性。

文章目录 简介一&#xff0c;参数列表二&#xff0c;使用介绍1. 修改用户权限2. 修改用户组权限3. 修改其他用户权限4. 同时修改多个权限5. 使用数字模式设置权限6. 递归修改目录权限 总结 简介 在Ubuntu系统中&#xff0c;chmod命令是一个强大的工具&#xff0c;用于修改文件…

Vim学习(三)—— Git Repo Gerrit

Git、Gerrit、Repo三者的概念及使用 三者各自作用&#xff1a; git&#xff1a;版本管理库&#xff0c;在git库中没有中心服务器的概念&#xff0c;真正的分布式。 repo&#xff1a;repo就是多个git库的管理工具。如果是多个git库同时管理&#xff0c;可以使用repo。当然使用…

JMeter 的并发设置教程

JMeter 是一个功能强大的性能测试工具&#xff0c;可以模拟许多用户同时访问应用程序的情况。在使用 JMeter 进行性能测试时&#xff0c;设置并发是非常重要的。本文将介绍如何在 JMeter 中设置并发和查看报告。 设置并发 并发是在线程组下的线程属性中设置的。 线程数&#…

基于SSM的小型仓库库存管理系统

C00142基于SSM的小型仓库库存管理系统 项目简介项目获取开发环境项目技术运行截图 项目简介 该系统有三类用户分别是管理员、员工、客户。 管理员&#xff08;登陆后台&#xff09;&#xff1a;可以对以上6个模块进行相应操作&#xff0c;还可以修改自己的密码。 员工&#xf…

软考高级架构师——5、系统规划分析与设计方法

系统计划主要用于描述从项目提出、选择到确立的过程&#xff0c;包括系统项目的提出与可行性 分析&#xff0c;系统方案的制订、评价和改进&#xff0c;新旧系统的分析和比较&#xff0c;以及现有软件、硬件和数据 资源的有效利用等问题。 1、项目的提出与选择 项目的立项目标…

Linux 终端命令之文件浏览(2) more

Linux 文件浏览命令 cat, more, less, head, tail&#xff0c;此五个文件浏览类的命令皆为外部命令。 hannHannYang:~$ which cat /usr/bin/cat hannHannYang:~$ which more /usr/bin/more hannHannYang:~$ which less /usr/bin/less hannHannYang:~$ which head /usr/bin/he…

vue复习。从安装到使用

vue官网&#xff1a;cn.vuejs.org vue安装 cnpm install -g vue/cli 查看是否安装成功 vue --version 创建一个项目 vue create vue-demo(项目名称) 这个取消掉。空格可选中或者取消。 运行项目&#xff1a; cd 进入到项目下 npm run serve 运行成功后&#xff0c;访问这…

数据安全加固:深入解析滴滴ES安全认证技术方案

前文分别介绍了滴滴自研的ES强一致性多活是如何实现的、以及如何提升ES的性能潜力。由于ES具有强大的搜索和分析功能&#xff0c;同时也因其开源和易于使用而成为黑客攻击的目标。近些年&#xff0c;业界ES数据泄露事件频发, 以下是一些比较严重的数据泄露案件&#xff1a; 202…

《机器学习系统:设计与实现》读书笔记一

最近几年一直在做算法工程的工作&#xff0c;对机器学习系统有所涉猎&#xff0c;也很感兴趣。近期发现一本开源书籍《机器学习系统&#xff1a;设计与实现》。去图书馆找了它的纸质版&#xff0c;发现内容不尽相同。在这里结合两者做一个读书笔记。本文是第一篇&#xff0c;主…

【RocketMQ入门-安装部署与Java API测试】

【RocketMQ入门-安装部署与Java API测试】 一、环境说明二、安装部署三、Java API 编写Producer和Consumer进行测试四、小结 一、环境说明 虚拟机VWMare&#xff1a;安装centos7.6操作系统源码包&#xff1a;rocketmq-all-5.1.3-source-release.zip单master部署&#xff0c;在…

冶金作业VR虚拟仿真厂家

对于高风险行业来说&#xff0c;开展安全教育培训是企业的重点工作&#xff0c;传统培训逐渐跟不上时代变化和工人需求&#xff0c;冶金安全VR模拟仿真培训系统作为一种新型的教育和培训工具&#xff0c;借助VR虚拟现实技术为冶金行业的工人提供一个安全、高效的培训环境。 冶金…

后端开发9.商品类型模块

概述 简介 商品类型我设计的复杂了点,设计了多级类型 效果图 数据库设计 创建表 DROP TABLE IF EXISTS &

c语言每日一练(6)

前言&#xff1a;每日一练系列&#xff0c;每一期都包含5道选择题&#xff0c;2道编程题&#xff0c;博主会尽可能详细地进行讲解&#xff0c;令初学者也能听的清晰。每日一练系列会持续更新&#xff0c;暑假时三天之内必有一更&#xff0c;到了开学之后&#xff0c;将看学业情…

ubuntu supervisor 部署 python 项目

ubuntu supervisor 查看系统是否可用 cuda 初环境与设备安装 supervisor 环境创建 Supervisor 配置文件启动 Supervisor 服务管理项目 本篇文章将介绍 ubuntu supervisor 部署 python 项目 Supervisor 是一个用于管理和监控进程的系统工具。它的主要功能是确保系统中的进程持续…

Kuebernetes资源控制管理

第四阶段 时 间&#xff1a;2023年8月11日 参加人&#xff1a;全班人员 内 容&#xff1a; Kuebernetes资源控制管理 目录 Kubectl命令工具 一、kubectl 命令行的语法 二、kubectl命令列表 三、使用 Kubectl 工具容器资源 &#xff08;一&#xff09;创建Pod &…

腾讯云CVM服务器2核2g1m带宽支持多少人访问?

腾讯云2核2g1m的服务器支持多少人同时访问&#xff1f;2核2g1m云服务器短板是在1M公网带宽上&#xff0c;腾讯云服务器网以网站应用为例&#xff0c;当大规模用户同时访问网站时&#xff0c;很大概率会卡在公网带宽上&#xff0c;所以压根就谈不上2核2G的CPU内存计算性能是否够…

MATLAB算法实战应用案例精讲-【图像处理】图像分类模型Swin TrasnformerViT

目录 Swin Trasnformer 1. 模型介绍 2. 模型结构 3. 模型实现 4. 模型特点 5. 模型效果 ViT( Vision Transformer) 模型介绍 模型结构与实现 1. 图像分块嵌入 2. 多头注意力 3. 多层感知机&#xff08;MLP&#xff09; 4. DropPath 5. 基础模块 6. 定义ViT网络 …

分布式 - 消息队列Kafka:Kafka消费者分区再均衡(Rebalance)

文章目录 01. Kafka 消费者分区再均衡是什么&#xff1f;02. Kafka 消费者分区再均衡的触发条件&#xff1f;03. Kafka 消费者分区再均衡的过程&#xff1f;04. Kafka 如何判定消费者已经死亡&#xff1f;05. Kafka 如何避免消费者的分区再均衡?06. Kafka 消费者分区再均衡有什…