|
利用ATmega8的ICP解码遥控器,精准快速,希望对初学者有帮助。
以下是部分代码:
#define IR_state_0 0 //无遥控信号
#define IR_state_1 1 //引导码前段
#define IR_state_2 2 //引导码后段
#define IR_state_3 3 //数据码前段
#define IR_state_4 4 //数据码后段
volatile uInt stamp=0; //暂存时间印记
volatile uChar count=0; //32位数据计数
volatile uChar state=0; //状态机
volatile uChar times=0;
volatile uChar IRCOM[4]; //保存接收的遥控数据
volatile uLong Nec_ircom=0;
volatile uChar ADDRESS=0;
volatile uChar IRCODE=0;
volatile uChar err_flag=0;
//************************端口初始化*********************************
void STF_INIT(void)
{
PORTB=0X00;
PORTB|=(1<<Freq_ICP);
DDRB|=(1<<MOSI )|(1<<SCK)|(1<<DISPPL);
DDRB&=~(1<<Freq_ICP);
PORTD=0x00;
DDRD|=(1<<LcdRs)|(1<<LcdEn)|(1<<RXD)|(1<<TXD);
DDRD &= ~((1<<KEY_sta)|(1<<IRIN));
PORTC=0x00;
DDRC=0xff;
}
//******************test*************************
void Test (void)
{
STF_INIT();
Timer1_INIT();
Reset_IR();
sei();
while(1);
}
/**************************************
*
* NEC红外协议解码
*
**************************************/
void NEC_Decode(void)
{
switch(state)
{
case IR_state_0: //第一次中断,数据丢弃(下降沿中断)
state = IR_state_1;//设置为状态1
break;
case IR_state_1: //接收引导码前半段(9ms)(上升沿中断)
if ((stamp >8500)&&(stamp<9500))
state = IR_state_2; //设置为状态2
else
Reset_IR();//干扰信号,复位接收状态
break;
case IR_state_2: //接收引导码后半段(4.5ms)(下降沿中断)
if ((stamp >4000)&&(stamp<5000))
state = IR_state_3; //设置为状态3
else
Reset_IR();//干扰信号,复位接收状态
break;
case IR_state_3://过滤掉数据码前半部分(560us)(上升沿中断)
state = IR_state_4; //设置为状态4
break;
case IR_state_4://接收数据后半段(0=565us,1=1690us)(下降沿中断)
count++;
if(count<=32)//接收32位数据(低位在前)
{
state = IR_state_3; //回到状态3
Nec_ircom=Nec_ircom>>1;
if(stamp >1600&&stamp<1800) //保存数据"1"
{
Nec_ircom|=0x80000000;
}
}
else
{
IRCOM[3] =( Nec_ircom&0xff);//地址
IRCOM[2] = ((Nec_ircom>>8)&0xff); //地址反
IRCOM[1] = (Nec_ircom>>16)&0xff;//数据
IRCOM[0] = (Nec_ircom>>24)&0xff;//数据反
IRCOM[0] = ~IRCOM[0];
if(IRCOM[1]==IRCOM[0])
{
LcdClear(1);
LcdClear(2);
LcdWcom(0x80);
printf("addr:%2X code:%2X",IRCOM[3],IRCOM[1]);
}
else
{
LcdWcom(0xc0);
printf("Decoding error !");
}
ADDRESS = IRCOM[3];
IRCODE = IRCOM[1];
Reset_IR(); //完成接收,复位接收状态
}
break;
}
}
/**************************************
*
* 复位状态设置
*
**************************************/
void Reset_IR (void)
{
TCCR1B &=~( _BV(ICES1)); // 设置为下降沿触发
state = IR_state_0; //复位为状态0
count=0;
err_flag=0;
}
/**************************************
*
* 初始化定时器1
*
**************************************/
void Timer1_INIT(void)
{
TCCR1B=0x00;
TCCR1A = 0x00; //普通模式
TCNT1H = 0x00; //8MHz
TCNT1L = 0x00;
TIMSK |=_BV(TICIE1); //输入捕捉中断标志
TIFR |= (1<<TOV1); //清中断标志
TCCR1B|= (1<<ICNC1)|((1<<CS11)); //开启输入捕捉口的噪声抑制器,8分频
TCCR1B&=~(1<<ICES1); //下降沿触发
}
/**************************************
*
* 定时器1 输入捕捉信号中断
*
**************************************/
ISR(TIMER1_CAPT_vect)
{
stamp= ICR1L; //保存时间印记
stamp+=(uInt)(ICR1H<<8);
TCNT1H = 0x00; //8MHz
TCNT1L = 0x00; //清零计数器
TCCR1B ^= _BV(ICES1); //切换捕获的触发方式
NEC_Decode();
}
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|