This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to control two channes PWM independently?

Maybe I should post my all the code here.

I want to generate two kinds of PWM1 and PWM2,used by the code as follows: static volatile bool ready_flag;

APP_PWM_INSTANCE(&PWM1,1); APP_PWM_INSTANCE(&PWM2,2);

void pwm1_ready_callback(void) { ready_flag = true;//This code may be unuseful,but it comes from the Nordic Demo. }; void pwm2_ready_callback(void) { ready_flag = true;//This code may be unuseful,but it comes from the Nordic Demo. };

One of them is initialized by the code as follows:

void pwm_ble_led(void) { static ret_code_t error_code; app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_1CH(1000000,LED_0); pwm1_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_LOW; error_code = app_pwm_init(&PWM1,&pwm1_cfg,pwm1_ready_callback); APP_CHECK_ERROR(error_code); }

The another as the same,the code as follows:

void pwm_power_ble(void) { static ret_code_t error_code; app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_1CH(1000000,LED_1); pwm1_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH; error_code = app_pwm_init(&PWM2,&pwm1_cfg,pwm2_ready_callback); APP_CHECK_ERROR(error_code); }

The PWM closed code as follows:

void pwm_ble_close(void) {
uint32_t err_code; app_pwm_disable(&PWM1); nrf_drv_gpiote_out_task_disable(LED_0); err_code = app_pwm_uninit(&PWM1); APP_ERROR_CHECK(err_code); }

void pwm_power_close(void) { uint32_t err_code; app_pwm_disable(&PWM2); nrf_drv_gpiote_out_task_disable(LED_1); err_code = app_pwm_uninit(&PWM2); APP_ERROR_CHECK(err_code); }

The PWM start working code as follows:

void pwm_ble_led_start(void) { pwm_ble_close();//this code is used for guaranting that the PWM is closed,otherwise the system would reset. pwm_ble_led(); app_pwm_enable(&PWM1); nrf_drv_gpiote_out_task_enable(LED_0); app_pwm_channel_duty_set(&PWM1,0,50); }

void pwm_power_led_start(void) { pwm_power_close(); pwm_power_led(); app_pwm_enable(&PWM2); nrf_drv_gpiote_out_task_enable(LED_1); app_pwm_channel_duty_set(&PWM2,0,50); }

The question is how to control the two PWM independently?I have tried the function of app_pwm_disable() and app_pwm_uninit(),but it does not work result of influencing the another PWM.

  • I do not really understand the question. What do you want to control of the PWM? Or what is the difference between these PWM's?

  • The two pwm instances should not influence each other. Can you explain more in detail what your problem is? You can use the 2 channel config: APP_PWM_DEFAULT_CONFIG_2CH(...) if the two pwm channels should have the same frequency. Generally app_pwm_disable(...) is for stopping the timer and may reduce power consumption, app_pwm_uninit(...) is for releasing allocated resources in addition to disabling the pwm. If you want the output to be low you can set the pwm value to zero.

  • I have tried to use the 2 channel config:APP_PWM_DEFAULT_CONFIG_2CH(...),but if I want to close one of them,I should call the function app_pwm_disable(...),the result is all of them are closed,it is not I really want. Then I use the APP_PWM_DEFAULT_CONFIG_1CH(...) to initialize two independently.But it also does not woks.

    When I called the pwm_led0_close() as the follows: void pwm_led0_close() { uint32_t err_code; app_pwm_disable(&PWM1); nrf_drv_gpiote_out_task_disable(LED_0); error_code = app_pwm_uninit(&PWM1); APP_CHECK_ERROR(error_code); }

    The state of LED_1 also closed,it means the function pwm_led0_close() influences the state of LED_1. In addition, calling the app_pwm_disable(...) will stop the timer but will not reducing the power consumption.Only calling the the app_pwm_disable(...) and app_pwm_uninit(&PWM1) together will reducing the power consumption.app_pwm.c

  • Firstly,I initialized two PWMs as mentioned above.Sometimes I want to close one of them.

    For example,I want to close LED_0,so I call the funtion as follows: void pwm_led0_close() { uint32_t err_code; app_pwm_disable(&PWM1); nrf_drv_gpiote_out_task_disable(LED_0); error_code = app_pwm_uninit(&PWM1); APP_CHECK_ERROR(error_code);} It worked to LED0,but as a result,It influenced the state of LED_1.

    As the same,when I close the LED_1 as the follows: void pwm_led1_close() { uint32_t err_code; app_pwm_disable(&PWM2); nrf_drv_gpiote_out_task_disable(LED_1); error_code = app_pwm_uninit(&PWM2); APP_CHECK_ERROR(error_code);} It worked to LED_1,but It influenced the state of LED_0, My question is how to close one of them under not influencing the state of another?

  • First of all you should use the app_pwm driver from SDK 10, this has some fixes to app_pwm_disable and app_pwm_uninit that caused inverted pwm output. It is not necessary to call nrf_drv_gpiote_task_disable(LED_0), doing this may cause strange behaviour. Calling app_pwm_disable will stop the timer, if both pwm instances (PWM1 and PWM2) is disabled and no other peripheral is requiring the HFCLK, the HFCLK will be stopped or go to idle (depending on RC or XTAL used) and thereby reduce the power consumption. app_pwm_uninit will call app_pwm_disable if pwm is enabled and then deallocate the resources.

Related