与单片机
红外接收模块检测到38K红外信号后,会在OUT引脚输出低电平,没有的话OUT脚就会输出高电平。
接收到红外信号,通过使用外部中断,进入中断,测量信号时间,判断信号值,具体要看使用的是什么协议。
NEC协议
NEC数据格式:
引导码、用户码、用户码(或者用户码反码)、按键键码和键码反码,最后一个停止位。每个一个字节。
引导码:9ms的载波+4.5ms的空闲。
比特值“0”:560us的载波+560us的空闲。
比特值“1”:560us的载波+1.68ms的空闲。
信号调制
目的:方便进行信号的传输
基带信号:从信号源发出没有经过调制的原始信号,特点是频率较低,信号频率从0开始,频谱较宽。
调制:就是用待传送信号去控制某个高频信号的幅度、相位、频率等参量变化的过程,即用一个信号去装载另一个信号。
红外接收流程图
程序代码
#include <reg52.h>
sbit IR_INPUT=P3^3;
bit irflag=0;
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)
{
if(TH1>=0X40) //持续时间超过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)
{
if(TH1>=0X40) //持续时间超过18ms时,强制退出循环
break;
}
TR1=0; //停止T1计数
return (TH1*256+TL1);//T1计数值合成为16bit整型数,并返回该数
}
void EXINT1_ISR() interrupt 2//中断函数,并执行红外解码
{
unsigned char i,j;
unsigned char byt;
unsigned int time;
//判定引导码
time=GetLowTime();
if((time<7833)||(time>8755))//判定时间为8.5ms~9.5ms
{
IE1=0;
return;//退出中断
}
time=GetHighTime();
if((time<3686)||(time>4608))//判定时间为4.0ms~5.0ms
{
IE1=0;
return;
}
//开始接收
for(i=0;i<4;i++) //循环接收四个字节
{
for(j=0;j<8;j++)//接收8个位
{
time=GetLowTime();
if((time<313)||(time>718))//340~780us 超过此范围为误码,退出操作
{
IE1=0;
return;
}
time=GetHighTime();
if((time>313)||(time<718))//340~780us bit为0
{
byt>>=1;//低位在先,数据右移
}
else if((time>1345)||(time<1751))//1460~1900us bit为1
{
byt>>=1;
byt|=0x80;
}
else
{
IE1=0;
return;
}
}
ircode[i]=byt;//接收完一个字节后保存到缓冲区
}
irflag=1;//接收完毕后设置标志
IE1=0; //退出前清零INT1中断标志
}