STC89C52单片机红外遥控器解码

发布者:数字狂舞最新更新时间:2016-04-15 来源: eefocus关键字:STC89C52  单片机  红外遥控器解码 手机看文章 扫描二维码
随时随地手机看文章
//////////////////////////////////////////////////////////////////////////

 实现功能:  按实验板所佩带的红外遥控器上面的数字键,把红外遥控器的代码显
     示在1602液晶上面,通过此实验也可测试你手上所用红外遥控器的代
    码编号,一定注意要跟红外探测头的距离不要太远,而且
    程序里只编写了遥控器上的数字键的部分
 实验板型号:KBL-XYD-C52
 实验名称:  红外控制1602液晶的显示
 编写人:  谢应东
 编写日期:  2012-5-3      
//////////////////////////////////////////////////////////////////////////

#include
#include

#define uchar unsigned char
#define uint  unsigned int

sbit IR = P3^3;         //红外接收器数据线

uchar code string0[] = {"IR REMOTE CONTROL"}; //定义要显示在1602上的字符串
uchar code string1[] = {"IR-CODE: 0X--  H"};  //定义要显示在1602上的字符串

#define BUSY  0x80                               //lcd忙检测标志
#define LCD_DATAPORT P0                          //定义P0口为LCD通讯端口

sbit Duan=P2^6;     //定义数码管的段选使能端
sbit Wei =P2^7;        //定义数码管的位选使能端

#define Digital_tube_Wei_Enable Wei=1;  //开启控制数码管的位选使能端
#define Digital_tube_Wei_Disable Wei=0;     //关闭控制数码管的位选使能端

#define Digital_tube_Duan_Enable Duan=1; //开启控制数码管的段选使能端
#define Digital_tube_Duan_Disable Duan=0; //关闭控制数码管的段选使能端

sbit LCD_RS=P3^4;         //数据/命令端
sbit LCD_RW=P3^5;         //读/写选择端
sbit LCD_EN=P3^6;

uchar cIRReceiveData[7];
//////////////////////////////////////////////////////////////////////////

函数名称:毫秒延时函数
函数功能:实现毫秒级的延时
参数介绍:Delay_MS: 定义需要延时的毫秒的数值
          iNumber: 记录Delay_MS的数值,以for语句实现所要求的延时
    iValue: 要延时毫秒所要进行的循环数值,本数值为实际测得
返回值: 
注意事项:本实验是在所用晶振为12M的前提下实现的毫秒延时,本函数是通过循环的形
          式完成,所以如果改变了晶振的频率,请做相应的改变
 //////////////////////////////////////////////////////////////////////////

void DelayMs(uint Delay_MS)
{
 uint iNumber,iValue;
 for(iNumber=0;iNumber   //用for语句实现单片机的延时
 {
     iValue=107;      //107这个数值是通过测定而得
     while(iValue--);
 }
}
 //////////////////////////////////////////////////////////////////////////

函数名称:Delay
函数功能:延时0.14毫秒,主要是用于红外解码
参数介绍:cDelay:延时0.14ms的次数
返回值: 
注意事项:无
 //////////////////////////////////////////////////////////////////////////

void Delay(unsigned char cDelay)    //x*0.14MS
{
 unsigned char cNumber;
 while(cDelay--)
 {
  for (cNumber=0;cNumber<13;cNumber++) {}
 }
}
//////////////////////////////////////////////////////////////////////////
函数名称:ReadStatusLCD
函数功能:检测液晶是否忙碌
参数介绍:无
返回值:  LCD_DATAPORT
注意事项:无
 //////////////////////////////////////////////////////////////////////////

unsigned char ReadStatusLCD()
{
 LCD_DATAPORT=0xff;
 LCD_RS=0;
 LCD_RW=1;
 LCD_EN=0;
 LCD_EN=0;
 LCD_EN=1;
 while(LCD_DATAPORT&BUSY);
 return(LCD_DATAPORT); 
}
 //////////////////////////////////////////////////////////////////////////

函数名称:WriteCommandLCD
函数功能:根据1602液晶的时序,通过单片机给1602液晶写一些相关的命令
参数介绍:cCommand:要写入的1602液晶命令
    cBusy:1602液晶是否空闲的标志
返回值: 
注意事项:无
 //////////////////////////////////////////////////////////////////////////

void WriteCommandLCD(uchar cCommand,uchar cBusy)
{
 if(cBusy)ReadStatusLCD();  //检测忙信号
 LCD_DATAPORT=cCommand;     //要写入的指令
 LCD_RS=0;                   // 选中指令寄存器
 LCD_RW=0;                // 写模式 
 LCD_EN=1;     // 开启1602液晶使能端
 _nop_();     // 等待写入指令
 _nop_();
 _nop_();
 LCD_EN=0;        // 关闭1602液晶使能端
}
 //////////////////////////////////////////////////////////////////////////
函数名称:WriteDataLCD
函数功能:根据1602液晶的时序,通过单片机给1602写入想要写入的数据
参数介绍:cData:要写入1602的数据
返回值: 
注意事项:无
 //////////////////////////////////////////////////////////////////////////

void WriteDataLCD(uchar cData)
{
 ReadStatusLCD();               
 LCD_DATAPORT=cData;
 LCD_RS=1;                  // 选中数据寄存器
 LCD_RW=0;               // 写模式
 LCD_EN=1;       // 打开1602液晶使能端
 _nop_();       // 等待写入数据
 _nop_();
 _nop_();
 LCD_EN=0;       // 关闭1602液晶使能端
}
 //////////////////////////////////////////////////////////////////////////

函数名称:Initial_LCD
函数功能:设置单片机的外部中断0和中断1,具体的设置状态都为外部低电平触发,并
          且开总中断
参数介绍:无
返回值: 
注意事项:无
 //////////////////////////////////////////////////////////////////////////
void Initial_LCD()
{
   
 Digital_tube_Wei_Enable;
 LCD_DATAPORT=0xff;
 Digital_tube_Wei_Disable;

 Digital_tube_Duan_Enable;
 LCD_DATAPORT=0X00;
 DelayMs(2);
 Digital_tube_Duan_Disable;
  
 
 LCD_DATAPORT=0; 
 DelayMs(15);
 WriteCommandLCD(0x38,0);    //三次显示模式设置,不检测忙信号
 DelayMs(5);
 WriteCommandLCD(0x38,0);
 DelayMs(5);
 WriteCommandLCD(0x38,0);
 DelayMs(5);
 
 WriteCommandLCD(0x38,1);    //8bit数据传送,2行显示,5*7字型,检测忙信号
 WriteCommandLCD(0x08,1);    //关闭显示,检测忙信号
 WriteCommandLCD(0x01,1);    //清屏,检测忙信号
 WriteCommandLCD(0x06,1);    //显示光标右移设置,检测忙信号
 WriteCommandLCD(0x0c,1);    //显示屏打开,光标不显示,不闪烁,检测忙信号
}
 //////////////////////////////////////////////////////////////////////////

函数名称:DisplayOneCharLCD
函数功能:按指定位置显示一个字符,比如说数字,英文字母等
参数介绍:cXCoord:要显示字符在某一行当中的位置
       cYCoord:要显示字符在液晶中的行数,比如说第一行或第二行
    cData:  要显示的字符,比如说1、a等
返回值: 
注意事项:限制cXCoord不能大于15,cYCoord不能大于1
 //////////////////////////////////////////////////////////////////////////

void DisplayOneCharLCD(uchar cXCoord,uchar cYCoord,uchar cData)
{
 cYCoord&=1;        //取cYCoord的第一位,其他的全部设置成0      
 if(cYCoord)cXCoord|=0x40;         //若y为1,显示第一行,地址码+0X40
    cXCoord|=0x80;                    //若不为1,则显示第二行,地址码+0X80
 WriteCommandLCD(cXCoord,0);    //把写入的地址送到1602液晶
 WriteDataLCD(cData);     //写入要写入的数据
}
 //////////////////////////////////////////////////////////////////////////
函数名称:DisplayListCharLCD
函数功能:按指定位置显示一串字符,比如说显示 abcdefg,123456等
参数介绍:cXCoord:要显示字符在某一行当中的位置
    cYCoord:要显示字符在液晶中的行数,比如说第一行或第二行
    cData:  要显示的字符串,比如说123456、adcdgd等 
返回值: 
注意事项:制cXCoord不能大于15,cYCoord不能大于1
 //////////////////////////////////////////////////////////////////////////

void DisplayListCharLCD(uchar cXCoord,uchar cYCoord,uchar code *Data)
{
 uchar ListLength=0;  //要显示字符串的长度
 cYCoord&=0x01;   //取cYCoord的第一位,其他的全部设置成0
 cXCoord&=0x0f;
 while(cXCoord<16)     //循环写入要写入的字符串
 {
  DisplayOneCharLCD(cXCoord,cYCoord,Data[ListLength]);
  ListLength++;
  cXCoord++;
 }
}
 //////////////////////////////////////////////////////////////////////////
函数名称:Init_INT1
函数功能:配置外部中断1,让其为下降沿触发,同时打开全局中断
参数介绍:无
返回值: 
注意事项:无
 //////////////////////////////////////////////////////////////////////////

void Init_INT1()
{
 IT1=1; //外部中断1,为下降沿触发
 EX1=1; //允许外部中断1中断
 EA=1;  //CPU开放中断
}
 //////////////////////////////////////////////////////////////////////////

函数名称:main
函数功能:初始化外部中断1以及1602液晶,同时把预先写好的字符串显示到1602上面,
    然后进入while循环里,等待中断的发生
参数介绍:无
返回值: 
注意事项:实验板上所用的数码管为共阴极数码管
 //////////////////////////////////////////////////////////////////////////

void main()
{
 Init_INT1();   //初始化外部中断1
    
 IR=1;          //I/O口初始化
 Initial_LCD(); //初始化1602液晶
 DisplayListCharLCD(0,0,string0); //显示字符预写好的字符串
 DisplayListCharLCD(0,1,string1); //显示字符预写好的字符串
 while(1);
}
 //////////////////////////////////////////////////////////////////////////
函数名称:IR_Routine
函数功能:对红外接收头接收到的红外信号进行解码,解码后,把遥控器上的数字显示
    在数码管上
参数介绍:无
返回值: 
注意事项:具体的协议,请看光盘里所带的名为“红外控制”的数据手册
 //////////////////////////////////////////////////////////////////////////

void IR_Routine() interrupt 2
{
 unsigned char cNumber1,cNumber2,cCount=0;
 EX1 = 0;    //关闭中断
 Delay(15);
 if (IR==1)  //然后再检测红线接收脚是有数据招收,有继续,没有则退出
    {
  EX1 =1;  //打开中断
  return;  //跳出去
 }
                          
 while (!IR)           //确认IR信号出现
         //等IR变为高电平,跳过9ms的前导低电平信号。
  Delay(1);
 }

 for (cNumber1=0;cNumber1<4;cNumber1++) //收集四组数据,前两组为地址码,仅
  //仅接着是两个命令码,这是NEC公司所定义的协议里规定的
  for (cNumber2=0;cNumber2<8;cNumber2++)//每组数据有8位
  {
   while (IR)          //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
   {
    Delay(1);
   }
   while (!IR)          //等 IR 变为高电平
   {
    Delay(1);
   }
   while (IR)           //计算IR高电平时长
   {
    Delay(1);
    cCount++;          
    if (cCount>=30)
    {
     EX1=1;
     return;
         //太长了就自动推出中断服务程序
                          //高电平计数完毕               
   cIRReceiveData[cNumber1]=cIRReceiveData[cNumber1] >> 1;//数据最高位补“0”
   if(cCount>=8)  //协议里定义‘1’的电平为2.25ms,因为Delay(1)延时为0.14ms
        //加上其他指令执行时的延时,所以大于等于8时,为高电平
    cIRReceiveData[cNumber1] = cIRReceiveData[cNumber1] | 0x80;
    //数据最高位补“1”
   cCount=0;
  }//end for k
 }//end for j
 if(cIRReceiveData[2]!=~cIRReceiveData[3])//判断接收到指令是不是正确,协议里规定
 //第一次发指令和第二次发的正好的按位取反的,以此保证接收数据的可靠性
  EX1=1;
  return;
 }
 cIRReceiveData[5]=cIRReceiveData[2] & 0x0F;     //取键码的低四位
 cIRReceiveData[6]=cIRReceiveData[2] >> 4;       //右移4次,高四位变为低四位
 
 if(cIRReceiveData[5]>9) //把接收到的数据转换成1602上面能显示的ASCII码
 {       //具体请看ASCII码表,看转换的关系
  cIRReceiveData[5]=cIRReceiveData[5]+0x37;
 }
 else
  cIRReceiveData[5]=cIRReceiveData[5]+0x30;
 
 if(cIRReceiveData[6]>9)
 {
  cIRReceiveData[6]=cIRReceiveData[6]+0x37;
 }
 else
  cIRReceiveData[6]=cIRReceiveData[6]+0x30;
 
 DisplayOneCharLCD(13,1,cIRReceiveData[6]); //显示接收到数据的第一位
 DisplayOneCharLCD(14,1,cIRReceiveData[5]); //显示接收到数据的第二位
    EX1 = 1;  //打开中断,解码完成,以进行下次解码
}

关键字:STC89C52  单片机  红外遥控器解码 引用地址:STC89C52单片机红外遥控器解码

上一篇:STC89C52单片机PS2键盘解码
下一篇:STC89C52单片机驱动数码管动态显示

推荐阅读最新更新时间:2024-03-16 14:50

整合MCU和DSP优势的DSC推动绿色革命
数字信号控制器(DSC)是一种集微控制器(MCU)和数字信号处理器(DSP)专长于一身的新型处理器。与MCU一样,DSC具有快速中断响应、提供面向控制的外设(如脉宽调制器和看门狗定时器)、用C编程等特性。DSC还集成了诸如单周期乘累加(MAC)单元、桶式移位器(barrel shifter)和大的累加器等功能。 DSC适合多种应用,但主要领域还是马达控制、电源转换和传感器处理。在这些应用中使用DSC的主要动机是降低功耗。采用DSC来降低功耗的最显著成果来自将变速马达转为恒速马达。变速驱动(需DSC提供的DSP马力来实现)的能耗大约只相当恒速驱动的一半。 节能潜力巨大 由于恒速驱动的应用广泛,因此,变速驱动具有广阔的节能应用前
[焦点新闻]
STM32F1xx系列单片机通过程序获取MCU信息
在使用STM32F1xx系列单片机时可以直接在指定地址中读取单片机相关信息,在参考手册上的相关介绍如下。 通过上面的介绍可以看到,直接去这些指定地址中读取数据,就可以获取到MCU的相关信息。下来就直接通过代码去获取这些信息。 #include sys.h #include delay.h #include usart.h #include led.h u32 flash_id ; u16 flash_size; u32 mcu_id; int main( void ) { while( 1 ) { flash_size = *( unsigned int * )( 0x1FFFF
[单片机]
STM32F1xx系列<font color='red'>单片机</font>通过程序获取<font color='red'>MCU</font>信息
基于事件一目标驱动的人机界面设计
引 言   人机界面(human-computer interface),又称用户界面、人机交互、人机接口等,是人与机器之间传递、交换信息的媒介.是用户使用计算机系统的综合操作环境。在商品竞争中,一个应用系统的成功与否在某种程度上也取决于用户使用界面的感受好坏,因此,人机界面的设计在应用系统的设计中有着重要的作用。嵌入式系统强调人机界面操作的实时性,简单化,强调在特定平台上特定应用的时间空间效率。在传统的小系统设计中。程序设计一般采用前后台工作方式。应用程序是一个无限的循环,循环中调用相应的函数完成相应的操作,时间相关性很强的关键操作(crltical operation)是靠中断服务来保证的。因为中断服务提供的信息一直要等到后台
[嵌入式]
单片机常见延时与中断问题及解决方法
延时与中断出错,是单片机新手在单片机开发应用过程中,经常会遇到的问题,本文汇总整理了包含了MCS-51系列单片机、MSP430单片机、C51单片机、8051F的单片机、avr单片机、STC89C52、PIC单片机…..在内的各种单片机常见的延时与中断问题及解决方法,希望对单片机新手们,有所帮助! 扩展阅读: 单片机延时程序经验 一、单片机延时问题20问 1、单片机延时程序的延时时间怎么算的? 答:如果用循环语句实现的循环,没法计算,但是可以通过软件仿真看到具体时间,但是一般精精确延时是没法用循环语句实现的。 如果想精确延时,一般需要用到定时器,延时时间与晶振有关系,单片机系统一般常选用11.059 2 MHz、12
[单片机]
STM8S系列单片机TIM1的PWM配置与TIM2的区别
为什么STM8的PWM用TIM1不能输出,TIM2可以,下面针对TIM1的PWM输出做了下列程序代码的编写。 STM8S系列单片机 PC1管脚来控制PWM的输出,即TIM1_CH1通道 PC2管脚来控制PWM的输出,即TIM1_CH2通道 PC3管脚来控制PWM的输出,即TIM1_CH3通道 //PWM初始化 void Driver_PWMON(u8 ch,u8 Num) { //开TIM1时钟 CLK- PCKENR1 |= CLK_PCKENR1_TIM1; //设置PWM频率,Fpwm=Fmaster/TIM2_ARR //这里Fpwm = 2000000/100 = 20K
[单片机]
怎样在微控制器上刻录引导加载程序
简介 如果你正在查看这个项目,那么你可能已经使用过Arduino板了。 Arduino UNO上的ATmega328微控制器很可能在一定时间(或不正确的连接)后发生故障。为了重用Arduino Board,您需要一个装有Bootloader的新ATmega328 IC(我将在一分钟内讨论Bootloader)。 还有其他原因可以在上面刻录Bootloader ATmega328微控制器,如果你已经编写了自己的Bootloader并想要测试它,或者你想要详细了解微控制器的工作情况。 警告: 如果你不熟悉这种东西,不建议在Arduino中调整Bootloader。 什么是Bootloader? 简单来说,Bootload
[单片机]
怎样在<font color='red'>微控制器</font>上刻录引导加载程序
ARM9微控制器完成信号采集及实现上层控制算法解析方案
引言 在很多嵌入式控制系统中,系统既要完成大量的信息采集和复杂的算法,又要实现精确的控制功能。采用运行有嵌入式Linux操作系统的ARM9微控制器完成信号采集及实现上层控制算法,并向DSP芯片发送上层算法得到控制参数,DSP芯片根据获得的参数和下层控制算法实现精确、可靠的闭环控制。 1 多机系统组成 该多机控制系统以ARM9微控制器s3c2440为核心,采用I2C总线挂载多个DSP芯片TMS320F28015作为协控制器,构成整个控制系统的核心。 1.1 S3C2440及TMS320F28015简介 Samsung公司的处理器S3C2440是内部集成了ARM公司ARM920T处理器内核的32位微控制器,资源丰富,带独立的
[单片机]
ARM9<font color='red'>微控制器</font>完成信号采集及实现上层控制算法解析方案
单片机项目经验到底是什么?项目开发培训真的靠谱吗?
每次看到钢铁侠这部电影,我都肾上腺素飙升,想去撸它几千行代码发泄一下。 很多人学习和从事单片机开发都是出于兴趣,虽然现实很难达到托尼斯塔克的水平,不过能通过自己写代码去做出自己想要的东西,已经很有成就感了。 10年前,我也是一样,从点亮第一个LED开始就迷上了单片机开发,原来写程序控制硬件是这样玩的。 为此,我那段时间把游戏都戒了,我的脑子也比较天马星空,把开发板的LED点亮以后,我就想着怎么把家里的灯用程序来控制。 后面发现控制也很简单,中间加个继电器就行了。 当时我是自学转行的,只学了51这个单片机就出去找工作了,刚开始找工作的第一个月四处碰壁,凡是面试过的公司都叫我回去等通知。 等多了,我也就看开了。 最终分析了企业的需求,
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved