这段时间写的程序较少,期间或多或少的会忘记一些程序编写方法;正好这段时间新进了一套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
- 添加目录后依然有一下多项错误
..\..\..\..\..\..\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的脉冲宽度设定范围。
*/
网友评论