美文网首页
在SDK10的SD-LOW POWER PWM例程中增加PWM功

在SDK10的SD-LOW POWER PWM例程中增加PWM功

作者: zldiy | 来源:发表于2017-12-17 21:56 被阅读0次

    这段时间写的程序较少,期间或多或少的会忘记一些程序编写方法;正好这段时间新进了一套51822的开发板,再折腾一下这个芯片。
    折腾对象:SDK中提供的Low-power PWM library 和 PWM library;
    过程:
    1. 首先看SDK提供的文档,对程序有个大概的了解;
    2. 再对SDK中提供例程做实验,来验证文档中的所讲的内容,最主要的还
    是库文件的使用方法;
    3.将两个例程做混合 ,目的在一个芯片上实现两个不同功能的PWM。


    前两部分都是理解的过程,而且分开实验时的例程直接使用就行,不涉及到修改和新建工程的程序。
    而在第三步时,编译时会出现各种各样的错误,需要自己一个个的去解决。
    实验过程: 在Low-Power PWM例程中增加PWM功能。
    1. 在Low-power PWM 工程中的nRF_librares 中添加 app_pwm.c文件。
    2. 在main.c文件中增加头文件加载项 #include “app_pwm.h”

    APP_PWM_INSTANCE(PWM_25K,1); // Create the instance "PWM_25K" using TIMER1.instance
    //---------------------------------------------
    //- PWM_25HZ init
    //---------------------------------------------
    void pwm_25hz_init(void)
    {
         uint32_t err_code;
         app_pwm_config_t pwm_25khz_cfg = APP_PWM_DEFAULT_CONFIG_1CH(5000L,BSP_LED_1);
         pwm_25khz_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_HIGH;
         err_code = app_pwm_init(&PWM_25K,&pwm_25khz_cfg,pwm25khz_ready_callback);
         APP_ERROR_CHECK(err_code);
         app_pwm_enable(&PWM_25K);
         app_pwm_channel_duty_set(&PWM_25K, 0, 2500);
    }
    
    //建立初始化PWM函数后,也需要在MAIN函数中调用才行。
    
    
    3. 编译程序,提示错误:找不到头文件 ```nrf_drv_timer.h;nrf_drv_gpiote.h;nrf_drv_ppi.h```
     解决办法:在option for target 选项的C/C++中增加对应的目录:
    
    ..\..\..\components\libraries\pwm
    ..\..\..\components\drivers_nrf\timer
    ..\..\..\components\drivers_nrf\ppi
    ..\..\..\components\drivers_nrf\gpiote
    
    1. 添加目录后依然有一下多项错误
    ..\..\..\..\..\..\components\libraries\pwm\app_pwm.c(57): error:  #94-D: the size of an array must be greater than zero
    

    意思好像是定义的一个数组是0,不允许数组为0个成员。因此继续查找错误的根源,发现 nrf_drv_config.h 中的一些宏定义都是零,也就是没有使能相关的外设,作如下更改:

    #define TIMER1_ENABLED 0   ->  #define TIMER1_ENABLED 1
    

    PWM库介绍文档中提到TIMER0给SD使用了,所以在app中不可以再使用TIMER0 而只用一个pwm就可以,因此选择使能 timer1
    根据文档中介绍也要用的GPIOTE功能,因此也需要将改功能使能:

       #define GPIOTE_ENABLED 0 -> #define GPIOTE_ENABLED 1
    

    修改完成后再做编译 上面的error被清除,但是还有另外一个错误出现了:

    .\_build\nrf51422_xxac_s110.axf: Error: L6218E: Undefined symbol nrf_drv_timer_capture_get (referred from app_pwm.o).
    

    未定标示符,开始在工程中满世界的找 nrf_drv_timer_capture_get 在现有的工程中确实没有多以上标示符的定义,后来再到PWM的实例中,查找该标示符,终于发现还是缺少一个源程序文件:nrf_drv_timer .c 文件;将该源程序添加到 driver目录下,再次编译程序。顺利通过。

    以上的内容只是笔记,其中记录的在一个程序中增加两外一个功能的方法,以及遇到编译出错时,如何排除错误。
    一、 没有在工程中添加头文件的路径
    二、 没有在工程中添加对应的源程序文件,也可以理解为外设驱动源程序。
    三、没有在对应的配置文件中使能某些对应功能。

    比较笨的办法:在实例程序中,去对比查找故障所在位置。主要是函数定义是在那个驱动源程序中?那些外设需要使能定义,在哪里定义?都可以在SDK的外设实例程序中找到对应的解决办法(对比差异)。

    大概就这些。


    低功耗PWM和PWM库中,函数的应用是不相同的,这都是今天在实际写程序时发现的,也是因为自己之前不注意仔细阅读文档的结果。
    区别1: 两种pwm在初始化时的不同

    //------------------------高速PWM初始化函数-------------------------
         app_pwm_config_t pwm_25khz_cfg = APP_PWM_DEFAULT_CONFIG_1CH(50L,BSP_LED_2);
         pwm_25khz_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_HIGH;
         err_code = app_pwm_init(&PWM_25K,&pwm_25khz_cfg,pwm25khz_ready_callback); 
    //- PWM配置函数输入变量50L表示50us的周期,单位是us;最小5us
    //- 设置为单通道单输出模式;BSP_LED_2 将该IO端口配置为PWM信号输出端口
    //- 设置输出端口的polarity 配置为高电平有效
    //- init 中的回调函数是在完成占空比设定并且成功后再被调用的函数。
    //- PWM callback that is executed when a PWM duty change has been completed.
    
    //---------------------------------低功耗PWM初始化函数--------------------------
        APP_TIMER_DEF(lpp_timer_0);
        low_power_pwm_config.active_high = false;
        low_power_pwm_config.period = 255;
        low_power_pwm_config.bit_mask = BSP_LED_0_MASK;
        low_power_pwm_config.p_timer_id = &lpp_timer_0;
        
        err_code = low_power_pwm_init((&low_power_pwm_0), &low_power_pwm_config, test_lpwm0_handler);
        APP_ERROR_CHECK(err_code);
    /*
    | bool   [active_high] | 输出端口有效电平设定
    | uint8_t  [period] |  实际的定时时间单位不明确。
    | uint32_t   [bit_mask]| 哪个端口设定为PWM输出
    | [app_timer_id_t]const *  | [p_timer_id]|  PWM实例
    回调函数是在需要时,定时器溢出是被调用,不需要时NULL即可;
    1.  If required, provide a callback function (see[app_timer_timeout_handler_t])that will be executed in the time-out handler.
    */
    

    区别2:PWM duty cycle 的设定不同之处。

    //--------------------------高速PWM duty cycle设定--------------------
    app_pwm_channel_duty_set(&p_instance,channel, duty);
    /*
    p_instance : PWM timer ID,PWM定时器实例ID
    channel : 单通道PWM有两路PWM信号输出,0和1;如果初始化的为1CH,则只有0通道;
    duty: 占空比设定值,单位为百分比 范围0~100;
    */
    
    //--------------------------低功耗PWM duty cycle设定--------------------
    low_power_pwm_duty_set(low_power_pwm_t * p_pwm_instance,uint8_t  duty_cycle)
    
    /*
     p_pwm_instance :  需要更改哪个PWM的duty,输入的是PWM实例的ID值;
    duty_cycle : New high pulse width. 0 means that the LED is always off. 
    255 means that it is always on. 新设定的高脉冲宽度,0~255的脉冲宽度设定范围。
    */
    

    相关文章

      网友评论

          本文标题:在SDK10的SD-LOW POWER PWM例程中增加PWM功

          本文链接:https://www.haomeiwen.com/subject/nopuwxtx.html