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

#nrf52840: create 2 PWMs with different pulse width using single instance by direct register access

As per #nrf52840 datasheet

  NRF_P0->DIR |= 0x0001E000;
  NRF_P0->OUT |= 0x0001E000;


  uint16_t pwm_seq[4]= {160 , 3200};

  NRF_PWM0->PSEL.OUT[0] = 0;
  NRF_PWM0->PSEL.OUT[0] = 13 ;

  NRF_PWM0->PSEL.OUT[1] = 0 ;
  NRF_PWM0->PSEL.OUT[1] = 14 ;


  NRF_PWM0->ENABLE = 0x00000001;
 
  NRF_PWM0->MODE = 0x00000000;

  NRF_PWM0->PRESCALER = 0x00000000; //16Mhz

  NRF_PWM0->COUNTERTOP = 16000; // PWM_Freq = 1000 Hz

  //NRF_PWM0->LOOP = 0x00000000;

  //NRF_PWM0->DECODER = 0x00000002;
 
  NRF_PWM0->SEQ[0].PTR = (uint32_t)(pwm_seq);
 
  NRF_PWM0->SEQ[0].CNT = 2;
 
  NRF_PWM0->SEQ[0].REFRESH = 0;
 
  NRF_PWM0->SEQ[0].ENDDELAY = 0;
 
  NRF_PWM0->TASKS_SEQSTART[0] = 1;

I've configured PWM0 registers as mentioned above. But with this setting both LED1 & LED2 are showing same intensity that means both channels set to common pulse width.

How to edit this configuration so that both channels will set to different pulse width ?

If I set NRF_PWM0->DECODER = 0x00000002; I didn't observe anything on two channels.

How to update pulse width dynamically after these initial configuration ?

Thank You !!

Parents
  • Hello World !!

    Here answering my own question....

    I found that working of PWM module depends upon sequence of configuration.

    Here is simple working demo,

    //---------------------------------------------------------------------------------------------------------------------------------------------------------

    #include "nrf_delay.h"

    uint16_t pwm_seq[4];

    void gpio_init(void)
    {


      NRF_P0->DIR |= 0x0001E000;   
      NRF_P0->OUT |= 0x0001E000; 

      NRF_PWM0->PSEL.OUT[0] = 13 ;     // LED_1
      NRF_PWM0->PSEL.OUT[1] = 14 ;     // LED_2
     
      NRF_PWM0->MODE = 0x00000000;

      NRF_PWM0->PRESCALER = 0x00000004; //1 Mhz

      NRF_PWM0->COUNTERTOP = 1000;  //1 Khz

      NRF_PWM0->DECODER = 0x00000002;
     
      NRF_PWM0->LOOP = 0x00000000;
     
      NRF_PWM0->SEQ[0].REFRESH = 0;
     
      NRF_PWM0->SEQ[0].ENDDELAY = 0;

      NRF_PWM0->SEQ[0].PTR = (uint32_t)(pwm_seq);
     
      NRF_PWM0->SEQ[0].CNT = 4;

      NRF_PWM0->ENABLE = 0x00000001;
     
      NRF_PWM0->TASKS_SEQSTART[0] = 1;


    }


    int main(void)
    {
     
      unsigned char data=0;
      int i;

      gpio_init();

      while(1)
      {
        pwm_seq[0] += 10;
        pwm_seq[1] += 100;
        
        NRF_PWM0->TASKS_SEQSTART[0] = 1;

        if(pwm_seq[0] > 1000)
        {
          pwm_seq[0] = 0;
        }

        if(pwm_seq[1] > 1000)
        {
          pwm_seq[1] = 0;
        }


        nrf_delay_ms(100);
     
      }

      return(0);

    }

Reply
  • Hello World !!

    Here answering my own question....

    I found that working of PWM module depends upon sequence of configuration.

    Here is simple working demo,

    //---------------------------------------------------------------------------------------------------------------------------------------------------------

    #include "nrf_delay.h"

    uint16_t pwm_seq[4];

    void gpio_init(void)
    {


      NRF_P0->DIR |= 0x0001E000;   
      NRF_P0->OUT |= 0x0001E000; 

      NRF_PWM0->PSEL.OUT[0] = 13 ;     // LED_1
      NRF_PWM0->PSEL.OUT[1] = 14 ;     // LED_2
     
      NRF_PWM0->MODE = 0x00000000;

      NRF_PWM0->PRESCALER = 0x00000004; //1 Mhz

      NRF_PWM0->COUNTERTOP = 1000;  //1 Khz

      NRF_PWM0->DECODER = 0x00000002;
     
      NRF_PWM0->LOOP = 0x00000000;
     
      NRF_PWM0->SEQ[0].REFRESH = 0;
     
      NRF_PWM0->SEQ[0].ENDDELAY = 0;

      NRF_PWM0->SEQ[0].PTR = (uint32_t)(pwm_seq);
     
      NRF_PWM0->SEQ[0].CNT = 4;

      NRF_PWM0->ENABLE = 0x00000001;
     
      NRF_PWM0->TASKS_SEQSTART[0] = 1;


    }


    int main(void)
    {
     
      unsigned char data=0;
      int i;

      gpio_init();

      while(1)
      {
        pwm_seq[0] += 10;
        pwm_seq[1] += 100;
        
        NRF_PWM0->TASKS_SEQSTART[0] = 1;

        if(pwm_seq[0] > 1000)
        {
          pwm_seq[0] = 0;
        }

        if(pwm_seq[1] > 1000)
        {
          pwm_seq[1] = 0;
        }


        nrf_delay_ms(100);
     
      }

      return(0);

    }

Children
No Data
Related