红外遥控实验

本文详细介绍了红外遥控的工作原理,包括发射装置的构成、红外编码方式(如NECProtocol的PWM和PPM码)、载波频率的选择,以及接收设备的结构和解码过程,特别强调了使用外部中断进行数据解析的方法。
摘要由CSDN通过智能技术生成

红外遥控介绍

红外线简介

红外线遥控就是利用波长为 0.76~1.5μ m 之间的近红外线来传送控制信号的。

红外遥控的原理

红外遥控是一种无线、 非接触控制技术, 具有抗干扰能力强, 信息传输可靠,功耗低, 成本低, 易实现等显著优点, 被诸多电子设备特别是家用电器广泛采用,并越来越多的应用到计算机系统中。

红外发射装置

红外发射装置, 也就是通常我们说的红外遥控器是由键盘电路、 红外编码电路、 电源电路和红外发射电路组成。 红外发射电路的主要元件为红外发光二极管。它实际上是一只特殊的发光二极管; 由于其内部材料不同于普通发光二极管, 因而在其两端施加一定电压时, 它便发出的是红外线而不是可见光。 目前大量的使用的红外发光二极管发出的红外线波长为 940nm 左右, 外形与普通发光二极管相同。

 通常红外遥控为了提高抗干扰性能和降低电源消耗, 红外遥控器常用载波的方式传送二进制编码, 常用的载波频率为 38kHz, 这是由发射端所使用的 455kHz晶振来决定的。 在发射端要对晶振进行整数分频, 分频系数一般取 12, 所以455kHz÷12≈37.9kHz≈38kHz。 也有一些遥控系统采用 36kHz、 40 kHz、 56 kHz等, 一般由发射端晶振的振荡频率来决定。 所以, 通常的红外遥控器是将遥控信号(二进制脉冲码) 调制在 38KHz 的载波上, 经缓冲放大后送至红外发光二极管, 转化为红外信号发射出去的。二进制脉冲码的形式有多种, 其中最为常用的是 NEC Protocol 的 PWM 码(脉冲宽度调制)和 Philips RC-5 Protocol 的 PPM 码(脉冲位置调制码, 脉冲串之间的时间间隔来实现信号调制)。 如果要开发红外接收设备, 一定要知道红外遥控器的编码方式和载波频率, 我们才可以选取一体化红外接收头和制定解码方案。 我们配套的红外遥控器使用的是 NEC 协议, 其特征如下:

  1. 8 位地址和 8 位指令长度;
  2. 地址和命令 2 次传输(确保可靠性)
  3. PWM 脉冲位置调制, 以发射红外载波的占空比代表“0” 和“1” ;
  4. 载波频率为 38Khz;
  5. 位时间为 1.125ms 或 2.25ms;

NEC 码的位定义: 一个脉冲对应 560us 的连续载波, 一个逻辑 1 传输需要2.25ms(560us 脉冲+1680us 低电平), 一个逻辑 0 的传输需要 1.125ms(560us脉冲+560us 低电平) 。 而红外接收头在收到脉冲的时候为低电平, 在没有脉冲的时候为高电平, 这样, 我们在接收头端收到的信号为: 逻辑 1 应该是 560us 低+1680us 高, 逻辑 0 应该是 560us 低+560us 高。 所以可以通过计算高电平时间判断接收到的数据是 0 还是 1。 NEC 码位定义时序图如下图所示:

 NEC 遥控指令的数据格式为: 引导码、 地址码、 地址反码、 控制码、 控制反码引导码由一个 9ms 的低电平和一个 4.5ms 的高电平组成, 地址码、 地址反码、 控制码、 控制反码均是 8 位数据格式。 按照低位在前, 高位在后的顺序发送。 采用反码是为了增加传输的可靠性(可用于校验) 。 数据格式如下:

 NEC 码还规定了连发码(由 9ms 低电平+2.5m 高电平+0.56ms 低电平+97.94ms 高电平组成), 如果在一帧数据发送完毕之后, 红外遥控器按键仍然没有放开, 则发射连发码 可以通过统计连发码的次数来标记按键按下的长短或次数。

红外接收设备

红外接收设备是由红外接收电路、 红外解码、 电源和应用电路组成。 红外遥控接收器的主要作用是将遥控发射器发来的红外光信好转换成电信号, 再放大、限幅、 检波、 整形, 形成遥控指令脉冲, 输出至遥控微处理器。 近几年不论是业余制作还是正式产品, 大多都采用成品红外接收头。 成品红外接收头的封装大致有两种: 一种采用铁皮屏蔽; 一种是塑料封装。 均有三只引脚, 即电源正( VDD)、电源负(GND) 和数据输出(VOUT) 。 其外观实物图如下图所示:

 正对接收头的凸起处看, 从左至右, 管脚依次是 1: VOUT, 2: GND, 3: VDD。

 由于红外接收头在没有脉冲的时候为高电平, 当收到脉冲的时候为低电平,所以可以通过外部中断的下降沿触发中断, 在中断内通过计算高电平时间来判断接收到的数据是 0 还是 1

硬件

 从上图中可知, 红外接收头的输出管脚接至单片机 P3.2 管脚上, 为了保证红外接收头输出管脚默认为高电平, 需外接一个 10K 上拉电阻, 可在上图并没有看到有上拉电阻, 在前面介绍最小系统时已知道, 单片机 IO 口都增加了 10K 上拉电阻。

软件

红外初始化函数

/********************************************************************
***********
* 函 数 名 : ired_init
* 函数功能 : 红外端口初始化函数, 外部中断 0 配置
* 输 入 : 无PRECHIN
* 输 出 : 无
*********************************************************************
**********/
void ired_init(void)
{
IT0=1; //下降沿触发
EX0=1; //打开中断 0 允许
EA=1; //打开总中断
IRED=1; //初始化端口
}

因为我们使用外部中断 0 来解码红外遥控数据, 所以需初始化配置外部中断0。

红外解码函数

初始化外部中断后, 中断就已经开启了, 当 P32 引脚来一个下降沿, 就会触发一次中断, 在中断内我们可以计算高电平时间, 通过高电平时间判断是否进入引导码及数据 0 和 1。 具体代码如下:

void ired() interrupt 0 //外部中断 0 服务函数
{
    u8 ired_high_time=0;
    u16 time_cnt=0;
    u8 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;
        }
    }
}

进入中断函数, 表示以来下降沿, 然后判断管脚是否为低电平, 如果为低电平则首先判断引导信号, 根据前面 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 中, 外部可直接使用这四个字节。

主函数

/********************************************************************
******************
实验名称: 红外遥控实验
接线说明:
实验现象: 下载程序后, 数码管上显示数码管上显示红外解码遥控器键值
注意事项: 红外接收头凸起处要与 PCB 板接口凸起丝印处对应
*********************************************************************
******************/
#include "public.h"
#include "smg.h"
#include "ired.h"
/********************************************************************
***********
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*********************************************************************
**********
void main()
{
    u8 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);
    }
}

注意: 红外接收头的凸起位置需对到 PCB 板丝印凸出位置, 否则功能无法正常实现。 出厂时的遥控器电池盖内都有一张绝缘片, 使用时必须将此绝缘片拿掉。 还有键值码不是大家所想的按键上的数字字符码, 这个要区分开。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值