微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > NEC协议的红外线接收程序

NEC协议的红外线接收程序

时间:10-02 整理:3721RD 点击:
#include<reg51.h>
#include"LCD1602_Display.h"
#include"LCD1602.h"
#include"Interrupt_Configuration.h"
#include"Delay.h"
sbit IRIO=P3^2;
unsigned int Overflow_Times;
unsigned char IR_Codes[4];//放置红外线接收到的用户码,用户码反码,数据码,数据码反码
void main()
{         
     LCD1602_Configuration();
         Timer0_Configuration();//定时器1配置:没有打开EA,TR1
     INT0_Configuration();//两次中断配置第二次统一才开启中断总允许EA
         IRIO=1;         
         LCD1602_Display();
         while(1);//等待在中断中接收红外线信号
}
void IR_Service()interrupt 0
{
     unsigned char i,j;
            Delay1ms(5);//相当于按键消抖
         if(IRIO==0)                                                                                                                            
         {
            while(!IRIO);//等待起始的9ms低电平AGC过去
                 while(IRIO);//等待4.5ms的高电平过去
              for(i=0;i<4;i++)
                  {
                             for(j=0;j<8;j++)
                           {  
                              Overflow_Times=0;
                                    while(!IRIO);//等待每位起始的0.56ms低电平过去
                                    TR0=1;
                                    while(IRIO);
                                    TR0=0;
                                  if(Overflow_Times<=4)//逻辑0
                                  {
                                          IR_Codes[i]=(IR_Codes[i]>>1)|0x00;
                                  }
                                  else//逻辑1
                                  {
                                            IR_Codes[i]=(IR_Codes[i]>>1)|0x80;
                                  }                  
                                  TH0=0;
                                    TL0=0;
                           }
                  }
                  if((IR_Codes[0]==~IR_Codes[1])&&(IR_Codes[2]==~IR_Codes[3]))//检测数据正反
                  {
                            LCD1602_Display_Code();
                          IRIO=1;
                  }
                  else
                  {
                      IRIO=1;
                            return;
                  }
         }
}
void Timer0_Service()interrupt 1//用来计算高电平持续的时间
{
          Overflow_Times++;
}
我的基本思想是:12Mhz的晶振,利用定时器在工作方式2下每0.256ms溢出一次来计算每位0.56ms低电平后面的高电平持续时间已确定是逻辑0还是逻辑1,然后将接收到的地址码,地址码反码,命令码,命令码反码放在数组IR_Codes[4]中,接着进行取反比较看数据是否正确,如正确,就显示在1602上,否则就return,重新接收数据。现在先不考虑由于硬件故障导致的诸如while(IRIO);等循环无法跳出的问题(就是硬件现在没有问题,不考虑硬件出问题时跳不出while的问题),我的程序有什么问题?我每次按下一个键有时显示,有时不显示,然后再多次按另外一个键,显示的数字竟然不停变化,不是固定的数。怎么搞的?那位大侠给看看,多谢了,急急急!

对于有时显示,有时不显示。你可以,在外部中断服务程序中,加一个LED的指示灯用作程序运行状态指示灯,进行调试。看看是不是,按下按键就能进入中断。
按同一个按键,显示不同的的值,是解码不正确。可以参考一下 宋雪松老师的《手把手教你学51单片机-C语言版》中的程序

666666666666666666666666666666

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top