原创 51 红外遥控解码 实验(二十二)

2008-5-12 11:51 5170 6 7 分类: MCU/ 嵌入式

点击下载点击下载


这个是通过红外遥控器控制单片机的实验,详情见附件.


平台:FDR-1 51开发板


主程序代码:


/*11.0592MHz晶振*/
#include
#include"delay52.h"
#include"LCD1602_4.h"


sbit beep="P3"^7;
sbit inf="P3"^3;
sbit led1=P1^3;


uchar key_code=0;/*key_code:遥控键值*/
uint  buf_key_code=0;/*键值暂存对应功能看主函数*/
uchar key_bit_count=0;/*键编码脉冲计数*/
uint  count_T=0,buf_CT=0;/*count_T:定时器中断次数计数,buf_CT用来截获某一时间的count_T值以供判断*/
uchar common_code_count=0;/*前导码脉冲计数*/
uchar inf_status=0;/*inf_status:脉冲接收器所处的状态,0:无信号,1:前导码接收区,2:数据编码接收区*/


void main()
{
 LCM1602_Init();
 EA=1;   //开全局中断
 ET0=1;   //开定时器0中断
 TMOD=0x02;//T0设置为8位自动装载模式
 TH0=0xCA; //自动装载值为202,中断间隔为50us
 TL0=0xCA; //初值为202
 IT1=1;   //INT1为下降沿触发
 EX1=1;   //开外部中断
 TR0=1;   //启动定时器计数
 while(1)
 { 
  /*收到数字键则显示数字*/
  if(key_code<10)
  {
   beep=0;//响蜂鸣器
  //CLEARSCREEN;
   LCM1602_write_string(0,0,"number:");
   num(0,7,key_code);//其它数字和编码值相同,直接显示键值
   LCM1602_write_string(1,0,"code:");
   num(1,5,key_code);
   key_code=255;//清键值
   delayms(20);
   beep=1;
  }
  /*收到功能键则显示相应的功能*/
  else if(key_code<50)
  {
   beep=0;
  // CLEARSCREEN;//清屏
   switch(key_code)
   {
    case 22:LCM1602_write_string(0,9,"mute");break;
    case 18:LCM1602_write_string(0,9,"power");break;
    case 10:LCM1602_write_string(0,9,"--");break;
    case 31:LCM1602_write_string(0,9,"s.sys");break;
    case 15:LCM1602_write_string(0,9,"BASS");break;
    case 27:LCM1602_write_string(0,9,"CALL");break;
    case 11:LCM1602_write_string(0,9,"TV/AV");break;
    case 25:LCM1602_write_string(0,9,"HOBBY");break;
    case 26:LCM1602_write_string(0,9,"recall");break;
    case 19:LCM1602_write_string(0,9,"CH+");break;
    case 23:LCM1602_write_string(0,9,"CH-");break;
    case 20:LCM1602_write_string(0,9,"VOL-");break;
    case 16:LCM1602_write_string(0,9,"VOL+");break;
    case 24:LCM1602_write_string(0,9,"MENU");break;
    case 28:LCM1602_write_string(0,9,"SLEEP");break;
    case 30:LCM1602_write_string(0,9,"PRE");break;
    case 12:LCM1602_write_string(0,9,"SCAN");break;
   }
   LCM1602_write_string(0,0,"function:");
   LCM1602_write_string(1,0,"code:");
   num(1,5,key_code);
   key_code=255;//清键值
   delayms(30);
   beep=1;
  }
  delayms(50);          
 }
}


void Time0(void) interrupt 1
{
    count_T++;//周期累加
 /*如果外部中断处于无信号区,则滤除前导宽脉冲中间的跳变毛刺*/
 if(inf_status==0&&count_T<160)
 {
  EX1=0;
 }
 /*如果外部中断处于信号区,则滤除宽脉冲中间的跳变毛刺*/
 else if((inf_status==1||inf_status==2)&&count_T<12)
 {
  EX1=0;
 }
 /*渡过上升沿后重新开放外部中断*/
 else
 {
  EX1=1;
 }
 /*超过25ms,则锁定count_T值,等待下一次信号脉冲下降沿来解开*/
 if(count_T>500)
 {
  inf_status=0;
  count_T=600;
 }
}


/***************************************************************
  外部中断1,用于捕获红外脉冲信号
****************************************************************/
void int_1(void) interrupt 2
{
 led1=0;
 TR0=1;
 if(count_T>15&&count_T<250)//如果信号合法,则捕进buf_CT,count_T清0,对下一个脉冲信号计时
 {
  buf_CT=count_T;
  count_T=0;
 }
 delay10us(10);//延时100us以消除下降沿跳变抖动
 if(inf==0)//INT1引脚稳定为低电平,则表示确实是信号,count_T重新计时,因上面延时了100us,故要补偿2次T0中断
 {
  count_T=2;
 }
 if(buf_CT>15&&buf_CT<250)//若收到的信号合法,则再进行以下的信号分析
 {
  if(inf_status==0)//若当前信号接收系统处于空闲状态,则标志进入前导码接收区
  {
   if(buf_CT>210&&buf_CT<250)//捕捉前导码
   {
    inf_status=1;//标志进入前导码接收区
    buf_key_code=0;
    key_bit_count=0;     
    buf_CT=0;
   }
  }
  else if(inf_status==1)//前导码接收区(收到的脉冲全部忽略)
  {
   if((buf_CT>15&&buf_CT<25)||(buf_CT>32&&buf_CT<45))//脉冲接收
   {        
    common_code_count++;//脉冲数计算
    if(common_code_count>=26)//若收够了26个脉冲
    {
      inf_status=2;//则标志进入数据接收区
     common_code_count=0;//脉冲计数清0
     key_bit_count=0;
     buf_key_code=0;
    } 
   }
  }
  else if(inf_status==2)//数据接收区
  {
   if(buf_CT>15&&buf_CT<25)//窄脉冲接收
   {
    buf_key_code>>=1;//接收0
    key_bit_count++;
        
   }
   else if(buf_CT>32&&buf_CT<45)//宽脉冲接收
   {
    buf_key_code>>=1;
    buf_key_code|=0x80;//接收1
    key_bit_count++;//数据脉冲数累加,一共有8个
   }
   if(key_bit_count>=8)//若收完8位个数据脉冲,则进行以下的处理
   {
    inf_status=0;//标志接收系统返回空闲状态
    key_bit_count=0;
    key_code=buf_key_code;
    buf_key_code=0;
    TR0=0;
    count_T=600;     
   }   
  }
  buf_CT=0;
 }
 led1=1;
 EX1=1; 
}

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户394394 2009-3-9 12:29

看了咱就没有人回呢!
相关推荐阅读
正点原子 2013-05-17 23:47
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第六十一章 战舰STM32开发板综合实验(标准例程终结篇)
   第六十一章 战舰STM32开发板综合实验        前面已经给大家讲了55个实例了,本章将设计一个综合实例,作为本指南的最后一个实验 ,该实验向大家展示了STM...
正点原子 2013-05-03 23:02
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第六十章 UCOSII实验3-消息队列、信号量集和软件定时器
   第六十章 UCOSII实验3-消息队列、信号量集和软件定时器   上一章,我们学习了UCOSII的信号量和邮箱的使用,本章,我们将学习消息队列、信号量集和软件定时器...
正点原子 2013-05-03 20:42
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第五十七章 ENC28J60网络实验
第五十七章 ENC28J60网络实验   本章,我们将向大家介绍ALIENTEK ENC28J60网络模块及其使用。本章,我们将使用ALIENTEK ENC28J60网络模块...
正点原子 2013-05-01 23:00
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第五十九章 UCOSII实验2-信号量和邮箱
第五十九章 UCOSII实验2-信号量和邮箱      上一章,我们学习了如何使用UCOSII,学习了UCOSII的任务调度,但是并没有用到任务间的同步与通信,本章我们将学习两个最基本的...
正点原子 2013-04-30 10:55
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第五十八章 UCOSII实验1-任务调度
  第五十八章 UCOSII实验1-任务调度      前面我们所有的例程都是跑的裸机程序(裸奔),从本章开始,我们将分3个章节向大家介绍UCOSII(实时多任务操作系...
正点原子 2013-04-26 23:16
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第五十七章 ENC28J60网络实验
 第五十七章 ENC28J60网络实验  本章,我们将向大家介绍ALIENTEK ENC28J60网络模块及其使用。本章,我们将使用ALIENTEK ENC28J60网络模块和uIP 1...
EE直播间
更多
我要评论
1
6
关闭 站长推荐上一条 /3 下一条