nRF51822 的兩路 PWM 極性


  忙了一陣這個PWM,玩着玩着終於發現了些規律。Nordic 也挺會坑爹的。

  nRF51822 是沒有硬件 PWM 的,只能靠一系列難以理解的 PPI /GPIOTE/TIMER來實現,其實我想說,我醉了。

  幸好SDK有這個的demo,不然真的很醉。這里說的是SDK9.0.0。

  即便是有SDK,相信很多人都像我一樣,看下去會覺得暈頭轉向的,不過知道幾個函數的應用就可以了。

  先記下怎么開始用一個PWM。這里我要用2路極性相反的PWM。

先來初始化兩個個PWM實例,名字是PWM1、PWM2,用硬件Timer1/Timer2作為基礎,千萬要切記Timer1/Timer2沒被占用,然后記得打開Timer1/Timer2的宏。

#define TIMER1_ENABLED 1
#define TIMER2_ENABLED 1
APP_PWM_INSTANCE(PWM1,1);
APP_PWM_INSTANCE(PWM1,1);

然后初始化一個PWM。

void pwm_init(uint32_t freq)
{
    static uint8_t flag=0;
    
    uint32_t period_us = 1000000UL/freq;

     /* 2-channel PWM, 200Hz, output on DK LED pins. */
    app_pwm_config_t pwm_cfg = APP_PWM_DEFAULT_CONFIG_1CH(period_us, BEEF_PIN_E1);
    app_pwm_config_t pwm_cfg2 = APP_PWM_DEFAULT_CONFIG_1CH(period_us, BEEF_PIN_E2);

//    pwm_cfg2.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;
    /* Switch the polarity of the second channel. */
//  pwm_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_LOW;
#if 1
    if(flag)
        pwm_cfg2.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_LOW;
    else
        pwm_cfg2.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;
#endif

    flag = !flag;
    /* Initialize and enable PWM. */
    ret_code_t err_code;
    err_code = app_pwm_init(&PWM1,&pwm_cfg,pwm_ready_callback);
    APP_ERROR_CHECK(err_code); 
    err_code = app_pwm_init(&PWM2,&pwm_cfg2,pwm_ready_callback);
    APP_ERROR_CHECK(err_code); 

}

上面的代碼你會注意到,我用了一個 flag 。這就是我想要說的重點。

這個函數是可以反復使用以修改 PWM的頻率的,在再次使用時,先uninit它,如下:

void pwm_uninit(void)
{
    app_pwm_uninit(&PWM1);
    app_pwm_uninit(&PWM2);
}

我要說的重點是,第二次使用pwm_init()后然后enable_pwm,你就會發現這兩路 的PWM的極性變成一樣的了,所以我用一個flag,每次切換一下。解決了這個問題。

另外我發現修改占空比時,要等上一段時間才能修改完成,這點非常奇怪,懶得去追究原因了,所以才用了兩個定時器來做這兩路PWM。

void pwm_on(void)
{

    app_pwm_enable(&PWM1);
    app_pwm_enable(&PWM2);

    app_pwm_channel_duty_set(&PWM1, 0, 50);
    app_pwm_channel_duty_set(&PWM2, 0, 50);

//    ready_flag = false;
//    while (app_pwm_channel_duty_set(&PWM1, 0, 50) == NRF_ERROR_BUSY);
//    while(!ready_flag);
 //   APP_ERROR_CHECK(app_pwm_channel_duty_set(&PWM1, 1, 50));
}

就是這兩個怪事。記下來。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM