找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5724|回复: 7
收起左侧

stc8a8k64s4a12单片机红外解码LCD1602显示程序

  [复制链接]
ID:505284 发表于 2019-6-20 08:59 | 显示全部楼层 |阅读模式
                                                                              stc8a8k64s4a12红外解码LCD1602显示
    在原来解码数码管的程序上修复了8位LED灯初始显示任意值bug,新增加了解码显示到LCD屏幕与pc串口端完全同步,可以通过三种有效解码方式更加精确的对支持NEC协议的所有红外遥控设备解码,此外对于其他型号及平台移植更为方便,希望有用到的 积极下载共享,有好的独特想法的可以提出来共同讨论,积极指正批评。
P90620-085340.jpg P90620-085349.jpg
单片机源程序如下:
  1. ////////////////////////////////////////////////////////////
  2. //   红外接收数据,查询方式,并通过串口发送输出  
  3. //   晶振:22.1184MHz         ,波特率:9600
  4. ////////////////////////////////////////////////////////////
  5. #include <STC8.H>
  6. #include "LCD1602.h"
  7. #define  LED P0
  8. sbit Ir_Pin = P2^7;             // 红外接收头信号输出脚
  9. extern delay(uint time);
  10. uchar code lhc_table[16]="0123456789ABCDEF";
  11. uchar tempdata[16];
  12. uchar Ir_Buf[4]; // 用于保存解码结果(Ir_Buf[0]--用户码L,Ir_Buf[3] --键反码)

  13. // 获取低电平时间 (其实是16位计数器的计数值,STC15系列定时器默认为16位自动重装方式)
  14. uint Ir_Get_Low()
  15. {
  16.         TL0 = 0;                 // 清空16位计数器0
  17.         TH0 = 0;                 // 清空16位计数器0
  18.         TR0 = 1;                 // 计数器0开始运行
  19.         while (!Ir_Pin && (TH0<0x80));          // 信号引脚变成高或低电平时间>17ms退出(只要>12ms即可)
  20.                                       // 0x8000=32768,  32768*0.54253uS=17777.62 uS            
  21.         TR0 = 0;                          // 这里 ! 优先级大于&&     
  22.         return (TH0 * 256 + TL0);                  // 返回16位计数器的计数值。
  23. }

  24. // 获取高电平时间(其实是16位计数器的计数值,STC15系列定时器默认为16位自动重装方式)
  25. uint Ir_Get_High()
  26. {
  27.         TL0 = 0;                    // 清空16位计数器0
  28.         TH0 = 0;                    // 清空16位计数器0
  29.         TR0 = 1;
  30.         while (Ir_Pin && (TH0<0x40));           // 信号引脚变成低电平或高电平时间>17ms退出
  31.         TR0 = 0;
  32.         return (TH0 * 256 + TL0);
  33. }  

  34. void UART_init(void)                      // 9600@22.1184MHz
  35. {                  
  36.         //下面代码设置定时器1
  37.         TMOD = 0x20;           // 0010 0000 定时器1工作于方式2(8位自动重装方式)
  38.         TH1  = 0xFA;           // 波特率:57600 /22.1184MHZ
  39.         TL1  = 0xFA;           // 波特率:57600 /22.1184MHZ
  40.         TR1  = 1;
  41.         //下面代码设置定串口
  42.         AUXR = 0x00;             // 很关键,使用定时器1作为波特率发生器,S1ST2=0
  43.         SCON = 0x50;         // 0101 0000 SM0.SM1=01(最普遍的8位通信),REN=1(允许接收)
  44. }        

  45. //  UART发送一字节        
  46. void UART_Send_Byte(uchar dat)
  47. {
  48.         SBUF = dat;
  49.         while (TI == 0);
  50.         TI = 0;             // 此句可以不要,不影响后面数据的发送,只供代码查询数据是否发送完成
  51. }

  52. void IR_work()  //红外解码程序
  53. {
  54.         tempdata[0]=lhc_table[Ir_Buf[0]/16];   //处理客户码
  55.         tempdata[1]=lhc_table[Ir_Buf[0]%16];
  56.         tempdata[2]='-';
  57.         tempdata[3]=lhc_table[Ir_Buf[1]/16];  //处理客户码
  58.         tempdata[4]=lhc_table[Ir_Buf[1]%16];
  59.         tempdata[5]='-';
  60.         tempdata[6]=lhc_table[Ir_Buf[2]/16];  //处理数据码
  61.         tempdata[7]=lhc_table[Ir_Buf[2]%16];
  62.         tempdata[8]='-';
  63.         tempdata[9]=lhc_table[Ir_Buf[3]/16];  //处理数据反码
  64.         tempdata[10]=lhc_table[Ir_Buf[3]%16];
  65.         LCD_write_string(5,1,tempdata);
  66.         LED=~Ir_Buf[2];
  67. }

  68. void main()
  69. {
  70.         uint time;
  71.         uchar i,j;
  72.         LED=0xff;
  73.         UART_init();
  74.         UART_Send_Byte(0X55);                // 测试串口工作是否正常
  75.         LCD_init();
  76.         delay(20);         //延时有助于稳定
  77.         LCD_clear();
  78.         
  79.         LCD_write_string(0,0,"LHC-DIY-STC8");
  80.         LCD_write_string(0,1,"code:");
  81.         while (1)
  82.         {
  83. start:
  84.                 ///////////// 接收同步信号 ///////////
  85.                 while (Ir_Pin);                    // 等待低电平出现
  86.                 time = Ir_Get_Low();        // 低电平区间16位计数器的计数值
  87.                 if ((time < 15667) || (time > 17510))   goto start;        
  88.                                                         // 引导脉冲低电平8500~9500us,T=12/22.1184=0.54253uS
  89.                                                         // 8500/0.54253uS=15667.3    9500/0.54253uS=17510.5
  90.                 time = Ir_Get_High();
  91.                 if ((time < 7372) || (time > 9216))  goto start;   // 引导脉冲高电平4000-5000us
  92.                                                                                      // 4000/0.54253uS=7372.8    5000/0.54253uS=9216
  93.                 ////////// 接收后续的4 字节数据        ////////
  94.                 for (i=0; i<4; i++)                  // 4个字节
  95.                 {
  96.                         for (j=0; j<8; j++)              // 每个字节8位
  97.                         {
  98.                                 time = Ir_Get_Low();                 // 接收每位560us 低电平
  99.                                 if ((time < 626) || (time > 1438))   goto start;                 // 340-780us
  100.                                                                                  // 340/0.54253uS=626.7    780/0.54253uS=1437.7
  101.                                 time = Ir_Get_High();                    // 接收每位560us或1690us高电平时间
  102.                                 if ((time>626) && (time<1438))  // 时间范围为340-780us(中心值560us),
  103.                     {
  104.                          Ir_Buf[i] >>= 1;                // 因低位在先,所以数据右移,移入的最高位为0
  105.                                 }
  106.                     else if ((time>2728) && (time<3502))
  107.                 {                           // 时间判定范围为1480~1900us(中心值1690us)
  108.                                                                             // 1480/0.54253uS=2727.9   1900/0.54253uS=3502.1
  109.                                         Ir_Buf[i] >>= 1;                // 因低位在先,所以数据右移,移入的最高位为0
  110.                                         Ir_Buf[i] |= 0x80;          // 最高位置1
  111.                                 }
  112.                     else                            // 不在上述范围内则说明为误码,直接退出
  113.                                 {
  114.                                         goto start;        
  115.                                 }
  116.                         }
  117.                 }
  118.                 UART_Send_Byte(Ir_Buf[0]);                // 用户码低字节
  119.                 UART_Send_Byte(Ir_Buf[1]);                // 用户码高字节
  120.                 UART_Send_Byte(Ir_Buf[2]);                // 键码
  121.                 UART_Send_Byte(Ir_Buf[3]);                // 键反码
  122.                 IR_work();
  123.         }
  124. }  
复制代码

所有资料51hei提供下载:
03 LCD1602显示.7z (33.15 KB, 下载次数: 144)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:149992 发表于 2021-2-5 14:44 | 显示全部楼层
谢谢共享!,努力赚黑币!
回复

使用道具 举报

ID:675308 发表于 2021-2-8 08:53 来自手机 | 显示全部楼层
用stc8F系列的行吗?
回复

使用道具 举报

ID:151533 发表于 2021-3-27 03:21 | 显示全部楼层
谢谢共享!下载了学习一下
回复

使用道具 举报

ID:74143 发表于 2022-4-23 17:13 | 显示全部楼层
移植到STC15W408AS无显示。
回复

使用道具 举报

ID:378617 发表于 2022-9-12 02:55 | 显示全部楼层
8952还能用吗
回复

使用道具 举报

ID:137736 发表于 2022-9-12 08:43 | 显示全部楼层
很好,下来调试一下
回复

使用道具 举报

ID:961114 发表于 2022-9-14 08:47 | 显示全部楼层
现在STC有DMA 直接支持 TFT接口I8080/MC6800方式并口刷屏,
TFT480*320, TFT320*240的 GUI 有 (uGFX + FreeRTOS) 在 32位8051, 
STC32G12K128上实现的开源案例!

或者先在 STC-ISP V6.90I 以上版本的 软件的 调试接口中显示部分显示
有: OLED128*64虚拟显示,  OLED320*240虚拟显示
有: 示波器TFT320*240虚拟显示,TFT480*320虚拟显示

还有虚拟键盘/按键, USB-CDC/就是串口
显示OLED12864很实用, STC 网站上 有 开源的 GUI/OLED12864, U8g2 在 32位 8051, STC32G12K128 上的实现,还有   GUI/U8g2-OLED12864 + FreeRTOS 在 STC32G12K128 上实现的例程,有DMA支持的 SPI/I2C 涮 OLED12864, MCU 无任何负担! TFT480*320, TFT320*240的 GUI 有 (uGFX + FreeRTOS) 在 32位8051, STC32G12K128上实现的开源案例,DMA 直接支持 TFT接口I8080/MC6800方式并口刷屏
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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