烦透了网上的sc6221的遥控解码程序,那些全是死延时来解码,没有新意,而且各大网还到处传播.被奉为入门子弟黄金教程,还美其名曰"费了很多的心血",,,,今天我终于忍不住了.用中断写了一个6221的解码程序.资源需要一个8位的定时器,一个外部中断.很多的台系mcu都可以参照使用翻译为汇编了....此程序非常方便各位调用.
/*************************************************************************/
//uPD6221遥控测试
//是谁对人类的贡献最大,就是那些无私贡献自已程序一生无私的人。
//Created by : mikezhong
//Created dated: Apr. 5,2007
/**************************************************************************/
#include "STC12C2052AD.h"
#include "intrins.h"
sbit P1_0=P1^0;
sbit P1_1=P1^1;
sbit P1_2=P1^2;
sbit P1_3=P1^3;
sbit P1_7=P1^7;
sbit P3_0=P3^0;
sbit P3_1=P3^1;
sbit P3_2=P3^2;
sbit P3_3=P3^3;
sbit P3_4=P3^4;
sbit P3_5=P3^5;
sbit P3_7=P3^7;
#define nop(); _nop_();
#define REMOTE_IN P3_3
#define OFF 0
#define ON 1
/****************Define IR code*******************************/
#define vol_up 0x807f50af //0x04fbd827 //遥控功能码
#define vol_down 0x807f6897 //0x04fb8877
#define mute 0x807fd02f
// 0 1 2 3 4 5 6 7 8 9
unsigned char displaycode[]={0xfd,0x61,0xdb,0xf3,0x67,0xb7,0xbf,0xe1,0xff,0xf7};
unsigned char vol;
unsigned char bit_count,count,int_flag,_9ms_flag,remote_ok;
unsigned int continue_flag;
long int remote_value,remote_value_buffer;
void Port_initial(void);
void T1_T0_INT1_initial(void);
void display(unsigned char d_data);
void Delay_us(unsigned char time);
/********************For remote control***********************/
void timer0_ISR(void) interrupt 1 //256us
{
TH0=0Xff; //256us-->0xff00,12MHz Crystal
TL0=0X00;
if (int_flag==1)
{
count++;
}
if (_9ms_flag==1)
{
continue_flag++;
}
if (continue_flag>=453)//116ms/0.256ms=453.125
{
_9ms_flag=0; //如果引导码后116ms都没有出现连续码,则无连续码,重新等待按键。
count=0;
int_flag=0;
bit_count=0;
continue_flag=0;
}
}
/************************************************************/
void INT1_ISR(void) interrupt 2
{
int_flag=1; //进入中断则标置置1,用于定时器中断中count计数。
if (bit_count==0)
{
if (count>49 && count<56) // 13.5ms/0.256ms=52.73
{
bit_count++;
_9ms_flag=1; //第一位引导码有效。
count=0; //从0开始计数。
return;
}
else if (count>39 && count<50 && _9ms_flag==1)//11.5ms/0.256ms=44.92
{
//P3_5=!P3_5; //for testing.
remote_ok=1; //遥控信号继续有效。
continue_flag=0; //清除超时标志。
int_flag=0; //清除外部中断标志,禁止count计数。
count=0; //计数count清零。
return;
}
else
{
nop();
count=0;
bit_count=0;
return;
}
}
if (count>2 && count<6) //1.125ms/0.256ms=4.39
{
remote_value =remote_value<<1;//保存0值到变量中。
bit_count++;
}
else if (count>6 && count<11)//2.25ms/0.256=8.789
{
remote_value=(remote_value<<1) + 0x00000001;//保存1值到变量中。
bit_count++;
}
else
{
count=0;
int_flag=0;
_9ms_flag=0;
bit_count=0;
continue_flag=0;
}
if (bit_count>=33)
{
remote_ok=1;
remote_value_buffer=remote_value;
int_flag=0;
bit_count=0;
count=0;
}
count=0;
} //int1中断结束
void main(void )
{
remote_value=0;
Port_initial();
T1_T0_INT1_initial();
TR0=1;
ET0=1;
EX1=1;
EA=1;
vol=30;
P3_5=0;
bit_count=0;
while (1)
{
display(vol);
if (remote_ok==1)
{
remote_ok=0;
remote_value=0;
switch (remote_value_buffer)
{
case vol_up: vol++;
remote_value_buffer=0;//如果在这里清除此变量remote_value_buffer,则为单击功能。
break;
case vol_down: vol--;break;//未清除remote_value_buffer,此为连击功能。
case mute: vol--;break;
default : break;
}
}
}
}
/**********************************************************
Accurate us time delay
Parameter:3 ->6 us
27 ->50 us,
55 ->100us,
82 ->150us,
107->200us,
131->250us,
160->300us,
189->350us,
214->400us,
253->476us
**********************************************************/
void Delay_us(unsigned char time)
{
while (--time)
{
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
}
}
/*********************************************/
void display(unsigned char d_data)
{
unsigned char high,low;//vol_high,vol_low分别为查表时要用到的高字节,和低字节
high=d_data/10;
low=d_data%10;
P1=0XFF;
P3_7=1;
P1=displaycode[high];
P1_0=0;P3_7=1;
Delay_us(253);
Delay_us(253);
P1=0XFF;P3_7=1;
P1=displaycode[low];
P1_0=1;P3_7=0;
Delay_us(253);
Delay_us(253);
}
/***********************************************************
Timer0 was used for remote control ,each 256us interrupt,
***********************************************************/
void T1_T0_INT1_initial(void)
{
TMOD=0X01; //Timer0 mode1. 16bit timer.
TCON=0x04; //enable timer0 interrupt.TF0=1;TR1=0;Enable INT1 fall-edge interrupt.
TH0=0Xff; //256us-->0xff00,12MHz Crystal
TL0=0X00;
}
/*********************PORT initialization************************/
void Port_initial(void)
{
P1M0=0X00;//input setup.
P1M1=0X00;
P3M0=0x00; //P3。3 input, other pins was set to output.
P3M1=0x00;
P1=0XFF;
P3=0Xff;
}