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

PWM modulation frequency or modulation amplitude

Hello, above is the PWM modulation waveform (positive Xuan Bo).

How does 1.nrf52832 regulate the frequency of circulation?

Take this nRF5_SDK_12.2.0_f012efa\examples\peripheral\pwm_driver example Demo1 as an example.

I want to give variable frequency.

Static void demo1_handler (nrf_drv_pwm_evt_type_t event_type)

{

Uint32_t err_code;

If (event_type = = NRF_DRV_PWM_EVT_FINISHED)

{

M_demo1_top + = 100;

If (m_demo1_top>=10000)

{

M_demo1_top=0;

}

Nrf_drv_pwm_config_t const config0 =

{

.output_pins =

{

25 x 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

};

Err_code = nrf_drv_pwm_init (&m_pwm0, &config0, NULL);

APP_ERROR_CHECK (err_code);

}

}

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 updated

* a way that increase and decrease of the light intensity can intensity

* continuously on succeeding channels (one second per channel).

* * /

Uint32_t err_code;

Nrf_drv_pwm_config_t const config0 =

{

.output_pins =

{

25 x 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

};

Err_code = nrf_drv_pwm_init (&m_pwm0, &config0, demo1_handler);

APP_ERROR_CHECK (err_code);

M_used = USED_PWM (0);

M_demo1_seq_values.channel_0 = 0;

/ / m_demo1_seq_values.channel_1 = 0;

/ / m_demo1_seq_values.channel_2 = 0;

/ / m_demo1_seq_values.channel_3 = 0;

M_demo1_phase = 0;

Nrf_drv_pwm_simple_playback (&m_pwm0, &m_demo1_seq, 1,

NRF_DRV_PWM_FLAG_LOOP);

}

M_demo1_top is the value of frequency control.

M_demo1_top + = 100;

If (m_demo1_top>=10000)

{

M_demo1_top=0;

}

M_demo1_top is added from zero to 10000, but no PWM has no output.

What should I do to change the PWM frequency output, from zero to high, from high to zero, modulation frequency conversion output pwm?

Looking forward to your reply, thank you.

报错

Parents
  • Hi,

    The desired pwm frequency is given by the formula F(pwm) = F(base_clock) / top_value. So your idea of increasing the m_demo1_top is correct. Note that the max top_value is 32767.

    M_demo1_top is added from zero to 10000, but no PWM has no output.

     When does this happen? When M_demo1_top reaches 10000?

  • Hello, thank you for your reply. It's known that you want to change. top_value = m_demo1_top. This value needs to be restarted to the initial pwm. I don't know if it's right. How to restart the initial pwm? Is it okay to start the PWM in the interruption?

  • The driver does not support it, but you could try to set the COUNTERTOP register directly in the handler. The duty cycle will also change if you only increase the top_value, so if you want the duty cycle to be the same, you will need to update the seq_value also. You will also need to add some RC filter, or similar to the pin output to get the desired output shown in the image you uploaded.

    Snippet:

    static nrf_pwm_values_individual_t seq_values_new;
    static void demo1_handler(nrf_drv_pwm_evt_type_t event_type)
    {
        if (event_type == NRF_DRV_PWM_EVT_FINISHED)
        {
            uint32_t current_mtop = NRF_PWM0->COUNTERTOP;
    
             if(current_mtop < 32767 )
             {
                NRF_PWM0->COUNTERTOP = current_mtop + 100;
    
                seq_values_new.channel_0 = NRF_PWM0->COUNTERTOP /2;
    
                nrf_pwm_values_t new_pwm_values; 
    
                new_pwm_values.p_individual = &seq_values_new;
    
                nrf_drv_pwm_sequence_values_update(&m_pwm0,1,new_pwm_values);
    
             }
    
        }
    }

  • Thank you for your reply, you can change the frequency output.

Reply Children
No Data
Related