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

How can I create 1.7MHz, 2.5MHz, 3MHz duty-cycle 50% by PWM in nRF52832

Hi,

As well know, nRF52832 can use "16Mhz base-clock to output PWM signal, and it is very simple to create 4Mhz, 2Mhz, 1MHz signal output,

But, If I want to output a 1.7Mhz, 2.5Mhz, 3Mhz signal output with 50% duty-cycle, does it possible?

How can I do this job?

Thank you,

Chianglin

Parents Reply Children
  • Hi ,

    Thank you for your answer so quickly.

    So, it is possible to create any frequency output by PWM (Include 1.7MHz, 2.5MHz and 3MHz by 50% duty-cycle,)? And I only need to modify COUNTERTOP register?

    Does it true?

    Thank you

    Chianglin

  • COUNTERTOP sets the PWM frequency, and nrf_pwm_sequence_t "sequence" of duty cycle values sets the duty-cycle. 

    COUNTERTOP resets the PWM counter, the compare matches in the "sequence" triggers the GPIO state change.

    See nrfx_pwm_simple_playback.

  • Hi,

    Please find the following source code.

    static uint16_t const              m_demo1_top  = 6;
    static uint16_t const              m_demo1_step = 200;
    
    static uint8_t                     m_demo1_phase;
    static nrf_pwm_values_individual_t m_demo1_seq_values;
    
    static nrf_pwm_sequence_t const    m_demo1_seq =
    {
        .values.p_individual = &m_demo1_seq_values,
        .length              = NRF_PWM_VALUES_LENGTH(m_demo1_seq_values),
        .repeats             = 0,
        .end_delay           = 2
    };
    
    static void demo1_handler(nrf_drv_pwm_evt_type_t event_type)
    {
        if (event_type == NRF_DRV_PWM_EVT_FINISHED)
        {
    	}
    }
    
    void PwmInit(void)
    {
        nrf_drv_pwm_config_t const config0 =
        {
            .output_pins =
            {																// 設定 "連接到 PWM 的 Pin" 和 Pin 的初始狀態
                3 | NRF_DRV_PWM_PIN_INVERTED,								// Offset 0x00000560. Channel-0
                4 | NRF_DRV_PWM_PIN_INVERTED,								// Offset 0x00000564. Channel-1
                31 | NRF_DRV_PWM_PIN_INVERTED,								// Offset 0x00000569. Channel-2
                2 | NRF_DRV_PWM_PIN_INVERTED 								// Offset 0x0000056C. Channel-3
            },
            .irq_priority = APP_IRQ_PRIORITY_LOWEST,
            .base_clock   = NRF_PWM_CLK_16MHz,								// Offset 0x0000050C. 這個地方設的是 PWM 暫存器的 PRESCALER
            .count_mode   = /*NRF_PWM_MODE_UP_AND_DOWN*/ NRF_PWM_MODE_UP,	// Offset 0x00000504. 計數模式 (上緣 or 上緣+下緣)
            .top_value    = m_demo1_top,									// Offset 0x00000508. 脈衝發生器計數器計數的值。 當DECODER.MODE = WaveForm時,將忽略該寄存器,並且僅使用來自RAM的值。
            .load_mode    = NRF_PWM_LOAD_INDIVIDUAL,						// Offset 0x00000510. (bit-0/1) 1st half word (16-bit) in ch.0; 2nd in ch.1; ...; 4th in ch.3
            .step_mode    = NRF_PWM_STEP_AUTO								// Offset 0x00000510. (bit-8) 選擇用於推進活動序列的源: SEQ [n] .REFRESH用於確定加載內部比較寄存器
        };
        APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, demo1_handler));
    
        m_demo1_seq_values.channel_0 = 3;
        m_demo1_seq_values.channel_1 = m_demo1_top/2 /*0*/;
        m_demo1_seq_values.channel_2 = m_demo1_top/2 /*0*/;
        m_demo1_seq_values.channel_3 = m_demo1_top/2 /*0*/;
        m_demo1_phase                = 0;
    
        (void)nrf_drv_pwm_simple_playback(&m_pwm0, &m_demo1_seq, 1, NRF_DRV_PWM_FLAG_LOOP);
    }
    

    If I call "PwmInit()" function. The PWM frequency is 2.667MHz and duty is 0.2us/0.16us.

    How to modify PWM setting, then I can get 2.5MHz frequency and 50% duty-cycle?

    Thank you,.

    Chianglin

  • Oh, I've made a terrible mistake. You won't be able able to get a PWM frequency of 1.7MHz or 2.5MHz, from a 16MHz timer. You will only be able to have a PWM frequency in integers of MHz, ie, 1, 2, 3, 4... MHz. I'm sorry for the confusion. 

Related