This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

4 CHANNELS PWM OUTPUT TROUBLE

image descriptionHi,guys In my project,I intend to generate 4 channels pwm,using 8 channel PPI,timer1,timer2. As below, the timer initializing and timer interrup handler code:

    static void timer_init(void)
    {![image description](/cfs-file/__key/communityserver-discussions-components-files/4/6204.IMG_5F00_20150327_5F00_113450.jpg)
     /* Start 16 MHz crystal oscillator */
              NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
              NRF_CLOCK->TASKS_HFCLKSTART    = 1;
     /* Wait for the external oscillator to start up */
              while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)       
              {
                    // Do nothing.
              } 
        //timer1  Setting
              NRF_TIMER1->TASKS_CLEAR  = 1;
              NRF_TIMER1->MODE         = TIMER_MODE_MODE_Timer;
	          NRF_TIMER1->BITMODE      = TIMER_BITMODE_BITMODE_08Bit;
              NRF_TIMER1->PRESCALER    = TIMER_PRESCALER;//9
              NRF_TIMER1->CC[0]        = SMALLEST_CC_VALUE;//10	
              NRF_TIMER1->CC[1]        = INITIAL_CC1_VALUE;//3
              NRF_TIMER1->CC[2]        = INITIAL_CC2_VALUE;//3
              NRF_TIMER1->CC[3]        = LARGEST_CC_VALUE;//240
              NRF_TIMER1->INTENSET     = TIMER_INTENSET_COMPARE3_Msk;
              NRF_TIMER1->SHORTS       = TIMER_SHORTS_COMPARE3_CLEAR_Msk;
              NRF_TIMER1->EVENTS_COMPARE[0] =NRF_TIMER1->EVENTS_COMPARE[1] =0;
              NRF_TIMER1->EVENTS_COMPARE[2] =NRF_TIMER1->EVENTS_COMPARE[3] =0;
       //timer2 setting
	          NRF_TIMER2->TASKS_CLEAR = 1;
              NRF_TIMER2->MODE        = TIMER_MODE_MODE_Timer;
              NRF_TIMER2->BITMODE     = TIMER_BITMODE_BITMODE_08Bit;
              NRF_TIMER2->PRESCALER   = TIMER_PRESCALER;
              NRF_TIMER2->CC[0]       = SMALLEST_CC_VALUE;	
              NRF_TIMER2->CC[1]       = INITIAL_CC1_VALUE;
              NRF_TIMER2->CC[2]       = INITIAL_CC2_VALUE;
              NRF_TIMER2->CC[3]       = LARGEST_CC_VALUE;
              NRF_TIMER2->SHORTS      = TIMER_SHORTS_COMPARE3_CLEAR_Msk;
              NRF_TIMER2->INTENSET    = TIMER_INTENSET_COMPARE3_Msk;	
              NRF_TIMER2->EVENTS_COMPARE[0] =NRF_TIMER2->EVENTS_COMPARE[1] =0;
              NRF_TIMER2->EVENTS_COMPARE[2] =NRF_TIMER2->EVENTS_COMPARE[3] =0;						
    }

  void TIMER1_IRQHandler(void)
  { 
       uint8_t p_is_nested_critical_region;
       sd_nvic_critical_region_enter(&p_is_nested_critical_region);
       mode_tick++;
       if((pre_data_1_mode[0]!=0)&&(pre_data_1_mode[0]!=3)&&(pre_data_1_mode[0]!=4))
       {
           runInTimerInterupt();
       }
    //clear the CC event flag 
       NRF_TIMER1->EVENTS_COMPARE[0] = NRF_TIMER1->EVENTS_COMPARE[1] = 0;
       NRF_TIMER1->EVENTS_COMPARE[2] = NRF_TIMER1->EVENTS_COMPARE[3] = 0;
    //if the colors' value do not change, return. 
   if(((uint8_t)rgbw.red==NRF_TIMER1->CC[1])&&((uint8_t)rgbw.green==NRF_TIMER1->CC[2]))
   {
       if((pre_data_1_mode[0])==0)
       {
           NRF_TIMER1->INTENCLR  = TIMER_INTENCLR_COMPARE3_Msk;
       }
       sd_nvic_critical_region_exit(p_is_nested_critical_region);
       return;
  }
  //red color value reset;
  if((uint8_t)rgbw.red<=SMALLEST_CC_VALUE)
   {
      NRF_TIMER1->CC[1]= (uint8_t)rgbw.red;
      nrf_gpiote_unconfig(gpiote_task_channel_number[0]);
      nrf_gpio_pin_clear(pwm_output_pin_number[0]);	
   }
   else if((uint8_t)rgbw.red>=LARGEST_CC_VALUE)
   {
      NRF_TIMER1->CC[1]= (uint8_t)rgbw.red;
      nrf_gpiote_unconfig(gpiote_task_channel_number[0]);
      nrf_gpio_pin_set(pwm_output_pin_number[0]);
   }
   else
   {
      NRF_TIMER1->TASKS_STOP = 1;
      NRF_TIMER1->EVENTS_COMPARE[0] = NRF_TIMER1->EVENTS_COMPARE[1] = 0;
      NRF_TIMER1->CC[1]= (uint8_t)rgbw.red;
      nrf_gpio_pin_clear(pwm_output_pin_number[0]);
      nrf_gpiote_task_config(0, pwm_output_pin_number[0],
      NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW); 
   }
   //green color value reset;	
   if((uint8_t)rgbw.green<=SMALLEST_CC_VALUE)
   {
       NRF_TIMER1->CC[2]=(uint8_t)rgbw.green;
       nrf_gpiote_unconfig(gpiote_task_channel_number[1]);
       nrf_gpio_pin_clear(pwm_output_pin_number[1]);
}
else if((uint8_t)rgbw.green>=LARGEST_CC_VALUE)
{
        NRF_TIMER1->CC[2]=(uint8_t)rgbw.green;
        nrf_gpiote_unconfig(gpiote_task_channel_number[1]);
        nrf_gpio_pin_set(pwm_output_pin_number[1]);
    }
    else
    {
         NRF_TIMER1->TASKS_STOP = 1;
         NRF_TIMER1->EVENTS_COMPARE[2] = NRF_TIMER1->EVENTS_COMPARE[3] = 0;
         NRF_TIMER1->CC[2]= (uint8_t)rgbw.green;
         nrf_gpio_pin_clear(pwm_output_pin_number[1]);
         nrf_gpiote_task_config(1, pwm_output_pin_number[1],
         NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
    }
    NRF_TIMER1->TASKS_CLEAR = 1;
    NRF_TIMER1->TASKS_START = 1;
    sd_nvic_critical_region_exit(p_is_nested_critical_region);

}

TIMER2_IRQHandler is just like the TIMER1_IRQHandler except it is handling the blue and white,but some times the pwm signals are disturbed by some reason,picture followed:image description

Related