查看: 1934|回复: 7

[原创] 逐飞科技LPC55S69_IOT小板评测之PWM红外发射篇

[复制链接]
  • TA的每日心情
    开心
    2020-12-17 09:04
  • 签到天数: 346 天

    [LV.8]以坛为家I

    19

    主题

    94

    帖子

    3

    金牌会员

    Rank: 6Rank: 6

    积分
    1361
    最后登录
    2024-1-15
    发表于 2020-11-2 12:42:06 | 显示全部楼层 |阅读模式
      最近比较忙再加上手里面也没有什么东西好更的了,摄像头和显示屏已经有童鞋做过了,笔者这里也不好意思再来过多描述,正好今天项目要用到38K的红外波来优化之前的程序,因为之前的红外的发射是用STM32F1做的,正好用LPC55S69来试试,话不多说接下来开整。


    一、选择定时器来匹配PWM波
      LPC55S69有众多的定时器资源,这里结合SDK选择了ctimer来开展。首先来了解一下红外知识点。红外遥控的编码目前广泛使用的是:NEC Protocol 的 PWM(脉冲宽度调制)和 Philips RC-5 Protocol 的 PPM(脉冲位置调制)。这里使用的是 NEC 协议,其特征如下:
    1、8 位地址和 8 位指令长度;
    2、地址和命令 2 次传输(确保可靠性)
    3、PWM 脉冲位置调制,以发射红外载波的占空比代表“0”和“1”;
    4、载波频率为 38Khz;
    5、位时间为 1.125ms 或 2.25ms;
    NEC 码的位定义:一个脉冲对应 560us 的连续载波,一个逻辑 1 传输需要 2.25ms(560us
    脉冲+1680us 低电平),一个逻辑 0 的传输需要 1.125ms(560us 脉冲+560us 低电平)。而遥控
    接收头在收到脉冲的时候为低电平,在没有脉冲的时候为高电平,这样,我们在接收头端收到
    的信号为:逻辑 1 应该是 560us 低+1680us 高,逻辑 0 应该是 560us 低+560us 高。
    NEC 遥控指令的数据格式为:同步码头、地址码、地址反码、控制码、控制反码。同步码
    由一个 9ms 的低电平和一个 4.5ms 的高电平组成,地址码、地址反码、控制码、控制反码均是
    8 位数据格式。按照低位在前,高位在后的顺序发送。采用反码是为了增加传输的可靠性(可
    用于校验)。
    1.jpg
    从图 33.1.1 中可以看到,其地址码为 0,控制码为 168。可以看到在 100ms 之后,我们还收到了几个脉冲,这是 NEC 码规定的连发码(由 9ms 低电平+2.5m 高电平+0.56ms 低电平+97.94ms 高电平组成)。


    二、初始化定时器
      
    1. #include "ctimer.h"
    2. #include "fsl_ctimer.h"
    3. #include "delays.h"

    4. volatile uint32_t g_pwmPeriod   = 0U;
    5. volatile uint32_t g_pulsePeriod = 0U;

    6. status_t CTIMER_GetPwmPeriodValue(uint32_t pwmFreqHz, uint16_t dutyCyclePercent, uint32_t timerClock_Hz)
    7. {
    8.     /* Calculate PWM period match value */
    9.     g_pwmPeriod = (timerClock_Hz / pwmFreqHz) - 1;  //

    10.     /* Calculate pulse width match value */
    11.     g_pulsePeriod = (g_pwmPeriod + 1U )* (100 - dutyCyclePercent) / 100;

    12.     return kStatus_Success;
    13. }

    14. void Ctimer_Config(uint32_t PwmFreqHz, uint16_t DutyCyclePercent)
    15. {
    16.           ctimer_config_t config;
    17.     uint32_t srcClock_Hz;
    18.     uint32_t timerClock;
    19.           /* Use 12 MHz clock for some of the Ctimers */
    20.     CLOCK_AttachClk(kFRO_HF_to_CTIMER2);
    21.           /* CTimer0 counter uses the AHB clock, some CTimer1 modules use the Aysnc clock */
    22.     srcClock_Hz = CTIMER_CLK_FREQ;
    23.           CTIMER_GetDefaultConfig(&config);
    24.           timerClock = srcClock_Hz / (config.prescale + 1);
    25.           CTIMER_Init(CTIMER, &config);
    26.        
    27.           /* Get the PWM period match value and pulse width match value of 20Khz PWM signal with 20% dutycycle */
    28.     CTIMER_GetPwmPeriodValue(PwmFreqHz, DutyCyclePercent, timerClock);
    29.     CTIMER_SetupPwmPeriod(CTIMER, CTIMER_MAT_OUT, g_pwmPeriod, g_pulsePeriod, false);
    30.     CTIMER_StartTimer(CTIMER);
    31. }
    复制代码
    选择的16的定时器timer2,选择的时钟为端口12MHz,载波位38KHz,所谓一切的发送都是为了和接收配合,这里的38K是因为接收波段是38K,所以才这样去设置的。

    三、载波的发送
      上述协议这里有了大概的理解了,那如何发送1,0这样的高低波段呢,这样联系PWM和延时做了一个发送机制,经测试非常的稳定。
    1. void send_0(void)
    2. {
    3.          uint16_t  pwm_width;       
    4.    pwm_width=100;
    5.          Ctimer_Config(Ir_Pwm, pwm_width);
    6.          delay_us(560);       
    7.    pwm_width=0;
    8.    Ctimer_Config(Ir_Pwm, pwm_width);  //占空比为0,即不发送红外信号
    9.    delay_us(560);                    //数据"0"的发送过程       
    10. }

    11. void send_1(void)
    12. {
    13. uint16_t  pwm_width;
    14. pwm_width=100;
    15. Ctimer_Config(Ir_Pwm, pwm_width);
    16. delay_us(560);
    17. pwm_width=0;
    18. Ctimer_Config(Ir_Pwm, pwm_width);  
    19. delay_us(1680);     //数据"1"的发送过程
    20. }


    21. void Send_Data(uint8_t data)        //一次一个字节
    22. {
    23.   uint8_t i,temp;
    24.        
    25.         Ctimer_Config(Ir_Pwm,100);      
    26.         delay_us(9000);             //9ms高电平
    27.         Ctimer_Config(Ir_Pwm,0);
    28.         delay_us(4500);             //4.5ms低电平  同步码
    29.                
    30.         for(i=0;i<8;i++)        //键值,一位一位的发
    31.         {
    32.                 temp=(data&0x80);   
    33.                 if(temp)send_1();       
    34.                 else send_0();
    35.                 data<<=1;
    36.         }
    37.         Ctimer_Config(Ir_Pwm,100);      
    38.         delay_us(560);             //9ms高电平
    39.         Ctimer_Config(Ir_Pwm,0);
    40.         delay_us(4500);             //4.5ms低电平  同步码
    41. }
    复制代码

    四、发射原理设计及其实验验证
       2.png
    3.png
      经接收装置检测,接收信号为0x3A。


    哎...今天够累的,签到来了~
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2020-12-17 09:04
  • 签到天数: 346 天

    [LV.8]以坛为家I

    19

    主题

    94

    帖子

    3

    金牌会员

    Rank: 6Rank: 6

    积分
    1361
    最后登录
    2024-1-15
     楼主| 发表于 2020-11-2 13:29:37 | 显示全部楼层
                    const uint32_t port1_pin4_config = (/* Pin is configured as CTIMER2_MAT1 */
                                            IOCON_PIO_FUNC3 |
                                            /* No addition pin function */
                                            IOCON_PIO_MODE_INACT |
                                            /* Standard mode, output slew rate control is enabled */
                                            IOCON_PIO_SLEW_STANDARD |
                                            /* Input function is not inverted */
                                            IOCON_PIO_INV_DI |
                                            /* Enables digital function */
                                            IOCON_PIO_DIGITAL_EN |
                                            /* Open drain is disabled */
                                            IOCON_PIO_OPENDRAIN_DI);
        /* PORT1 PIN4 (coords: 1) is configured as CTIMER2_MAT1 */
        IOCON_PinMuxSet(IOCON, 1U, 4U, port1_pin4_config);
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2016-12-2 08:40
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    97

    主题

    836

    帖子

    7

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    3967
    最后登录
    2024-4-16
    发表于 2020-11-2 22:03:23 | 显示全部楼层
    俺们今天发布了LPC550x系列,8毛美金的Cortex-M33,划人民币6.4元吧,缺货的看过来
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2020-12-17 09:04
  • 签到天数: 346 天

    [LV.8]以坛为家I

    19

    主题

    94

    帖子

    3

    金牌会员

    Rank: 6Rank: 6

    积分
    1361
    最后登录
    2024-1-15
     楼主| 发表于 2020-11-3 08:58:22 | 显示全部楼层
    mgn 发表于 2020-11-2 22:03
    俺们今天发布了LPC550x系列,8毛美金的Cortex-M33,划人民币6.4元吧,缺货的看过来 ...

    已经看了过去
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2021-11-4 13:30
  • 签到天数: 47 天

    [LV.5]常住居民I

    3

    主题

    167

    帖子

    0

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    379
    最后登录
    2024-4-16
    发表于 2020-11-3 11:48:49 | 显示全部楼层
    可能可以试试看连个wifi模块之类的
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2020-12-17 09:04
  • 签到天数: 346 天

    [LV.8]以坛为家I

    19

    主题

    94

    帖子

    3

    金牌会员

    Rank: 6Rank: 6

    积分
    1361
    最后登录
    2024-1-15
     楼主| 发表于 2020-11-3 16:55:50 | 显示全部楼层
    leo01 发表于 2020-11-3 11:48
    可能可以试试看连个wifi模块之类的
    1. void Ir_Test(void)     
    2. {
    3.         uint8_t miss_count;
    4.   uint8_t key1=0,key2=0;
    5.        
    6.         while(key1!=0x3A && key2!=0x3A)       
    7.         {
    8.                 key1=IR_Scan1();                                              //刷新红外信息指令
    9.                 key2=IR_Scan2();       
    10.                 Delay_ms(150);
    11.                 miss_count++;
    12.     if(miss_count>=3)       
    13.       break;
    14.         }
    15.                                 
    16.         if(key1==0x3A && key2==0x3A)                                  //两个红外接收均正常   
    17.         {
    18.           memset(IR_code_data,0,IRCODE_DATA_LENGTH);
    19.                 memcpy(IR_code_data,IR_REMOTE_ALL,6);
    20.                 epd_display_hanzi_32x32(0,104,IR_code_data,6);              //显示红外,由红外接收来触发对应信息的显示      //全
    21.         }       
    22.        
    23.         else if(key1!=0x3A && key2!=0x3A)
    24.         {
    25.                 memset(IR_code_data,0,IRCODE_DATA_LENGTH);
    26.                 memcpy(IR_code_data,IR_REMOTE_NONE,6);
    27.                 epd_display_hanzi_32x32(96,104,IR_code_data,6);                   //显示红外,由红外接收来触发对应信息的显示      //无
    28.                 Ir_Error=true;
    29.         }       
    30.          
    31.          else if(key1!=0x3A || key2!=0x3A)
    32.          {                         
    33.                         if((key1!=0x3A && key2==0x3A) || (key2!=0x3A && key1==0x3A))
    34.                         {
    35.                                 memset(IR_code_data,0,IRCODE_DATA_LENGTH);
    36.                                 memcpy(IR_code_data,IR_REMOTE_HALF,6);
    37.                                 epd_display_hanzi_32x32(64,104,IR_code_data,6);                      //显示红外,由红外接收来触发对应信息的显示                         //半
    38.                                 Ir_Error=true;       
    39.                         }               
    40.                        
    41.          }                            
    42. }
    复制代码
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2020-12-17 09:04
  • 签到天数: 346 天

    [LV.8]以坛为家I

    19

    主题

    94

    帖子

    3

    金牌会员

    Rank: 6Rank: 6

    积分
    1361
    最后登录
    2024-1-15
     楼主| 发表于 2020-11-3 16:56:25 | 显示全部楼层
    leo01 发表于 2020-11-3 11:48
    可能可以试试看连个wifi模块之类的

    写了一个接收程序响应函数,校验这个码
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2020-12-17 09:04
  • 签到天数: 346 天

    [LV.8]以坛为家I

    19

    主题

    94

    帖子

    3

    金牌会员

    Rank: 6Rank: 6

    积分
    1361
    最后登录
    2024-1-15
     楼主| 发表于 2020-11-3 17:08:14 | 显示全部楼层
    这里是两个红外进行接收,都是OK的
    1604394420(1).png
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-19 23:41 , Processed in 0.144957 second(s), 26 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

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