找回密码
 注册会员
更新自动建库工具PCB Footprint Expert 2024.04 Pro / Library Expert 破解版

红外遥控器解码程序较好的算法

[复制链接]
admin 发表于 2012-9-2 13:24:18 | 显示全部楼层 |阅读模式

本文包含原理图、PCB、源代码、封装库、中英文PDF等资源

您需要 登录 才可以下载或查看,没有账号?注册会员

×
在网上找了很多类似,测试好像不行,和工作频率有关,还有一些程序的算法非常差。
于是自己动手写了一个比较好的算法,可以应用在C51,STC等单片机上,只需要修改一下参数
if(tcpStart>9000)即可,9000是计数器的引导头9ms最小记数量, 将其修改小后可以适合多种频率下。另32位码的需要将 if(indataxp>33).,如下只是一个测试程序,程序主要在void int_0() 中断中处理,接收命令完成后,通过串口发给PC检看结果。
对于正在研究这块的人来说是一个非常好的参考。

#include<reg52.h>
#include "intrins.h"
#include "string.h"
#define INBUF_LEN 4 //数据长度
unsigned char inbuf1[INBUF_LEN];
unsigned char checksum,count3;
bit read_flag= 0 ;
#define uchar unsigned char
#define uint unsigned int
sfr WDT_CONTR=0xc1; //看门狗
sfr CLK_DIV=0x97; //CPU分频
sbit led1 = P2^0;
sbit led2 = P2^1;
sbit led34 =P3^4;
sbit led35 =P3^5;
sbit indata=P3^2;
//PanHui
//2010-10-1
//ph_layout@126.com
//***********类型定义******************
//将定时器中的高低8位转成INT型
union h8l8type{
int hl;
char cdata[2];
};
union h8l8type hl88;

//***********变量定义***********************
//遥控器
uchar tcp01=0;
uchar indataxp=0;
uint tcpStart=0,tcp3,tcp1;
uchar indata48[6]={0,0,0,0,0,0};
uchar indata8;

//晶体频率

//函数声明
void int_0(void);
void delayms(uint xms);
void delay1ms(uint xms);
void init_serialcomm( void );
void send_char_com( unsigned char ch) ;
void rs232();

//延时程序
void delayms(uint xms)
{
uint i,j;
for(i=xms;i>0;i--)
{
for(j=110;j>0;j--);
}
}
//内部时钟,1毫秒定时 xms = 660
void delay1ms(uint xms)
{
uint dms;
for(dms=0;dms<xms;dms++)_nop_();
}
///////////////////////////////////////////////////////
//主程序
//////////////////////////////////////////////////////
void main()
{
uchar i;
//test
//********是否为看门狗复?****

//*********初始化*************
EX0 = 0; //关INT0的中断
EA = 0;

//中断INT0

//CLK_DIV = 0x01;
//*******遥控器中断设置*************
//定时计数器0设置
TMOD=0x21;
ET0=0;
TH0=0;
TL0=0;
IT0=1; //1->0下降沿中断事件
EX0=1; //打开中断
EA=1; //开总中断

//WDT_CONTR = 0x35;

//串口
rs232();


while(1)
{

//WDT_CONTR = 0x35;

for(i=6;i<=5;i++)
{

//P2=~i;
send_char_com(indata48[0]);
send_char_com(indata48[1]);
send_char_com(indata48[2]);
send_char_com(indata48[3]);
send_char_com(indata48[4]);
send_char_com(indata48[5]);
//P1=~indata48[i];
delayms(220000);
delayms(220000);
}


}

}
//**************************************************
//**************************************************
/* 遥控器输入P3.2 INT0中断,解码程序*/
//**************************************************
//**************************************************
void int_0() interrupt 0 using 0
{

uchar inxp;
//采用TCP查询法
EA=0; //关中断

hl88.cdata[0] = TH0;
hl88.cdata[1] = TL0;
TH0=0;
TL0=0;
TR0=1;

if(tcp01==1)
{
//引导头
tcpStart = hl88.hl;
if(tcpStart>9000)
{
tcp01=3;
tcp3=(tcpStart/16)*3;
//P1=~hl88.cdata[1];;
//P2=~hl88.cdata[0];

indata48[0]=0;
indata48[1]=0;
indata48[2]=0;
indata48[3]=0;
indata48[4]=0;
indata48[5]=0;
//while(1);
}
}
else
{

if(tcp01 == 3)
{
//数据中断
indataxp++;
if(indataxp>49)
{
tcp01=0;
//保存指令
//P1=~indata48[4];
//P2=~indata48[5];
indataxp=0;

send_char_com(indata48[0]);
send_char_com(indata48[1]);
send_char_com(indata48[2]);
send_char_com(indata48[3]);
send_char_com(indata48[4]);
send_char_com(indata48[5]);
}
else
{

inxp = indataxp/8;
if(tcp3 > hl88.hl)
{
indata48[inxp]= indata48[inxp]<<1|0x01;
}
else
{
indata48[inxp]=indata48[inxp]<<1;
}

}
}

}

if(tcp01==0)tcp01=1;
EA=1; //打开中断
}





//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////// 串口调试程式 ////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////

void init_serialcomm( void )
{
SCON = 0x50 ; //SCON: serail mode 1, 8-bit UART, enable ucvr
TMOD |= 0x21 ; //TMOD: timer 1, mode 2, 8-bit reload
PCON |= 0x80 ; //SMOD=1;
TH1 = 0xFb; //Baud:9600 fosc=11.0592MHz
IE |= 0x90 ; //Enable Serial Interrupt
TR1 = 1 ; // timer 1 run
// TI=1;
}
//向串口发送一个字符
void send_char_com( unsigned char ch)
{
SBUF=ch;
while (TI== 0 );
TI= 0 ;
}
//向串口发送一个字符串,strlen为该字符串长度
void send_string_com( unsigned char *str, unsigned int strlen)
{
unsigned int k= 0 ;
do
{
send_char_com(*(str + k));
k++;
} while (k < strlen);
}

//串口接收中断函数
void serial () interrupt 4 using 3
{
if (RI)
{
unsigned char ch;
RI = 0 ;
ch=SBUF;
if (ch> 127 )
{
count3= 0 ;
inbuf1[count3]=ch;
checksum= ch- 128 ;
}
else
{
count3++;
inbuf1[count3]=ch;
checksum ^= ch;
if ( (count3==(INBUF_LEN- 1 )) && (!checksum) )
{
read_flag= 1 ; //如果串口接收的数据达到INBUF_LEN个,且校验没错,
//就置位取数标志
}
}
}
}

void rs232()
{
init_serialcomm(); //初始化串口
*滑块验证:
您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

QQ|手机版|MCU资讯论坛 ( 京ICP备18035221号-2 )|网站地图

GMT+8, 2024-12-24 07:14 , Processed in 0.057886 second(s), 12 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表