搜索

[技术支持] 【芯圣SDK-HC89F0541测评】+ NEC红外编码解码

[复制链接]
2032|5
 楼主 | 2020-9-13 21:33 | 显示全部楼层 |阅读模式
本帖最后由 fair2817 于 2020-9-13 21:37 编辑

非常高兴在第八波的抽奖中成为幸运者。等待几天后收到了芯圣寄出的开发板。
IMG_20200913_210021.jpg
由于以前买过芯圣的HC89S105开发板,所以已经安装过了相关驱动。拿到HC89F0541开发板后什么也不需要做了,直接开始用Keil编程测试。本次测试主要使用了定时器、外部中断及串口模块。程序直接使用它例程中的外部中断程序和原C51开发板中的部分程序,根据本次测试的具体情况做了修改移植。
将以前买的C51学习板拿出来,连上红外接收头的相关线路。
IMG_20200913_205321.jpg
用USB转串口连上PC
IMG_20200913_205341.jpg
没有使用LCD1602来显示,主要怕线太多了。直接使用串口传输数据到串口助手就可以了。
IMG_20200913_205335.jpg
一切就绪后,用遥控板向红外接收头发送数据,这是串口助手收到的数据,一切正常。
IMG_20200913_205307.jpg


很高兴正好赶上这次活动,希望芯圣越做越好。很喜欢它们的PTM功能,使用起来非常方便。


源码如下:main.c (移植于0541开发板中的外部中断程序,对串口波特率进行了相应修改)
  1. /**
  2. *   ************************************************************************************
  3. *                                                                上海芯圣电子股份有限公司
  4. *                                                                    www.holychip.cn
  5. *        ************************************************************************************
  6. *        @Examle Version                V1.0.1.0
  7. *        [url=home.php?mod=space&uid=1102]@demo[/url]        Version                V1.0.4.0
  8. *        [url=home.php?mod=space&uid=212281]@date[/url]                                2018.5.10
  9. *        ************************************************************************************
  10. *                                                                         模块性能介绍
  11. *        1、MCU总共提供了26个外部中断,可以设置4级中断的优先级。
  12. *        2、有4个外部中断向量入口,INT0/INT1分别有一个独立的中断向量入口,INT2-7共用一个中断
  13. *           向量入口,INT8-17共用一个中断向量入口。
  14. *        3、INT0-17中断都可以设定4种触发方式,分别为上升沿、下降沿、双沿以及低电平。
  15. *        4、INT0、INT1中断标志位硬件自动清0,INT2-INT17需软件清0。
  16. *        5、P2口中断仅可以设置为下降沿中断,并且只有一个标志位。
  17. *        ************************************************************************************
  18. *                                                                         应用注意事项
  19. *        1、只要相应的EINTx(x=2...15)被允许,对应的中断标志就可能被置1,反之,对应标志不会被
  20.            置1。
  21. *        2、外部中断在使用查询方式时,无法正常清除中断标志位。可以通过先禁止中断使能位再清除
  22. *           中断标志,在完成清除中断标志位后再使能外部中断来进行正常的外部中断产生查询。使用
  23. *           中断方式时,无该问题。
  24. *        ************************************************************************************
  25. *                                                                         客户服务
  26. *        感谢您使用我们的单片机,若发现错误或对函数的使用存在疑问。请添加上海芯圣电子官方QQ群
  27. *        ****************************技术支持群:201030494***********************************
  28. *   ************************************************************************************
  29. **/

  30. #define        ALLOCATE_EXTERN
  31. #include "HC89F0541.h"
  32. #include "ir.h"

  33. /***************************************************************************************
  34.   * 实始化UART1的要关配置
  35. ***************************************************************************************/
  36. void UART1_Init()
  37. {
  38.         P1M6 = 0xC2;                                        //P16设置为推挽输出
  39.         P1M7 = 0x62;                                        //P17设置为上拉输出
  40.         TXD_MAP = 0x16;                                                //TXD映射P16
  41.         RXD_MAP = 0x17;                                                //RXD映射P17               
  42.         T4CON = 0x06;                                                //T4工作模式:UART1波特率发生器
  43.   TH4 = 0xFF;
  44.         TL4 = 0x98;                                                        //波特率9600
  45.         SCON2 = 0x02;                                                //8位UART,波特率可变
  46.         //SCON = 0x10;             //允许串行接收
  47.         //IE |= 0x10;                                                        //使能串口中断
  48. }

  49. void INT0_Init()
  50. {
  51.         P0M0 = 0x69;                                        //P00设置为带SMT上拉输入
  52.         PITS0 |= 0x01;                                                //INT0下降沿
  53.         IE |= 0x01;                                                        //打开INT0中断
  54. }

  55. void TIMER0_Init()
  56. {
  57.         TMOD |= 0x00; //定时器0工作方式0,16位自动重装
  58.         TCON1 |= 0x01;   //使用fcpu / 1
  59.         TH0 = 0xEE;  //根据红外程序和0541定时器模块进行了修改,278us一次中断
  60.         TL0 = 0xA0;
  61.         ET0 = 1;           //定时器0中断
  62.         TR0 = 1;     //启动定时器0
  63. }

  64. void main()
  65. {
  66.         uchar i;
  67. /************************************系统初始化****************************************/
  68.         CLKSWR = 0x51;                                                //选择内部高频RC为系统时钟,内部高频RC 2分频,Fosc=16MHz
  69.         CLKDIV = 0x01;                                                //Fosc 1分频得到Fcpu,Fcpu=16MHz
  70.         INT0_Init();
  71.         UART1_Init();
  72.         TIMER0_Init();
  73.         EA = 1;                                                                //打开总中断
  74.         while(1)
  75.         {
  76.                 if(IRok)                //外部中断处理完接收的32位红外数据
  77.                 {
  78.                         IRok = 0;
  79.                         IRcordpro();  //处理字节
  80.                         if(IRpro_ok)          //如何成功处理,然后通过UART发送出去
  81.                         {
  82.                                 IRpro_ok = 0;
  83.                                 for(i=0;i<4;i++)
  84.                                 {
  85.                                         SBUF = IRcord[i];
  86.                                         while(!TI);
  87.                                         TI = 0;
  88.                                 }
  89.                         }
  90.                 }
  91.         }
  92. }
复制代码
红外处理程序:ir.h  (移植于原开发板中的部分程序)
  1. /*====================================
  2. 硬件接口位声明
  3. ====================================*/

  4. uchar IRtime;                 //检测红外高电平持续时间(脉宽)
  5. uchar IRcord[4];    //此数组用于储存分离出来的4个字节的数据(用户码2个字节+键值码2个字节)
  6. uchar IRdata[33];   //此数组用于储存红外的33位数据(第一位为引导码用户码16+键值码16)
  7. bit IRpro_ok, IRok;  //第一个用于红外接收4个字节完毕。IRok用为检测脉宽完毕


  8. void time0() interrupt TIMER0_VECTOR   //定义定时器0
  9. {
  10.         IRtime++;                            //检测脉宽,1次为278us

  11. }



  12. /***************************************************************************************
  13.   * @说明          INT0中断服务函数    用于处理红外的各个电平
  14.   *        @参数        无
  15.   * @返回值 无
  16.   * @注                无
  17. ***************************************************************************************/

  18. void int0() interrupt INT0_VECTOR                          //定义外部中断0
  19. {
  20.         static uchar i;                                 //        声明静态变量(在跳出函数后在回来执行的时候不会丢失数值)i用于把33次高电平的持续时间存入IRdata
  21.         static bit startflag;                //开始储存脉宽标志位
  22.         if(startflag)                                 //开始接收脉宽检测
  23.         {
  24.                 if( (IRtime < 53) && (IRtime >= 32) ) /*判断是否是引导码,底电平9000us+高4500us        
  25.                 这个自己可以算我以11.0592来算了NEC协议的引导码低8000-10000+高4000-5000
  26.                 如果已经接收了引导码那么i不会被置0就会开始依次存入脉宽*/
  27.                         i = 0;                                 //如果是引导码那么执行i=0把他存到IRdata的第一个位
  28.                 IRdata[i] = IRtime;                   //以T0的溢出次数来计算脉宽,把这个时间存到数组里面到后面判断
  29.                 IRtime = 0;                                 //计数清零,下一个下降沿的时候在存入脉宽
  30.                 i++;                                          //计数脉宽存入的次数
  31.                 if(i == 33)                                  //如果存入34次 数组的下标是从0开始i等于33表示执行了34次
  32.                 {
  33.                          IRok = 1;                                 //那么表示脉宽检测完毕
  34.                         i = 0;                                  //把脉宽计数清零准备下次存入
  35.                 }
  36.         }
  37.         else                  
  38.         {
  39.                 IRtime = 0;                                  //引导码开始进入把脉宽计数清零开始计数
  40.                 startflag = 1;                         //开始处理标志位置1
  41.         }
  42. }


  43. void IRcordpro()                                    //提取它的33次脉宽进行数据解码
  44. {
  45.         uchar i, j, k, cord, value;        /*i用于处理4个字节,j用于处理一个字节中每一位,k用于33次脉宽中的哪一位
  46.         cord用于取出脉宽的时间判断是否符合1的脉宽时间*/
  47.         k = 1;                                                 //从第一位脉宽开始取,丢弃引导码脉宽
  48.         for(i = 0; i < 4; i++)
  49.         {
  50.                 for(j = 0; j < 8; j++)
  51.                 {
  52.                         cord = IRdata[k];            //把脉宽存入cord
  53.                         if(cord > 5)                         //如果脉宽大于我11.0592的t0溢出率为约278us*5=1390那么判断为1
  54.                         value = value | 0x80;        /*接收的时候是先接收最低位,
  55.                         把最低位先放到value的最高位在和0x08按位或一下
  56.                         这样不会改变valua的其他位的数值只会让他最高位为1*/
  57.                         if(j < 7)
  58.                         {
  59.                                 value = value >> 1;        //value位左移依次接收8位数据。
  60.                         }
  61.                         k++;                                //每执行一次脉宽位加1
  62.                 }
  63.                 IRcord[i] = value;           //每处理完一个字节把它放入IRcord数组中。
  64.                 value = 0;                            //清零value方便下次在存入数据
  65.         }
  66.         IRpro_ok = 1;                                   //接收完4个字节后IRpro ok置1表示红外解码完成        
  67. }
复制代码


使用特权

评论回复
| 2020-9-14 10:15 | 显示全部楼层
谢谢分享【 NEC红外编码解码】

使用特权

评论回复
| 2020-9-14 12:54 | 显示全部楼层
路过路过!

使用特权

评论回复
| 2020-9-17 12:38 | 显示全部楼层
这个开发板做的很漂亮呀,不错的,应该很好地。

使用特权

评论回复
| 2020-9-17 19:12 | 显示全部楼层
希望芯圣越做越好。很喜欢它们的PTM功能,使用起来非常方便。

使用特权

评论回复
| 2020-9-19 13:51 | 显示全部楼层
谢谢分享

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表