首页 测试文本

清翔零基础教你学51单片机_个人学习笔记(15)_红外通讯(理论+实践)

说明

本人使用的是清翔的51单片机开发板,如果型号相同最方便,但是如果型号不同也可以参考,因为芯片都是一样的,只是外设不同而已,使用时只需要对照自己的开发板原理图稍微修改下引脚即可。

|

本次笔记对应视频教程的第42,43集 红外通讯(理论+实践)

如果笔记之中有任何错误,请在评论区指出,谢谢

一、红外遥控

1.1 概述

红外遥控(Infrared Remote Control)是一种常见的无线遥控技术,通过使用红外线信号来传输命令和控制信息。它广泛应用于消费电子产品(如电视、音响、空调等)以及家庭自动化设备中。

红外遥控的优点包括:

  1. 便携性:红外遥控设备通常是小巧轻便的,方便携带和使用。
  2. 简单易用:红外遥控通常具有直观的按钮布局和标记,用户可以轻松理解和操作。
  3. 廉价:红外遥控设备相对较为廉价,适用于广泛的消费电子产品。
  4. 可编程性:某些高级的红外遥控设备具有可编程功能,允许用户自定义按键和操作。

然而,红外遥控也存在一些缺点:

  1. 有限的范围:红外线信号的传输受到距离和障碍物的限制,通常在可见范围内有效,无法实现远程控制。
  2. 定向性要求:红外遥控需要面向接收设备发送信号,如果角度或定位不正确,可能导致信号无法传达给设备。
  3. 干扰问题:其他红外设备或者强光源可能会干扰或阻碍红外遥控信号的传输,导致操作失败。
  4. 信号通信安全性较低:红外遥控信号通常是未加密的,因此存在一定的安全隐患,容易受到信号的截获和干扰。

尽管红外遥控存在一些限制和缺点,但它仍然是一种简单实用的遥控技术,广泛应用于各种家庭娱乐和自动化设备中。随着技术的进步,其他无线遥控技术(例如无线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(理论+实践)

|

如果笔记之中有任何错误,请在评论区指出,谢谢

posted @ 2025-11-08 15:25  BO_S  阅读(28)  评论(0)    收藏  举报
页脚 测试文本