遥控HT6222芯片的解码调试
由于视力测试仪设计的需要,会用到红外遥控器,而此前对于红外就收管解码的原理只之甚少。基本上是一头雾水,网上查阅相关资料,很少有讲的清楚详细的,对于解码程序的编写原理也没有见人分析过,倒是同一个程序在百度文库里就被转疯了(还是十几年前的人写的了,表示无语),里面程序写的非常凌乱,也没介绍原理。
由于开始接触的是HT6222芯片,下载到它的数据手册看了以后对程序的编写更是一头雾水,发送波形如下
图一
图二
图三
由于看到的是一系列的脉冲,因此感到程序无从下手。可能看到资料多了而有些又是有偏差到最后就连默认是的高电平还是低电平都不大清楚了。
直到拿到了红外解码管TSOP1838,找了很久没确定它的接线方式,可能是多疑了,因为下图并没有说明是正面还是方面,当然一般都应该是正面吧,当就这也让我犹豫了蛮久。以下为正面。
图四
然后接好后接到示波器上看红外管的接收波形,顿然大悟,so easy!,默认电平为高,低电平有效。
红外管接收波形如下:
接着就调试好了红外解码的程序。
以下为Atmega128的程序,由于需要用到avr的做主控MCU而本人接触AVR不到一周如程序有所疏忽,还请指正,谢谢。
/*
* IR_code.c
*
* Created: 2012/11/16 16:48:59
* Author: walker
*/
/*============================================================
=============================================================*/
#define F_CPU 12000000UL
#include
#include
#include
#include
#define uint unsigned int
#define uchar unsigned char
volatile uint code_arry[16];
volatile uchar g_flag=0,g_keyEorr=0,int_count=0;
void initialize_int0(void)
{
EIMSK=(1<<0); // 使用外部中断0(INT0)PD0号管脚
EICRA=0x02; // 下降沿中断请求(异步)
}
void initialize_timer(void)
{
TCCR1A=0x00;
TCCR1B=0x0C;
TCCR1C=0x00;
TIMSK=0x00;
OCR1A=46875; //12Mhz下256分频1s的计数
}
/**************************************
解码程序:返回一个字节的按键码
**************************************/
uchar get_ircode()
{
uchar code=0;
volatile uint i;
volatile uint ir_code=0,s_msb=0,d_msb=0;
SREG&=~0x80; //g所有中断
g_flag=0;
for(i=0;i<16;i++)
{
if(code_arry<=65)
ir_code<<=1;
else if(code_arry>65)
{
ir_code<<=1;
ir_code|=1;
}
}
s_msb=ir_code>>8;
d_msb=ir_code&0x00ff;
if((d_msb&s_msb)!=0)
g_keyEorr=1;
else
code=s_msb;
SREG|=0x80;
return code;
}
int main(void)
{
initialize_int0();
initialize_timer();
DDRD =0xfE;
DDRA =0xff;
PORTA=0xfe;
SREG|=0x80; // 使能所有中断
for(;;)
{
if(g_flag==1)
{
PORTA=get_ircode();
}
}
}
SIGNAL(SIG_INTERRUPT0) // 外部中断0
{
static uint i=0,flag=0;
uint time=0;
if (g_keyEorr) //如解码出错则重新初始化
{
time=0;
flag=0;
g_flag=0;
g_keyEorr=0;
int_count=0;
i=0;
}
time=TCNT1L;
time|=(TCNT1H<<8);
if(time>562&&time<850)//12ms<16ms 开始标志
{
flag=1;
i=0;
int_count=0;
time =0;
}
if(flag==1)
{
int_count++;
if(int_count>16&&int_count<=32)//只要16位数据
{
code_arry[i++]=time;
}
else if(int_count>32)
{
int_count=0;
i=0;
flag=0;
g_flag=1;//解码标志打开
PORTA=0x55;
}
}
time=0;
EIFR|=0X01; // INT0的flag强制清零。写1,自动清零*/
TCNT1H=0;
TCNT1L=0;
}
全文完。
文章评论(0条评论)
登录后参与讨论