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

Use timer2 to generate 1K Hz square waveform, but can not get a continuously 1K Hz square waveform

Hi

I want a 1K Hz square waveform to drive a peripheral device, but I can not get a continuously square waveform on GPIO 19, pls have a look at the picture I attached, the following is the timer initialization and interrupt routine, pls help check why this happened, thanks.

////////////////////////////////////////////////////////////////////////////Timer2 init static void timer2_init (void) { NRF_TIMER2->TASKS_STOP = 1; // Create an Event-Task shortcut to clear TIMER0 on COMPARE[0] event NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer; NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_16Bit; NRF_TIMER2->PRESCALER = timer2_prescaler_set; // timer2_prescaler_set = 4

NRF_TIMER2->TASKS_CLEAR = 1;               	// clear the task first to be usable for later

NRF_TIMER2->CC[0] = timer2_interval;   //timer2_interval = 500			

NRF_TIMER2->INTENSET    = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos;
/* Create an Event-Task shortcut to clear TIMER1 on COMPARE[0] event. */

// NRF_TIMER2->SHORTS = (TIMER_SHORTS_COMPARE1_CLEAR_Enabled << TIMER_SHORTS_COMPARE1_CLEAR_Pos);

sd_nvic_SetPriority (TIMER2_IRQn, APP_IRQ_PRIORITY_LOW);		// Setzt die Prioroität auf HIGH

sd_nvic_EnableIRQ (TIMER2_IRQn); // Aktiviert den Interrupt

NRF_TIMER2->TASKS_START = 1;

}

//////////////////////////////////////////////////////////////////////////////////////////////////////// void TIMER2_IRQHandler(void) { uint16_t i;

if ((NRF_TIMER2->EVENTS_COMPARE[0] != 0) && \
    ((NRF_TIMER2->INTENSET & TIMER_INTENSET_COMPARE0_Msk) != 0))
{
		NRF_TIMER2->EVENTS_COMPARE[0] = 0;
		NRF_TIMER2->CC[0] += timer2_interval;
									
		nrf_gpio_pin_toggle(19);
}

}

1k_waveform.jpg

  • FormerMember
    0 FormerMember

    Sorry, my bad. Deleted the wrong answer in the reply: Either remove the short between compare0 and clear while initializing or don't update the CC[0] register in the ISR. See if this helps.

  • FormerMember
    0 FormerMember

    In the ISR, just try to use the condition of only checking for the event i.e. void TIMER2_IRQHandler(void) { if(NRF_TIMER2->EVENTS_COMPARE[0] != 0) { NRF_TIMER2->EVENTS_COMPARE[0] = 0; NRF_TIMER2->CC[0] += timer2_interval;

    nrf_gpio_pin_toggle(19); } }

  • Hi

    I guess your problem is, that your ISR has lower priority than the BLE activity. If BLE is active any of your interrupts are handled with lower priority than the ISR of the softdevice. These are the gaps you see in your attached image.

    The only (and probably beeter) way to generate your signal parallel to running BLE is to connect the TIMER over PPI with GPIOTE.

    1. CC[0]-Event of the timer should be connected to a SET-Task of the GPIOTE.
    2. CC[1]-Event of the timer should be connected to a CLEAR-Task of the GPIOTE.
    3. CC[1]-Event is shortend with the Clear-Task of the Timer

    The CC[1] defines the period of the resulting signal and the CC[0] value defines the duty cycle.

    Cheers Adrian

Related