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

How to generate two complimentary 300KHz signals with specific timing

How can I generate two complimentary signals using PWM with a period of 3.33us (300khz) with ability to control number of pulses to generate.

1: With current api PWM takes period is integer values of microseconds so I can set either 3us or 4us, but I need to set 3.33us

2: How do I control exact number of pulses generated by PWM

3: For my second signal is it possible to set delay so that first signal and the second signal does not overlap

Parents
  • Hi,

    it would be too complex configuration for PWM, though maybe it's possible...  I would recommend you to use TIMER and GPIOTE for this task. Note that you cannot achieve an exact 300khz signal, either with TIMER or PWM, the closest value is 16000000/53=301.8kHz (if it matters to you). A number of pulses can be counted by an interrupt handler triggered with COMPARE[3] event.

    Here is a code that uses TIMER1:

    nrf_gpiote_task_configure(0, DRVA_PIN_NUMBER, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
    nrf_gpiote_task_configure(1, DRVB_PIN_NUMBER, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
    
    NRF_TIMER1->MODE        = TIMER_MODE_MODE_Timer;
    NRF_TIMER1->BITMODE     = (TIMER_BITMODE_BITMODE_32Bit << TIMER_BITMODE_BITMODE_Pos);
    NRF_TIMER1->PRESCALER   = 0; // 16MHz
    NRF_TIMER1->SHORTS      = (TIMER_SHORTS_COMPARE3_CLEAR_Enabled << TIMER_SHORTS_COMPARE3_CLEAR_Pos);
    
    int period = 16000000/300000;
    
    NRF_TIMER1->CC[0] = 2; // ensure 124ns delay
    NRF_PPI->CH[0].EEP = (uint32_t) &NRF_TIMER1->EVENTS_COMPARE[0];
    NRF_PPI->CH[0].TEP = (uint32_t) &NRF_GPIOTE->TASKS_SET[0];
    
    NRF_TIMER1->CC[1] = period/2;
    NRF_PPI->CH[1].EEP = (uint32_t) &NRF_TIMER1->EVENTS_COMPARE[1];
    NRF_PPI->CH[1].TEP = (uint32_t) &NRF_GPIOTE->TASKS_CLR[0];
    
    NRF_TIMER1->CC[2] = period/2 + 2; // ensure 124ns delay
    NRF_PPI->CH[2].EEP = (uint32_t) &NRF_TIMER1->EVENTS_COMPARE[2];
    NRF_PPI->CH[2].TEP = (uint32_t) &NRF_GPIOTE->TASKS_SET[1];
    
    NRF_TIMER1->CC[3] = period;
    NRF_PPI->CH[3].EEP = (uint32_t) &NRF_TIMER1->EVENTS_COMPARE[3];
    NRF_PPI->CH[3].TEP = (uint32_t) &NRF_GPIOTE->TASKS_CLR[1];
    
    NRF_PPI->CHENSET = PPI_CHENSET_CH0_Enabled << PPI_CHENSET_CH0_Pos | 
                       PPI_CHENSET_CH1_Enabled << PPI_CHENSET_CH1_Pos |
                       PPI_CHENSET_CH2_Enabled << PPI_CHENSET_CH2_Pos |
                       PPI_CHENSET_CH3_Enabled << PPI_CHENSET_CH3_Pos; 
    
    NRF_TIMER1->TASKS_CLEAR = 1;
    NRF_TIMER1->TASKS_START = 1;
    

  • Thank you, it works. 301.8khz will work for me.

Reply Children
No Data
Related