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

Generating Pulses

Hello, I am trying to generate pulses with the nRF52832 chip.I created a basic setup for test purposes; I simply connected a LED to the PWM output, but even though I put 0 into the sequence duty cycle values my LED still light up. My code is below. I'd appreciate any help.

Regards.

Note: Since Keil is not updating nRF SDK on its servers I probably am using outdated things. Also, I'm using s210 softdevice

#include <stdbool.h>
#include <stdint.h>
#include "nrf_delay.h"
#include "nrf_gpio.h"
#include "nrf_gpiote.h"
#include "nrf_pwm.h"
#include "nrf_esb.h"
#include "nrf_error.h"
#include "nrf.h"
#include "nrf_drv_pwm.h"
int main(void)
{

nrf_pwm_values_common_t seq_values[1] = {0};

//nrf_pwm_sequence_t const seq =
//{
//    .values.p_common = seq_values,
//    .length          = NRF_PWM_VALUES_LENGTH(seq_values),
//    .repeats         = 0,
//    .end_delay       = 0
//};

uint32_t out_pins[4]={16,NRF_PWM_PIN_NOT_CONNECTED,NRF_PWM_PIN_NOT_CONNECTED,NRF_PWM_PIN_NOT_CONNECTED};
nrf_pwm_enable(NRF_PWM0);
nrf_pwm_pins_set(NRF_PWM0,out_pins);
nrf_pwm_configure(NRF_PWM0,NRF_PWM_CLK_1MHz,NRF_PWM_MODE_UP,64000);	
//nrf_pwm_sequence_set(NRF_PWM0,0,&seq);
nrf_pwm_seq_ptr_set(NRF_PWM0,0,seq_values);
nrf_pwm_seq_cnt_set(NRF_PWM0,0,NRF_PWM_VALUES_LENGTH(seq_values));
nrf_pwm_seq_refresh_set(NRF_PWM0,0,0);
nrf_pwm_seq_end_delay_set(NRF_PWM0,0,0);
nrf_pwm_loop_set(NRF_PWM0,200);
nrf_pwm_decoder_set(NRF_PWM0,NRF_PWM_LOAD_COMMON,NRF_PWM_STEP_AUTO);
    nrf_pwm_event_clear(NRF_PWM0, NRF_PWM_EVENT_LOOPSDONE);
    nrf_pwm_event_clear(NRF_PWM0, NRF_PWM_EVENT_SEQEND0);
    nrf_pwm_event_clear(NRF_PWM0, NRF_PWM_EVENT_SEQEND1);
    nrf_pwm_event_clear(NRF_PWM0, NRF_PWM_EVENT_STOPPED);
nrf_pwm_task_trigger(NRF_PWM0,NRF_PWM_TASK_SEQSTART0);
    while (1)
    {		

//			nrf_gpio_cfg(16,NRF_GPIO_PIN_DIR_OUTPUT,NRF_GPIO_PIN_INPUT_DISCONNECT,NRF_GPIO_PIN_NOPULL,NRF_GPIO_PIN_S0S1,NRF_GPIO_PIN_NOSENSE);
//			nrf_gpio_pin_toggle(16);
//			nrf_delay_ms(500);
				
				//if(nrf_pwm_event_check(NRF_PWM0,NRF_PWM_EVENT_SEQEND0))nrf_pwm_task_trigger(NRF_PWM0,NRF_PWM_TASK_SEQSTART0);
				
				
			

		}
}
Parents
  • Hi,

    I will strongly recommend to use the nrf_drv_pwm functions, and not use the PWM HAL(Hardware access layer) functions directly. Note that you are overflowing the COUNTERTOP register by using the value 64000. Max value is 32767.

    Also note that with the sequence duty cycle values the most significant bit[15] denotes the polarity. So if you want seq_value 0 to correspond to 0 V, you need to set bit 15 to 1. E.g. by using bitwise OR.

    seq_values->channel_0 = duty_cycle | 0x8000;
    

    Code example that shows how to set a duty cycle between 0 and 100 % that uses 10kHz PWM:

    #include <stdio.h>
    #include <string.h>
    #include "nrf_drv_pwm.h"
    #include "app_util_platform.h"
    #include "app_error.h"
    #include "boards.h"
    #include "bsp.h"
    #include "nrf_drv_clock.h"
    #include "nrf_delay.h"
    
    
    #define OUTPUT_PIN 16
    
    static nrf_drv_pwm_t m_pwm0 = NRF_DRV_PWM_INSTANCE(0);
    
    // Declare variables holding PWM sequence values. In this example only one channel is used 
    nrf_pwm_values_individual_t seq_values[] = {0, 0, 0, 0};
    nrf_pwm_sequence_t const seq =
    {
        .values.p_individual = seq_values,
        .length          = NRF_PWM_VALUES_LENGTH(seq_values),
        .repeats         = 0,
        .end_delay       = 0
    };
    
    
    // Set duty cycle between 0 and 100%
    void pwm_update_duty_cycle(uint8_t duty_cycle)
    {
    
        // Check if value is outside of range. If so, set to 0%
        if(duty_cycle >= 100)
        {
            seq_values->channel_0 = 0;
        }
        else
        {
            
            seq_values->channel_0 = duty_cycle | 0x8000; // Change polarity 
        }
       
        nrf_drv_pwm_simple_playback(&m_pwm0, &seq, 1, NRF_DRV_PWM_FLAG_LOOP);
    }
    
    static void pwm_init(void)
    {
        nrf_drv_pwm_config_t const config0 =
        {
            .output_pins =
            {
                OUTPUT_PIN, // channel 0
                NRF_DRV_PWM_PIN_NOT_USED,             // channel 1
                NRF_DRV_PWM_PIN_NOT_USED,             // channel 2
                NRF_DRV_PWM_PIN_NOT_USED,             // channel 3
            },
            .irq_priority = APP_IRQ_PRIORITY_LOWEST,
            .base_clock   = NRF_PWM_CLK_1MHz,
            .count_mode   = NRF_PWM_MODE_UP,
            .top_value    = 100,
            .load_mode    = NRF_PWM_LOAD_INDIVIDUAL,
            .step_mode    = NRF_PWM_STEP_AUTO
        };
        // Init PWM without error handler
        APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, NULL));
    
    }
    
    
    int main(void)
    {
    
        // Start clock for accurate frequencies
        NRF_CLOCK->TASKS_HFCLKSTART = 1; 
        // Wait for clock to start
        while(NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) ;
    
        pwm_init();
        pwm_update_duty_cycle(40);
    
        for (;;)
        {
    
        }
    }
    
    
    /** @} */
    
  • I feel sorry to ask this but I did not understand the 'polarity' concept. What exactly is it?

Reply Children
No Data
Related