说明
本人使用的是清翔的51单片机开发板,如果型号相同最方便,但是如果型号不同也可以参考,因为芯片都是一样的,只是外设不同而已,使用时只需要对照自己的开发板原理图稍微修改下引脚即可。
|
本次笔记对应视频教程的第42,43集 红外通讯(理论+实践)
如果笔记之中有任何错误,请在评论区指出,谢谢
目录
一、红外遥控
1.1 概述
红外遥控(Infrared Remote Control)是一种常见的无线遥控技术,通过使用红外线信号来传输命令和控制信息。它广泛应用于消费电子产品(如电视、音响、空调等)以及家庭自动化设备中。
红外遥控的优点包括:
- 便携性:红外遥控设备通常是小巧轻便的,方便携带和使用。
- 简单易用:红外遥控通常具有直观的按钮布局和标记,用户可以轻松理解和操作。
- 廉价:红外遥控设备相对较为廉价,适用于广泛的消费电子产品。
- 可编程性:某些高级的红外遥控设备具有可编程功能,允许用户自定义按键和操作。
然而,红外遥控也存在一些缺点:
- 有限的范围:红外线信号的传输受到距离和障碍物的限制,通常在可见范围内有效,无法实现远程控制。
- 定向性要求:红外遥控需要面向接收设备发送信号,如果角度或定位不正确,可能导致信号无法传达给设备。
- 干扰问题:其他红外设备或者强光源可能会干扰或阻碍红外遥控信号的传输,导致操作失败。
- 信号通信安全性较低:红外遥控信号通常是未加密的,因此存在一定的安全隐患,容易受到信号的截获和干扰。
尽管红外遥控存在一些限制和缺点,但它仍然是一种简单实用的遥控技术,广泛应用于各种家庭娱乐和自动化设备中。随着技术的进步,其他无线遥控技术(例如无线RF遥控、蓝牙遥控等)的出现也提供了更多选择来解决红外遥控的局限性。
1.2 红外遥控电路的组成
发射部分和接收部分。
发射部分:键盘电路,红外编码芯片,红外发射电路
接收部分:红外接收电路、红外解码芯片、电源、应用电路
1.3 原理图
数据手册给出的红外接收电路推荐接法
1.4 NEC协议数据格式
接收端和发射端是相反的
1.5 位定义
1.6 编程思路
注意接收方得和发送方的波形是反的。像这样比如接收方的起始码个发送方是反的
因此可以根据两次下降沿的产生来表明完成一个信号,使用外部中断0来让定时器计数,从而判断信号时长,从而知道收到的是0还是1,或者是引导码都能分析出来。
二、编程
2.1 创建工程
复制上一份工程文件夹,修改名称为“15.红外通信”,进入项目文件夹,打开工程文件,删除main.c函数的内容。
2.2 main.c
void main()
{
uchar i,j,temp,value;
TMOD = 0x22; //设置定时器0和定时器1都是8位自动重装
TL0 = TH0 = 0x00;
EA = 1; //打开总中断
ET0 = 1; //打开定时器0中断
//TR0 = 1; //启动定时器0
IT0 = 1; //外部中断0为下降沿触发
EX0 = 1; //开启外部中断0
TH1 = 0xfd; //配置串口波特率9600
TL1 = 0xfd;
TR1 = 1;
SM1 = 1;
while(1)
{
if (IROK) //接收完成,开始解码
{
for (i = 0; i < 4; i++) //4个数据,循环4次
{
for (j = 8*i; j < 8 + 8*i; j++) //8位组成1个字符
{
temp = IRdata[j + 1]; //舍弃起始码,从后一个开始取值
value >>= 1; //右移1位
if (temp >= 6) //时长在2.1ms~2.4ms,为1
value |= 0x80; //为1就运行这行,为0什么也不做
}
SBUF = value;
value = 0x00;
while(!TI);
TI = 0;
}
IROK = 0;
}
}
}
//外部中断0
void int0() interrupt 0
{
static uchar i; //标志存了几次数据
static bit startflag; //起始信号有个下降沿,再次出现下降沿才表示起始信号结束,数据开始,因此要过滤掉第一个下降沿
TR0 = 1; //开始计时
if(startflag)
{
//IRtime = IRtime*2.7776 + TL0*0.01085; //两次中断时间间隔,10倍ms
//TL0 = 0; //计算完当前持续时间,立马清零计数器,计算下一次的时间
if (IRtime >=20)
i = 0;
IRdata[i] = IRtime; //把时间存入
IRtime = 0; //清零
i++;
if (i == 33) //说明已经存入33个数据
{
TR0 = 0; //关闭T0
TL0 = 0; //清空T0
startflag = 0;
i = 0;
IROK = 1; //接收完成标志
}
}
else
{
startflag = 1;
}
}
//定时器0中断
void timer0() interrupt 1
{
IRtime++; //计算溢出多少次,一次277.76us
}
在外部中断0这里,这句代码是必要的
if (IRtime >=20)
i = 0;
这可以确保起始码被放在第一位然后其余的数据依次往后存放,我只看了视频讲解红外原理部分,以及清翔给出的代码,没有看代码讲解,我先自己写的代码,下载后有时解析不正常,被困扰好久,加上这句就没问题了。
2.3 main.h
写函数和变量声明
/************************************************ 红外相关 *******************/
sbit IR = P3^2;
uchar IRtime;//计数一个红外脉冲有多少个定时器0溢出
uchar IRdata[33];
bit IROK;//表明一次接收完成
2.4 现象
前两位0和1是反的,后两位的0和1是反的,一切正常。
本次笔记对应视频教程的第42,43集 红外通讯(理论+实践),到此结束。红外这部分代码跟前几节相比是比较少的,看起来理论部分不难,就一个起始码,加上4个字节,实际上从0开始写还是比较麻烦的,自己写的时候需遇到现象不正常,却不知道问题出在哪,调试的时间非常长,这也是本次笔记发布较慢的原因。希望后来者能少走些弯路。
|
下次笔记将对应视频教程的第44,45集 实时时钟DS1302(理论+实践)
|
如果笔记之中有任何错误,请在评论区指出,谢谢