第22章 红外遥控实验
第二十二章 红外遥控实验
1. 导入
在前面章节, 我们介绍的通信, 如 SPI、 IIC 等通信均为有线, 这一章我们来介绍一种无线通信技术--红外遥控通信。 我们开发板标配了一个一体化红外接收头和红外遥控器, 我们来学习如何使用 51 单片机解码红外遥控器的信号。 本章使用 51 单片机的外部中断功能来解码红外遥控器的编码信号。
2. 红外遥控介绍
红外遥控是一种无线、 非接触控制技术, 具有抗干扰能力强, 信息传输可靠,功耗低, 成本低, 易实现等显著优点, 被诸多电子设备特别是家用电器广泛采用,并越来越多的应用到计算机系统中。
红外发射装置, 也就是通常我们说的红外遥控器是由键盘电路、 红外编码电路、 电源电路和红外发射电路组成。 红外发射电路的主要元件为红外发光二极管。它实际上是一只特殊的发光二极管; 由于其内部材料不同于普通发光二极管, 因而在其两端施加一定电压时, 它便发出的是红外线而不是可见光。 目前大量的使用的红外发光二极管发出的红外线波长为 940nm 左右, 外形与普通发光二极管相同。 红外发光二极管有透明的, 还有不透明的, 在我们的红外遥控器上可以看到这个红外发光二极管。 红外遥控器和红外发光二极管如下图所示:
通常红外遥控为了提高抗干扰性能和降低电源消耗, 红外遥控器常用载波的方式传送二进制编码, 常用的载波频率为 38kHz, 这是由发射端所使用的 455kHz晶振来决定的。 在发射端要对晶振进行整数分频, 分频系数一般取 12, 所以455kHz÷ 12≈37.9kHz≈38kHz。 也有一些遥控系统采用 36kHz、 40 kHz、 56 kHz等, 一般由发射端晶振的振荡频率来决定。 所以, 通常的红外遥控器是将遥控信号( 二进制脉冲码) 调制在 38KHz 的载波上, 经缓冲放大后送至红外发光二极管, 转化为红外信号发射出去的。
二进制脉冲码的形式有多种, 其中最为常用的是 NEC Protocol 的 PWM 码(脉冲宽度调制)和 Philips RC-5 Protocol 的 PPM 码(脉冲位置调制码, 脉冲串之间的时间间隔来实现信号调制)。 如果要开发红外接收设备, 一定要知道红外遥控器的编码方式和载波频率, 我们才可以选取一体化红外接收头和制定解码方案。
更多内容可以参考:红外遥控_百度百科 (baidu.com)
单片机学习(十)红外遥控与外部中断 - CodeReaper - 博客园 (cnblogs.com)
3. 硬件设计
本实验使用到硬件资源如下:
-
动态数码管
-
红外接收头和遥控器
动态数码管电路在前面章节都介绍过, 这里就不再重复。 红外遥控器和接收头是一体的, 内部结构不用去管它。 下面来看下开发板上红外接收模块电路, 如下图所示:
从上图中可以看出, 该电路是独立的, 红外接收头的输出管脚接至 J11 端子上, 为了保证红外接收头输出管脚默认为高电平, 需外接一个 10K 上拉电阻, 可在上图并没有看到有上拉电阻, 在前面介绍最小系统时已知道, 单片机 IO 口都增加了 10K 上拉电阻, 所以此处可省略。
4. 软件设计
本章所要实现的功能是: 数码管上显示红外解码遥控器键值。程序框架如下:
-
编写数码管显示功能
-
编写红外解码函数
-
编写主函数
数码管显示功能我们已经封装好了,下面开始写红外解码相关函数:
#ifndef _ired_H
#define _ired_H
#include "public.h"
//管脚定义
sbit IRED = P3^2;
//声明变量
extern unsigned char gired_data[4];
//函数声明
void ired_init(void);
#endif
#include "ired.h"
unsigned char gired_data[4]; // 存储4个字节接收码(地址码+地址反码+控制码+控制反码)
// 红外端口初始化函数,外部中断0配置
void ired_init(void)
{
IT0 = 1; // 下降沿触发
EX0 = 1; // 打开中断0允许
EA = 1; // 打开总中断
IRED = 1;// 初始化端口
}
void ired() interrupt 0 // 外部中断0服务函数
{
unsigned char ired_high_time = 0;
unsigned int time_cnt = 0;
unsigned char i = 0,j = 0;
if(IRED == 0)
{
time_cnt = 1000;
while((!IRED) && (time_cnt)) // 等待引导信号9ms低电平结束,若超过10ms强制退出
{
delay_10us(1); // 延时约10us
time_cnt--;
if(time_cnt == 0)
return;
}
if(IRED) // 引导信号9ms低电平已过,进入4.5ms高电平
{
time_cnt = 500;
while(IRED && time_cnt) // 等待引导信号4.5ms高电平结束,若超过5ms强制退出
{
delay_10us(1);
time_cnt--;
if(time_cnt == 0)
return;
}
for(i = 0; i < 4; i++)//循环4次,读取4个字节数据
{
for(j = 0; j < 8; j++)//循环8次读取每位数据即一个字节
{
time_cnt = 600;
while((IRED==0) && time_cnt) // 等待数据1或0前面的0.56ms结束,若超过6ms强制退出
{
delay_10us(1);
time_cnt--;
if(time_cnt == 0)
return;
}
time_cnt = 20;
while(IRED) // 等待数据1或0后面的高电平结束,若超过2ms强制退出
{
delay_10us(10); // 约0.1ms
ired_high_time++;
if(ired_high_time > 20)
return;
}
gired_data[i] >>= 1; // 先读取的为低位,然后是高位
if(ired_high_time >= 8) // 如果高电平时间大于0.8ms,数据则为1,否则为0
gired_data[i] |= 0x80;
ired_high_time=0; // 重新清零,等待下一次计算时间
}
}
}
if(gired_data[2] != ~gired_data[3]) // 校验控制码与反码,错误则返回
{
for(i = 0; i < 4; i++)
gired_data[i] = 0;
return;
}
}
}
因为我们使用外部中断 0 来解码红外遥控数据, 所以需初始化配置外部中断0。 初始化配置在外部中断实验章节已详细介绍, 此处不再重复。
初始化外部中断后, 中断就已经开启了, 当 P3.2 引脚来一个下降沿, 就会触发一次中断, 在中断内我们可以计算高电平时间, 通过高电平时间判断是否进入引导码及数据 0 和 1。
进入中断函数, 表示以来下降沿, 然后判断管脚是否为低电平, 如果为低电平则首先判断引导信号, 根据前面 NEC 协议可知, 引导信号有 9ms 的低电平和4.5ms 的高电平, 因此通过 time_cnt 赋值 1000, 然后在 while 循环内判断, time_cnt 每递减一次约 10us, 1000 次则为 10ms, 在解码时, 这个时间要适当放宽一点范围, 因为不同传感器性能会有差异, 所以此处以 10ms 的低电平为界限,如果超过 10ms 则强制退出, 防止系统死机。 判断完引导信号的低电平, 接着判断高电平, 实现方法一样。 当引导信号判断完成后进入地址码、 地址反码、 控制码及控制反码共 4 个字节的数据判断, 也就是数据 0 和 1 的判断, 实现方法也是和前面判断引导信号一样, 这里使用到了嵌套循环, 外层循环次数是 4, 表示读取 4 个字节, 内层循环次数是 8, 表示读取每个字节的 8 位。 注意, 红外遥控解码数据是从低位开始, 最后是高位。
最后将读取的 4 个字节数据存储在全局变量数组 gired_data 中, 外部可直接使用这四个字节。
#include "public.h"
#include "smg.h"
#include "ired.h"
void main()
{
unsigned char ired_buf[3];
ired_init();//红外初始化
while(1)
{
ired_buf[0]=gsmg_code[gired_data[2]/16]; // 将控制码高4位转换为数码管段码
ired_buf[1]=gsmg_code[gired_data[2]%16]; // 将控制码低4位转换为数码管段码
ired_buf[2]=0X76; // 显示H的段码
smg_display(ired_buf, 6);
}
}
主函数代码很简单, 首先调用使用的外设头文件, 然后初始化红外, 进入while 循环将红外解码数据转换为数码管段码数据, 然后在数码管上显示。
5. 小结
照例,我们来详细分析一下重要代码:
2024.7.22 第一次修订
2024.8.23 第二次修订,后期不再维护
本文作者:hazy1k
本文链接:https://www.cnblogs.com/hazy1k/p/18375249
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步