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

nRF52 Timer Code Help

Hi

I'm working on a project in which I use a timer to generate two signals that I need to phase shift each other, but at the beginning and at the end it cuts, can anyone advise me how to solve this problem ?. I'm attaching my code and a video to see my issue.

https://www.youtube.com/watch?v=HNIGHqlCFf0

#include <stdbool.h>
#include "nrf.h"
#include "nrf_gpio.h"
#include "boards.h"
#include "nrf_delay.h"

int Frequency = 200;
int Phase_Set = 1;

int Phase[4] = {1, 1, 0, 0};

int cnt = 0;

#define GPIO_OUT_1         NRF_GPIO_PIN_MAP(0,6)
#define GPIO_OUT_2         NRF_GPIO_PIN_MAP(0,8)

void timer_init(int frequency, int phase)
{		
    NRF_TIMER2->SHORTS      = (TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos);
    NRF_TIMER2->MODE        = TIMER_MODE_MODE_Timer;
    NRF_TIMER2->BITMODE     = (TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos);
    NRF_TIMER2->PRESCALER   = 0;
	  NRF_TIMER2->CC[0] = frequency;                             
	  NRF_TIMER2->CC[1] = phase;  
 	
  	NRF_TIMER2->INTENSET = (TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos) | (TIMER_INTENSET_COMPARE1_Enabled << TIMER_INTENSET_COMPARE1_Pos);
	
    NVIC_EnableIRQ(TIMER2_IRQn);		
    NRF_TIMER2->TASKS_START = 1;               
}

void TIMER2_IRQHandler(void)
{
	 if(NRF_TIMER2->EVENTS_COMPARE[0]){
		 	nrf_gpio_pin_toggle(GPIO_OUT_1);           
		  NRF_TIMER2->EVENTS_COMPARE[0] = 0;           
  }
	
	 if(NRF_TIMER2->EVENTS_COMPARE[1]){
		 cnt++;
		 nrf_gpio_pin_write(GPIO_OUT_2,Phase[cnt]);
	   if(cnt == 4)
     cnt = 0;
		 NRF_TIMER2->EVENTS_COMPARE[1] = 0;           
  }
}

int main(void)
{
	NRF_CLOCK->TASKS_HFCLKSTART = 1;
	nrf_gpio_cfg_output(GPIO_OUT_1);       
	nrf_gpio_cfg_output(GPIO_OUT_2);
	timer_init(Frequency,Phase_Set);                              
	
	while(1){
 	Phase_Set++;
  if (Phase_Set == Frequency){
		  Phase_Set = 1;
  }
	NRF_TIMER2->CC[1] = Phase_Set;
	nrf_delay_ms(50); 
	}
}

Parents
  • Hi,

    seems CPU can't get in time to handle your interrupts. For such a high frequencies, it's better to use GPIOTE controlled by timer. You can allocate two GPIOTE channels with MODE=Task, POLARITY=Toggle, then configure their toggling from TIMER events via PPI:

    COMPARE[0] --> GPIOTE->TASKS_OUT[0] and TIMER2->EVENTS_CLEAR,  where CC[0]=frequency

    COMPARE[1] --> GPIOTE->TASKS_SET[1],  where CC[1]=phase

    COMPARE[2] --> GPIOTE->TASKS_CLR[1],  where CC[2]=(phase+frequency/2)%frequency

  • Thank you for your answer, I'm not entirely sure how to do this because the main program must run in TIMER2_IRQHandler nrf_gpio_pin_toggle(GPIO_OUT_1); must remain phase preserved via GPIOTE I only want to scroll GPIO_OUT_2.

Reply Children
Related