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

UART + Timer Issue NRF51

Hi,

I am using the following code to implement a millisecond timer read function. In main, while loop, I do nothing but run a 1ms delay and measure the time in mill second before and after and print the difference with uart over serial terminal. The output I get is 1ms but after every 12 odd readings I get 984ms as output and this continues.

Is this due to the uart or is there some issue with the timer implementation. Would appreciate the help. Thanks. 

#include <stdio.h>
#include "boards.h"
#include "app_util_platform.h"
#include "app_uart.h"
#include "app_error.h"
#include "nrf_delay.h"


/*UART buffer size. */
#define UART_TX_BUF_SIZE 256
#define UART_RX_BUF_SIZE 1


uint32_t time;

#define MY_TIMER NRF_TIMER1
#define MY_TIMER_IRQn TIMER1_IRQn
#define MY_TIMER_IRQHandler TIMER1_IRQHandler

static uint32_t my_timer_seconds;

static void my_timer_start(void)
{
// Reset the second variable
my_timer_seconds = 0;

// Ensure the timer uses 24-bit bitmode or higher
MY_TIMER->BITMODE = TIMER_BITMODE_BITMODE_24Bit << TIMER_BITMODE_BITMODE_Pos;

// Set the prescaler to 4, for a timer interval of 1 us (16M / 2^4)
MY_TIMER->PRESCALER = 4;

// Set the CC[0] register to hit after 1 second
MY_TIMER->CC[0] = 1000000;

// Make sure the timer clears after reaching CC[0]
MY_TIMER->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Msk;

// Trigger the interrupt when reaching CC[0]
MY_TIMER->INTENSET = TIMER_INTENSET_COMPARE0_Msk;

// Set a low IRQ priority and enable interrupts for the timer module
NVIC_SetPriority(MY_TIMER_IRQn, 3);
NVIC_EnableIRQ(MY_TIMER_IRQn);

// Clear and start the timer
MY_TIMER->TASKS_CLEAR = 1;
MY_TIMER->TASKS_START = 1;
}

static uint32_t my_timer_get_ms(void)
{
// Store the current value of the timer in the CC[1] register, by triggering the capture task
MY_TIMER->TASKS_CAPTURE[1] = 1;

// Combine the state of the second variable with the current timer state, and return the result
return (my_timer_seconds * 1000) + (MY_TIMER->CC[1] / 1000);
}

static uint64_t my_timer_get_us(void)
{
// Store the current value of the timer in the CC[1] register, by triggering the capture task
MY_TIMER->TASKS_CAPTURE[1] = 1;

// Combine the state of the second variable with the current timer state, and return the result
return (uint64_t)my_timer_seconds * 1000000 + MY_TIMER->CC[1];
}

// Timer interrupt handler
void MY_TIMER_IRQHandler(void)
{
if(MY_TIMER->EVENTS_COMPARE[0])
{
MY_TIMER->EVENTS_COMPARE[0] = 0;

// Increment the second variable
my_timer_seconds++;
}
}

/**
* @brief UART events handler.
*/
static void uart_events_handler(app_uart_evt_t * p_event)
{
switch (p_event->evt_type)
{
case APP_UART_COMMUNICATION_ERROR:
APP_ERROR_HANDLER(p_event->data.error_communication);
break;

case APP_UART_FIFO_ERROR:
APP_ERROR_HANDLER(p_event->data.error_code);
break;

default:
break;
}
}


/**
* @brief UART initialization.
*/
static void uart_config(void)
{
uint32_t err_code;
const app_uart_comm_params_t comm_params =
{
RX_PIN_NUMBER,
TX_PIN_NUMBER,
RTS_PIN_NUMBER,
CTS_PIN_NUMBER,
APP_UART_FLOW_CONTROL_DISABLED,
false,
UART_BAUDRATE_BAUDRATE_Baud115200
};

APP_UART_FIFO_INIT(&comm_params,
UART_RX_BUF_SIZE,
UART_TX_BUF_SIZE,
uart_events_handler,
APP_IRQ_PRIORITY_LOW,
err_code);

APP_ERROR_CHECK(err_code);
}



/**
* @brief Function for main application entry.
*/
int main(void)
{


uart_config();
my_timer_start();

uint8_t reg = 0;
ret_code_t err_code;

while(true)
{
time=my_timer_get_ms();
nrf_delay_ms(1);
printf("%i\n", my_timer_get_ms()-time);

}
}

/** @} */

Related