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

pwm hardware individual loading mode nrf52

Please can anyone help me on how to use(program) PWM hardware with individual loading mode? My goal is to control 12 LEDs individually with different duty cycles and playbacks using pwm hardware which has 12 outputs to make a kind of led chaser.

Thanks in advance

Parents
  • @Akshaey: Have you tried to play with the pwm_driver example in the SDK the demo 1 example ? We have 3 PWM instance (PWM0, PWM1, PWM2) and each has 4 channels. In these 4 channel, they will have the same frequency, you can control duty cycle for each of them.

  • @akshaey: If you do this in the pwm_driver example you can see LED1 at 20% duty cycle , LED2 at 40% duty cycle, LED3 at 60%, and LED4 at 80%. Base clock is 1MHz and count to 10000 top (m_demo1_top = 10000) meaning the frequency is 100Hz. LED1 is at 205 duty cycle because I set m_demo1_seq_values.channel_0 = 2000; You can choose anything else.

    You can remove demo1_handler() if you don't need a handler (passing NULL when calling nrf_drv_pwm_init)

    static void demo1_handler(nrf_drv_pwm_evt_type_t event_type)
    {
       
    }
    static void demo1(void)
    {
        NRF_LOG_INFO("Demo 1\r\n");
    
        /*
         * This demo plays back a sequence with different values for individual
         * channels (LED 1 - LED 4). Only four values are used (one per channel).
         * Every time the values are loaded into the compare registers, they are
         * updated in the provided event handler. The values are updated in such
         * a way that increase and decrease of the light intensity can be observed
         * continuously on succeeding channels (one second per channel).
         */
    
        nrf_drv_pwm_config_t const config0 =
        {
            .output_pins =
            {
                BSP_LED_0 | NRF_DRV_PWM_PIN_INVERTED, // channel 0
                BSP_LED_1 | NRF_DRV_PWM_PIN_INVERTED, // channel 1
                BSP_LED_3 | NRF_DRV_PWM_PIN_INVERTED, // channel 2
                BSP_LED_2 | NRF_DRV_PWM_PIN_INVERTED  // channel 3
            },
            .irq_priority = APP_IRQ_PRIORITY_LOWEST,
            .base_clock   = NRF_PWM_CLK_1MHz,
            .count_mode   = NRF_PWM_MODE_UP,
            .top_value    = m_demo1_top,
            .load_mode    = NRF_PWM_LOAD_INDIVIDUAL,
            .step_mode    = NRF_PWM_STEP_AUTO
        };
        APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, demo1_handler));
        m_used |= USED_PWM(0);
    
        m_demo1_seq_values.channel_0 = 2000;
        m_demo1_seq_values.channel_1 = 4000;
        m_demo1_seq_values.channel_2 = 6000;
        m_demo1_seq_values.channel_3 = 8000;
        m_demo1_phase                = 0;
    
        (void)nrf_drv_pwm_simple_playback(&m_pwm0, &m_demo1_seq, 1,
                                          NRF_DRV_PWM_FLAG_LOOP);
    }
    

    Here only show you with 4 PWM, you can extend to 12 PWM by using more instance m_pwm1 and m_pwm2, with same configuration.

Reply
  • @akshaey: If you do this in the pwm_driver example you can see LED1 at 20% duty cycle , LED2 at 40% duty cycle, LED3 at 60%, and LED4 at 80%. Base clock is 1MHz and count to 10000 top (m_demo1_top = 10000) meaning the frequency is 100Hz. LED1 is at 205 duty cycle because I set m_demo1_seq_values.channel_0 = 2000; You can choose anything else.

    You can remove demo1_handler() if you don't need a handler (passing NULL when calling nrf_drv_pwm_init)

    static void demo1_handler(nrf_drv_pwm_evt_type_t event_type)
    {
       
    }
    static void demo1(void)
    {
        NRF_LOG_INFO("Demo 1\r\n");
    
        /*
         * This demo plays back a sequence with different values for individual
         * channels (LED 1 - LED 4). Only four values are used (one per channel).
         * Every time the values are loaded into the compare registers, they are
         * updated in the provided event handler. The values are updated in such
         * a way that increase and decrease of the light intensity can be observed
         * continuously on succeeding channels (one second per channel).
         */
    
        nrf_drv_pwm_config_t const config0 =
        {
            .output_pins =
            {
                BSP_LED_0 | NRF_DRV_PWM_PIN_INVERTED, // channel 0
                BSP_LED_1 | NRF_DRV_PWM_PIN_INVERTED, // channel 1
                BSP_LED_3 | NRF_DRV_PWM_PIN_INVERTED, // channel 2
                BSP_LED_2 | NRF_DRV_PWM_PIN_INVERTED  // channel 3
            },
            .irq_priority = APP_IRQ_PRIORITY_LOWEST,
            .base_clock   = NRF_PWM_CLK_1MHz,
            .count_mode   = NRF_PWM_MODE_UP,
            .top_value    = m_demo1_top,
            .load_mode    = NRF_PWM_LOAD_INDIVIDUAL,
            .step_mode    = NRF_PWM_STEP_AUTO
        };
        APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, demo1_handler));
        m_used |= USED_PWM(0);
    
        m_demo1_seq_values.channel_0 = 2000;
        m_demo1_seq_values.channel_1 = 4000;
        m_demo1_seq_values.channel_2 = 6000;
        m_demo1_seq_values.channel_3 = 8000;
        m_demo1_phase                = 0;
    
        (void)nrf_drv_pwm_simple_playback(&m_pwm0, &m_demo1_seq, 1,
                                          NRF_DRV_PWM_FLAG_LOOP);
    }
    

    Here only show you with 4 PWM, you can extend to 12 PWM by using more instance m_pwm1 and m_pwm2, with same configuration.

Children
No Data
Related