}
void delay_ms(uint z)//延时子程序1ms {
uint x,y; for(x=z;x>0;x--) for(y=113;y>0;y--); }
void init(void)/////初始化 {
ir=1; //红外端口写1 led_cs=0; //关闭LED EA=1; //开总中断
TMOD=0x02; //定时器0,模式2,8位自动装载模式 TH0=0Xd1; //定时50us TL0=0Xd1;
IT1=1; //INT1下降沿触发 ET0=1; //允许定时器中断 EX1=1; //允许外部中断 }
/*********************************************** 定时器中断
***********************************************/ void time0() interrupt 1///定时器中断 {
count++;//定时器中断次数累加 }
/********************************************** 外部中断,红外解码程序
**********************************************/ void int1() interrupt 2///外部中断 {
TR0=1;//开定时器中断
if(count>12&&count<270)//如果信号合法,则放入buf_count,count清0,对下一个脉冲信号计时 {
buf_count=count; count=0; }
delay_10us(10);//延时100us以消除下降沿跳变抖动
if(ir==0)//INT1引脚稳定为低电平,则表法确实是信号,count重新计时,因上面延时了50us,故要补偿1次TO中断 {
count=2; }
if(buf_count>12&&buf_count<270)//若收到的信号合法,则再进行信号分析 {
if(ir_status==0)//如果之前未收到引导码 {
if(buf_count>210&&buf_count<270)//判断是否引导码13.5ms {
ir_status=1;//系统标记 buf_count=0;// } }
else if(ir_status==1)///收到引导码 {
if(common_code_count>=25)//若收完26个脉冲 {
ir_status=2;//数据解码标记
common_code_count=0;//系统码计算清零 buf_count=0;//中断计数暂存清0 }
else if((buf_count>40&&buf_count<70)||(buf_count>12&&buf_count<32)) {
buf_count=0;
common_code_count++;//每收到一个信号自加1 } }
else if(ir_status==2)//进入数据编码接收 {
if(key_bit_count<8)//收到数据少于8位,则将收到的数据写入buf_key_code {
if(buf_count>40&&buf_count<70) {
buf_count=0; buf_key_code>>=1;
buf_key_code|=0x80;//收到1 key_bit_count++;//数据脉冲累加
}
else if(buf_count>12&&buf_count<32)//收到0 {
buf_count=0;
buf_key_code>>=1;//收到0 key_bit_count++; } }
else //若收完8位数据则做以下处理 {
ir_status=0;//接收状态返回到空闲 key_code=buf_key_code; key_bit_count=0; buf_key_code=0; buf_count=0; TR0=0; new_code=1; } } } }
/********************************************** 1062驱动程序
**********************************************/
void wirte_cmd(uchar cmd)//写命令 { rs=0; P0=cmd; en=1; delay_ms(5); en=0; }
void wirte_data(uchar dat)//写数据 { rs=1; P0=dat;
en=1; delay_ms(5); en=0; }
void wirte_string(const unsigned char *s)//在第二行第5个字开始写字符串 {
wirte_cmd(0x80+0x40+0x05); while(*s) {
wirte_data(*s); s++; } }
void init_1602()///1602初始化 { dm=0; wm=0; led_cs=0; wirte_cmd(0x38); delay_ms(5); wirte_cmd(0x0c); delay_ms(5); wirte_cmd(0x06); }
/************************************* 主程序
*************************************/ void main() {
init(); ///初始化 init_1602(); //1602初始化
while(!new_code);//判断是否有新按键,如果有则执行下面程序,没有则一直循环 wirte_cmd(0x01);//1602清屏 delay_ms(5);
wirte_cmd(0x80);//在第一行写入EE01 DEMO:IR for(num=0;num<12;num++) {
wirte_data(table[num]); delay_ms(1); }
wirte_cmd(0x80+0x40);//在第二行写入code: for(num=0;num<5;num++)
{
wirte_data(table1[num]); delay_ms(1); }
if(key_code<10)//如果按鍵小于10则写入相应的数字 {
wirte_data(table2[key_code]); delay_ms(2); }
else if(key_code<50)//大于10则写入字符,与遥控器对应 {
switch(key_code) {
case 21:wirte_string(\ case 28:wirte_string(\ case 10:wirte_string(\
case 14:wirte_cmd(0x80+0x40+0x05);wirte_data(0x7f);wirte_data(0x7e);break;//先写字符位置,然后写字符, case 25:wirte_string(\ case 19:wirte_string(\ case 15:wirte_string(\ case 30:wirte_string(\ case 31:wirte_string(\ case 27:wirte_string(\ case 26:wirte_string(\ case 16:wirte_string(\ case 24:wirte_string(\ case 13:wirte_string(\ case 12:wirte_string(\ case 20:wirte_string(\ delay_ms(2); }
new_code=0; } }