2.代码文件和测试

发布日期:2020-12-26 09:09:54 来源:网络转载

创建好“infrared.c”和“infrared.h”文件。


1.infrared.c的代码

#include <reg52.h>
#include <infrared.h>
  
unsigned char irflag = 0; //红外接收标志,收到一帧正确数据后置1
unsigned char ircode[4];  //红外代码接收缓冲区
  
/* 初始化红外接收功能 */
void InitInfrared()
{
    IR_INPUT = 1;  //确保红外接收引脚被释放
    TMOD &= 0x0F;  //清零T1的控制位
    TMOD |= 0x10;  //配置T1为模式1
    TR1 = 0;       //停止T1计数
    ET1 = 0;       //禁止T1中断
    IT1 = 1;       //设置INT1为负边沿触发
    EX1 = 1;       //使能INT1中断
}
 
/* 获取当前高电平的持续时间 */
unsigned int GetHighTime()
{
    TH1 = 0;                //清零T1计数初值
    TL1 = 0;
    TR1 = 1;                //启动T1计数
    while (IR_INPUT)        //红外输入引脚为1时循环检测等待,变为0时则结束本循环
    {
        if (TH1 >= 0x40)
        {                   //当T1计数值大于0x4000,即高电平持续时间超过约18ms时,
            break;          //强制退出循环,是为了避免信号异常时,程序假死在这里。
        }
    }
    TR1 = 0;                //停止T1计数
   
    return (TH1*256 + TL1); //T1计数值合成为16bit整型数,并返回该数
}
 
/* 获取当前低电平的持续时间 */
unsigned int GetLowTime()
{
    TH1 = 0;                //清零T1计数初值
    TL1 = 0;
    TR1 = 1;                //启动T1计数
    while (!IR_INPUT)       //红外输入引脚为0时循环检测等待,变为1时则结束本循环
    {
        if (TH1 >= 0x40)
        {                   //当T1计数值大于0x4000,即低电平持续时间超过约18ms时,
            break;          //强制退出循环,是为了避免信号异常时,程序假死在这里。
        }
    }
    TR1 = 0;                //停止T1计数
   
    return (TH1*256 + TL1); //T1计数值合成为16bit整型数,并返回该数
}
 
/* INT1中断服务函数,执行红外接收及解码 */
void EXINT1_ISR() interrupt 2
{
    unsigned char i,j;
    unsigned char byt;
    unsigned int time;
     
    //接收并判定引导码的9ms低电平
    time = GetLowTime();
    if ((time<7833) || (time>8755))  //时间判定范围为8.5~9.5ms,
    {                                //超过此范围则说明为误码,直接退出
        IE1 = 0;                     //退出前清零INT1中断标志
        return;
    }
    //接收并判定引导码的4.5ms高电平
    time = GetHighTime();
    if ((time<3686) || (time>4608))  //时间判定范围为4.0~5.0ms,
    {                                //超过此范围则说明为误码,直接退出
        IE1 = 0;
        return;
    }
 
    //接收并判定后续的4字节数据
    for (i=0; i<4; i++)     //循环接收4个字节
    {
        for (j=0; j<8; j++) //循环接收判定每字节的8个bit
        {
            //接收判定每bit的560us低电平
            time = GetLowTime();
            if ((time<313) || (time>718))        //时间判定范围为340~780us,
            {                                    //超过此范围则说明为误码,直接退出
                IE1 = 0;
                return;
            }
            //接收每bit高电平时间,判定该bit的值
            time = GetHighTime();
            if ((time>313) && (time<718))        //时间判定范围为340~780us,
            {                                    //在此范围内说明该bit值为0
                byt >>= 1;                       //因低位在先,所以数据右移,高位为0
            }
            else if ((time>1345) && (time<1751)) //时间判定范围为1460~1900us,
            {                                    //在此范围内说明该bit值为1
                byt >>= 1;   //因低位在先,所以数据右移,
                byt |= 0x80; //高位置1
            }
            else             //不在上述范围内则说明为误码,直接退出
            {
                IE1 = 0;
                return;
            }
        }
        ircode[i] = byt;     //接收完一个字节后保存到缓冲区
    }
    irflag = 1;              //接收完毕后设置标志
    IE1 = 0;                 //退出前清零INT1中断标志
}


2.infrared.h的代码

因为主函数中只需要使用“InitInfrared();”函数来初始化,而“unsigned int GetHighTime()”和“unsigned int GetLowTime()”都是只在“void EXINT1_ISR() interrupt 2”中使用,所以头文件不用声明这三部分的函数。

#ifndef __INFRARED_H__
#define __INFRARED_H__
  
sbit IR_INPUT = P3^3;           //红外接收引脚
extern unsigned char irflag;    //红外接收标志,收到一帧正确数据后置1
extern unsigned char ircode[4]; //红外代码接收缓冲区
  
void InitInfrared();            //初始化红外接收功能
  
#endif


13.03.png


3.main.c测试代码

我们在宋老师的例程lesson16_1中通过按红外遥控器上的按键得知,第一行的三个按键会使ircode[2]分别变为0x45、0x46、0x47显示在数码管上,那么我们只需要判断ircode[2]的数据就可以知道按下的是哪个按键然后去执行相关任务就可以了。

我们用小灯测试红外遥控器的按键是否有效,有效则会切换小灯的亮灭。

#include <reg52.h>
#include <function.h>//详见第六章第8讲
#include <infrared.h>
 
void main()
{
    LED_Init();//初始化LED硬件模块
    EA = 1; 
    InitInfrared();
  
    while (1)
    {
        if (irflag)  
        {
            irflag = 0;   
            //以下是遥控器第一行按键
            if(ircode[2]==0x45)LED9=!LED9;
            if(ircode[2]==0x46)LED8=!LED8;
            if(ircode[2]==0x47)LED7=!LED7;
      
            //以下是遥控器第二行按键
            if(ircode[2]==0x44)LED4=!LED4;
            if(ircode[2]==0x40)LED3=!LED3;
            if(ircode[2]==0x43)LED2=!LED2;    
        }  
    }
}
关键词 :
网站违法和不良信息举报邮箱:23139485@qq.com
CopyRight@2020-2030 www.haoapp8.cn All Rights Reserved.C语言学习网版权所有 粤ICP备15061369号
免责声明:本站内容来源于用户自行提供或网络收集,其真实性、准确性和合法性,www.haoapp8.cn不提供任何保证,亦不承担任何法律责任.而产生的法律关系及法律纠纷,由您自行协商解决。