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的问题),我的程序有什么问题?我每次按下一个键有时显示,有时不显示,然后再多次按另外一个键,显示的数字竟然不停变化,不是固定的数。怎么搞的?那位大侠给看看,多谢了,急急急!
#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