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

這段時(shí)間寫(xiě)的程序較少,期間或多或少的會(huì)忘記一些程序編寫(xiě)方法;正好這段時(shí)間新進(jìn)了一套51822的開(kāi)發(fā)板,再折騰一下這個(gè)芯片。
折騰對(duì)象:SDK中提供的Low-power PWM library 和 PWM library;
過(guò)程:
1. 首先看SDK提供的文檔,對(duì)程序有個(gè)大概的了解;
2. 再對(duì)SDK中提供例程做實(shí)驗(yàn),來(lái)驗(yàn)證文檔中的所講的內(nèi)容,最主要的還
是庫(kù)文件的使用方法;
3.將兩個(gè)例程做混合 ,目的在一個(gè)芯片上實(shí)現(xiàn)兩個(gè)不同功能的PWM。


前兩部分都是理解的過(guò)程,而且分開(kāi)實(shí)驗(yàn)時(shí)的例程直接使用就行,不涉及到修改和新建工程的程序。
而在第三步時(shí),編譯時(shí)會(huì)出現(xiàn)各種各樣的錯(cuò)誤,需要自己一個(gè)個(gè)的去解決。
實(shí)驗(yàn)過(guò)程: 在Low-Power PWM例程中增加PWM功能。
1. 在Low-power PWM 工程中的nRF_librares 中添加 app_pwm.c文件。
2. 在main.c文件中增加頭文件加載項(xiàng) #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函數(shù)后,也需要在MAIN函數(shù)中調(diào)用才行。

3. 編譯程序,提示錯(cuò)誤:找不到頭文件 ```nrf_drv_timer.h;nrf_drv_gpiote.h;nrf_drv_ppi.h```
 解決辦法:在option for target 選項(xiàng)的C/C++中增加對(duì)應(yīng)的目錄:
..\..\..\components\libraries\pwm
..\..\..\components\drivers_nrf\timer
..\..\..\components\drivers_nrf\ppi
..\..\..\components\drivers_nrf\gpiote
  1. 添加目錄后依然有一下多項(xiàng)錯(cuò)誤
..\..\..\..\..\..\components\libraries\pwm\app_pwm.c(57): error:  #94-D: the size of an array must be greater than zero

意思好像是定義的一個(gè)數(shù)組是0,不允許數(shù)組為0個(gè)成員。因此繼續(xù)查找錯(cuò)誤的根源,發(fā)現(xiàn) nrf_drv_config.h 中的一些宏定義都是零,也就是沒(méi)有使能相關(guān)的外設(shè),作如下更改:

#define TIMER1_ENABLED 0   ->  #define TIMER1_ENABLED 1

PWM庫(kù)介紹文檔中提到TIMER0給SD使用了,所以在app中不可以再使用TIMER0 而只用一個(gè)pwm就可以,因此選擇使能 timer1
根據(jù)文檔中介紹也要用的GPIOTE功能,因此也需要將改功能使能:

   #define GPIOTE_ENABLED 0 -> #define GPIOTE_ENABLED 1

修改完成后再做編譯 上面的error被清除,但是還有另外一個(gè)錯(cuò)誤出現(xiàn)了:

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

未定標(biāo)示符,開(kāi)始在工程中滿世界的找 nrf_drv_timer_capture_get 在現(xiàn)有的工程中確實(shí)沒(méi)有多以上標(biāo)示符的定義,后來(lái)再到PWM的實(shí)例中,查找該標(biāo)示符,終于發(fā)現(xiàn)還是缺少一個(gè)源程序文件:nrf_drv_timer .c 文件;將該源程序添加到 driver目錄下,再次編譯程序。順利通過(guò)。

以上的內(nèi)容只是筆記,其中記錄的在一個(gè)程序中增加兩外一個(gè)功能的方法,以及遇到編譯出錯(cuò)時(shí),如何排除錯(cuò)誤。
一、 沒(méi)有在工程中添加頭文件的路徑
二、 沒(méi)有在工程中添加對(duì)應(yīng)的源程序文件,也可以理解為外設(shè)驅(qū)動(dòng)源程序。
三、沒(méi)有在對(duì)應(yīng)的配置文件中使能某些對(duì)應(yīng)功能。

比較笨的辦法:在實(shí)例程序中,去對(duì)比查找故障所在位置。主要是函數(shù)定義是在那個(gè)驅(qū)動(dòng)源程序中?那些外設(shè)需要使能定義,在哪里定義?都可以在SDK的外設(shè)實(shí)例程序中找到對(duì)應(yīng)的解決辦法(對(duì)比差異)。

大概就這些。


低功耗PWM和PWM庫(kù)中,函數(shù)的應(yīng)用是不相同的,這都是今天在實(shí)際寫(xiě)程序時(shí)發(fā)現(xiàn)的,也是因?yàn)樽约褐安蛔⒁庾屑?xì)閱讀文檔的結(jié)果。
區(qū)別1: 兩種pwm在初始化時(shí)的不同

//------------------------高速PWM初始化函數(shù)-------------------------
     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配置函數(shù)輸入變量50L表示50us的周期,單位是us;最小5us
//- 設(shè)置為單通道單輸出模式;BSP_LED_2 將該IO端口配置為PWM信號(hào)輸出端口
//- 設(shè)置輸出端口的polarity 配置為高電平有效
//- init 中的回調(diào)函數(shù)是在完成占空比設(shè)定并且成功后再被調(diào)用的函數(shù)。
//- PWM callback that is executed when a PWM duty change has been completed.
//---------------------------------低功耗PWM初始化函數(shù)--------------------------
    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] | 輸出端口有效電平設(shè)定
| uint8_t  [period] |  實(shí)際的定時(shí)時(shí)間單位不明確。
| uint32_t   [bit_mask]| 哪個(gè)端口設(shè)定為PWM輸出
| [app_timer_id_t]const *  | [p_timer_id]|  PWM實(shí)例
回調(diào)函數(shù)是在需要時(shí),定時(shí)器溢出是被調(diào)用,不需要時(shí)NULL即可;
1.  If required, provide a callback function (see[app_timer_timeout_handler_t])that will be executed in the time-out handler.
*/

區(qū)別2:PWM duty cycle 的設(shè)定不同之處。

//--------------------------高速PWM duty cycle設(shè)定--------------------
app_pwm_channel_duty_set(&p_instance,channel, duty);
/*
p_instance : PWM timer ID,PWM定時(shí)器實(shí)例ID
channel : 單通道PWM有兩路PWM信號(hào)輸出,0和1;如果初始化的為1CH,則只有0通道;
duty: 占空比設(shè)定值,單位為百分比 范圍0~100;
*/
//--------------------------低功耗PWM duty cycle設(shè)定--------------------
low_power_pwm_duty_set(low_power_pwm_t * p_pwm_instance,uint8_t  duty_cycle)

/*
 p_pwm_instance :  需要更改哪個(gè)PWM的duty,輸入的是PWM實(shí)例的ID值;
duty_cycle : New high pulse width. 0 means that the LED is always off. 
255 means that it is always on. 新設(shè)定的高脈沖寬度,0~255的脈沖寬度設(shè)定范圍。
*/
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容