PIC16F616或者PIC16F722 怎么写红外接收译码程序
单片机io接收数字信号。不同脉宽的波形。用程序进行软解。再根据实际的含义,对应一下。主要是看波形。分析波形。难度不大。
#define TIME 125 //定时器定时时间
#define IR_sample TIME //定义采样时间
#define IR_SYNC_MAX (15000/IR_sample)//120 //前导码最大时间(9ms+4.5ms=13.5ms)
#define IR_SYNC_MIN (9700 /IR_sample)//77 //前导码最小时间(连发9ms+2.25ms=11.25ms)
#define IR_SYNC_DIVIDE (12375/IR_sample)//99 //区分连发前导码((11.25+(13.5-11.25))/2=12.375ms)
#define IR_DATA_MAX (3000 /IR_sample)//24 //数据最大时间3ms
#define IR_DATA_MIN (600 /IR_sample)//4 //数据最小时间0.6ms
#define IR_DATA_DIVIDE (1687 /IR_sample)//13 //区分0和1数据,(1.12+(2.25-1.12)/2)=1.685ms
#define IR_BIT_NUMBER 32 //32位数据
#define User_code 0x0cf3
uchar IR_SampleCnt,IR_BitCnt,IR_UserH,IR_UserL,IR_data,IR_DataShit,IR_code,D_F0;
bit bdata Ir_Pin_temp,IR_Sync,IrUserErr,IR_OK;
void IR_RX_HT6121()
{
uchar SampleTimer; //信号周期
IR_SampleCnt++; //定时器对红外口检测次数
D_F0 = Ir_Pin_temp; //保存前一次扫描到的端口电平状态
Ir_Pin_temp = p_reg;//Ir_pin; //读取当前端口电平状态
if(D_F0 && !Ir_Pin_temp) //判断是否触发
{
SampleTimer = IR_SampleCnt; //记录脉冲周期
IR_SampleCnt = 0; //清零计数值
if(SampleTimer > IR_SYNC_MAX) IR_Sync=0;//超出最大前导信号,退出
else if(SampleTimer >= IR_SYNC_MIN)
{
if(SampleTimer >= IR_SYNC_DIVIDE) //区分连发信号与同步信号
{
IR_Sync = 1; //接收到有效同步信号
IR_BitCnt = IR_BIT_NUMBER; //赋值32位有用信号
}
}
else if(IR_Sync) //已接收到同步信号
{
if((SampleTimer < IR_DATA_MIN)|(SampleTimer > IR_DATA_MAX)) IR_Sync=0;//数据周期过长,退出
else
{
IR_DataShit >>= 1; //键反码右移一位(发送端是低位在前,高位在后格式)
if(SampleTimer >= IR_DATA_DIVIDE) IR_DataShit |= 0x80; //区分0和1
if(--IR_BitCnt==0) //所有数据接收完毕
{
IR_Sync = 0; //清除同步信号标志
if(~IR_DataShit == IR_data) //判断数据正反码
{
if((IR_UserH == (User_code / 256))&&(IR_UserL == (User_code%256)))
{
IrUserErr = 0; //判断用户码正确
}
else
IrUserErr = 1; //判断用户码错误
//IR_code = IR_data;
d_rem_key = IR_data; //取键码值
//Set_buz(5);//测试
IR_OK = 1; //键码值有效标志
}
}
else if((IR_BitCnt & 7)==0) //数据倒序
{
IR_UserL = IR_UserH; // 保存用户码高字节
IR_UserH = IR_data; // 保存用户码低字节
IR_data = IR_DataShit; // 保存当前红外字节
}
}
}
}
}
用定时器定时125us,然后在中断子程序中调用这个函数就好
两种方法:一是使用红外编解码芯片,二是使用软件编写编解码程序,主要用定时器来实现