找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3454|回复: 1
打印 上一主题 下一主题
收起左侧

tc9012-011红外遥控单片机解码lcd显示

[复制链接]
跳转到指定楼层
楼主
ID:72705 发表于 2015-1-24 15:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
//    本程序主要是遥控器解码和1602驱动程序
//-------------------------------------------------------
//    LCD1602    IR-DECODE
//    连线表:  CPU=89S52
//    SysClock=12MHz
//    LCD:  1602
//    功能:解码红外遥控器
//    遥控器芯片:tc9012-011
   
#include <at89x52.h>
#define uchar unsigned char
#define uint  unsigned int
/*----------------------------控制I/O口设置,根据实际而定---------------*/
#define  RS     P0_7         //RS数据命令选择端,高电平数据,低电平命令
#define  RW     P0_6         //RW读写选择端,高电平读操作,低电平写操作
#define    E     P0_5         //E使能控制端,E高电平跳变为低电平时LCD执行命令
#define    DATA P2           //数据端口定义
#define    D0    P2_0
#define    D1    P2_1
#define    D2    P2_2
#define    D3    P2_3
#define    D4    P2_4
#define    D5    P2_5
#define    D6    P2_6
#define    D7    P2_7
#define    KEY1 P1_0
#define    KEY2 P1_1
#define    IR_RE P3_2
/*------------------------------------------------------------------------------*/
  bit    k=0;                                       //红外解码判断标志位,为0则为有效信号,为1则为无效
  uchar n=0;                                       //用来控制外部中断
  uchar code str0[16]=" REMOTE CONTROL";           //开机画面显示
  uchar code str1[16]="  IR-CODE: ";
  uchar code str2[16]="ERROR";
  
  uchar *p0=str0;
  uchar *p1=str1;
  uchar *p2=str2;
  delay1ms(uint k);
  
  void disp(void);                             //红外键值显示程序
  uchar  data date[4];                         //date数组为存放地址原码,反码,数据原码,反码
  
/*------------------------LCD忙判断子程序--------------------------------------*/
void busy()
{
  RS=0;RW=1;
  E=0;E=1;DATA=0xff;
  while(D7);
}
/*----------------------- 写命令子程序-----------------------------------------*/
void wcom(uchar com)
{
  busy();
  RS=0;RW=0;
  E=1;
  DATA=com;
  E=0;
}
/*-------------------------写数据子程序--------------------------------------*/
void wdata(uchar dat)
{
  busy();
  RS=1;RW=0;
  E=1;
  DATA=dat;
  E=0;
}
/*--------------------------读命令子程序-----------------------------------*/

uchar rcom(void)
{
  uchar com;
  busy();
  RS=0;RW=1;
  DATA=0xff;
  E=1;
  com=DATA;
  E=0;
  return(com);
}
/*----------------------------读数据子程序-----------------------------*/
uchar rdat(void)
{
  uchar dat;
  busy();
  RS=1;RW=1;
  DATA=0xff;
  E=1;
  dat=DATA;
  E=0;
  return(dat);
}
/*--------------------------延时1ms程子程序-----------------------*/
delay1000()              
{
    uint i,j;
    for(i=0;i<1;i++)
      for(j=0;j<124;j++)
      ;
}
/*---------------------------延时882us子程序-----------------------*/
delay882()
{
    uint i,j;
    for(i=0;i<1;i++)                  
      for(j=0;j<109;j++)
      ;
}
/*--------------------------延时2400ms程子程序-----------------------*/
delay2400()                                          
{
    uint i,j;
    for(i=0;i<3;i++)           
      for(j=0;j<99;j++)
       ;
}

/*--------------------------以下为初始化程序,由上面子程序组成,根据个人爱好-----------*/

/******************************清屏程序***********************************/
void clear()
{ wcom (0x01);}
/******************************归位程序********************************/
void rehome()
{ wcom(0x02); }
/*******************8*****888**88888显示模式设定8888888888888888888888*/
void  mode(bit x)
{
     if(x==1)wcom(0x38);           //两行5*8 mode
else wcom(0x34);             //一行5*10 mode
}
/*------------------------显示开关控制命令----------------------------*/
void on_off(bit x)
{
  if(x==1)wcom(0x0f);            //显示开,光标开,光标闪烁
  else wcom(0x0c);              //显示开,光标关
}

/*------------------------init初始化组合-------------------------*/
void init()
{
  clear();           //清屏
  mode(1);           //模式设置
  on_off(1);          //显示设置
  wcom(0x06);         //移动方式
}
/*---------------------------对字符串的处理------------------------*/
void strchar(uchar *p)
{
  while(*p!='\0')
  {
     wdata(*p);
p++;
  }
}
/*----------------------------------------------------------*/
/*-----------------------红外解码程序(核心)-----------------*/
/*----------------------------------------------------------*/
void IR_decode()
{
  uchar  i,j;
  while(IR_RE==0);
  delay2400();
  if(IR_RE==1)                                //延时2.4ms后如果是高电平则是新码
  {
      delay2400();                             //延时4.8ms避开4.5ms的高电平
  for(i=0;i<4;i++)
  {
     for(j=0;j<8;j++)
     {
            while(IR_RE==0);                        //等待地址码第1位高电平到来
            delay882();                          //延时882ms判断此时引脚电平
      ///CY=IR_RE;
            if(IR_RE==0)
            {        
      date[i]>>=1;
      date[i]=date[i]&0x7f;      
            }
            else if(IR_RE==1)
      {
      delay1000();
      date[i]>>=1;
      date[i]=date[i]|0x80;
      }
   }                                     //1位数据接收结束
      }                                        //32位二进制码接收结束
    }
}

/*------------------二进制码转换为压缩型BCD码,并显示---------------*/
void two_2_bcd(uchar date)
{
    uchar temp;
    temp=date;
    date&=0xf0;
    date>>=4;                     //右移四位得到高四位码
    date&=0x0f;                   //与0x0f想与确保高四位为0
    if(date<=0x09)
    {
     // wcom(0xcb);                  
      wdata(0x30+date);             //lcd显示键值高四位
    }
    else
    {
      date=date-0x09;
  //wcom(0xcb);
  wdata(0x40+date);
    }
    date=temp;
    date&=0x0f;
    if(date<=0x09)
    {
      wdata(0x30+date);             //lcd显示低四位值
    }
    else
    {
      date=date-0x09;
  wdata(0x40+date);
    }
    wdata(0x48);                  //显示字符'H'
}

//////////////////////////////转换程序结束///////////////////////////

/*----------------------解码成功后,1602显示键值子程序---------------*/
void disp()
{
    uchar date1;
    date1=date[3]^0xff;                //如果得到的数据原码和数据反码相反
    if(date[2]==date1)                  //显示键值
    {  
    wcom(0xc0);
       two_2_bcd(date[0]);
    wdata(0x20);
    two_2_bcd(date[1]);
        wdata(0x20);
    two_2_bcd(date[2]);
        wdata(0x20);
    two_2_bcd(date[3]);
    }
}

/*------------------------外部中断0程序-------------------------*/
/*------------------主要用于处理红外遥控键值--------------------*/
void int0() interrupt 0
{
    uint i;
    for(i=0;i<4;i++)
    {
      delay1000();
  if(IR_RE==1){k=~k;}                    //刚开始为4.5ms的引导码,如果4ms内出现高电平则退出解码程序
    }
    if(k==0)
    {
    EX0=0;                                 //检测到有效信号关中断,防止干扰
    IR_decode();                           //如果接收到的是有效信号,则调用解码程序
    disp();                                //解码成功,调用显示程序,显示该键值
    }
  EX0=1;                                  //开外部中断,允许新的遥控按键
}

/*---------------------------------------------------------------*/
/*            以下为主程序,主要对LCD初始化,开始界面设置          */
/*---------------------------------------------------------------*/
void main(void)
{
  SP=0x60;                                 //堆栈指针
  TMOD=0x11;                               //定时器模式设置所选为 模式1
  TH0=0xd8;                                //定时器初值理论为 10ms;
  TL0=0xf7;                                //实际取d8f7
  ET0=1;                                   //允许定时器0中断
  EX0=1;                                   //允许外部中断0,用于检测红外遥控器按键
  EA=1;                                    //总中断开
  init();                                  //初始化LCD
  wcom(0x80);                              //写入字符的地址为第1行第1列
  strchar(p0);                             //调用显示字符串函数
  wcom(0xc0);
  //strchar(p1);
  while(1);
}


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:61484 发表于 2015-4-14 22:47 | 只看该作者
感谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表