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

Measuring elapsed microseconds between 12 successive rising edges on 12 GPIOS on NRF52832 DK

Hi everyone,

I'm new with nrf52832, and I need to measure elapsed time in microsecond between rising edges of 12 different Gpios. I have 12 piezoelectric sensors filtered, amplified, getting a 0V-3.3V Logic level in input. Once one of these senors rises up, I need to start counting microseconds and store corresponding elapsed microsecond until I have 11 different values (assuming the first sensor's timing is 0). And then posting it over ble.

I red some documentations, and I heard about Timeslot API, timers and sys_tick, but I don't know which one would be better for my application.

Would you have any idea about how should I take this ?

Thanks for your help, and have a good day !

Parents
  • Below is my implementation of a microsecond timer. This is old code (SDK 10 for NRF51), so it will not run right away, but should point you in the right direction.

    #include "nrf.h"
    #include "nrf_drv_timer.h"
    #include "bsp.h"
    
    #include "debug.h"
    
    #include "timer.h"
    
    uint64_t timer_micros = 0;
    
    uint32_t timer_ticks; // set in timer_init()
    uint32_t timer_interval = 1000000; // us
    uint64_t timer_last = 0;
    
    // COMPARE0 is used for overflow
    // COMPARE3 is used for reading the timer
    
    int pin_state = 0;
    
    void timer_event_handler(nrf_timer_event_t event_type, void* p_context)
    {
    	if ( event_type != NRF_TIMER_EVENT_COMPARE0 )
    		return;
    
    	if ( pin_state == 0 ) {
    		pin_state = 1;
    		nrf_gpio_pin_set(PIN_TIMER);
    	} else {
    		pin_state = 0;
    		nrf_gpio_pin_clear(PIN_TIMER);
    	}
    	
    	timer_micros = timer_micros + timer_ticks;
    	
    	if ( timer_micros >= timer_last + timer_interval ) {
    		timer_last = timer_micros;
    		timer_callback();
    	}
    }
    
    // Run on TIMER1
    // Timer must be enabled in nrf_drv_config.h
    const nrf_drv_timer_t timer = NRF_DRV_TIMER_INSTANCE(1);
    nrf_drv_timer_config_t timer_config;
    
    uint64_t timer_read(void)
    {
    	uint32_t ticks = nrf_drv_timer_capture(&timer, NRF_TIMER_CC_CHANNEL3);
    	uint64_t ret = timer_micros + ticks;
    	return ret;
    }
    
    void timer_init(void)
    {
    	// TIMER0 is 32-bit, TIMER1 & 2 are 16-bit
    	timer_config.bit_width = NRF_TIMER_BIT_WIDTH_16;
    	timer_config.frequency = NRF_TIMER_FREQ_1MHz;
    	timer_config.interrupt_priority = 1; // 0 = highest, 3 = lowest
    	timer_config.mode = NRF_TIMER_MODE_TIMER;
    	
    	
    	uint32_t err_code = NRF_SUCCESS;
    	err_code = nrf_drv_timer_init(&timer, &timer_config, timer_event_handler);
    	if ( err_code != NRF_SUCCESS )
    		_ERROR("nrf_drv_timer_init() failed");
    	
    	uint32_t time_ms = 50;
    	timer_ticks = nrf_drv_timer_ms_to_ticks(&timer, time_ms);
    	if ( timer_ticks > 65535 )
    		_ERROR("Timer frequency too high");
    	
    	_DEBUG ("Timer: interrupt every %d ms, %d ticks per interrupt\n", time_ms, timer_ticks);
    	
    	nrf_drv_timer_extended_compare(
    		 &timer, NRF_TIMER_CC_CHANNEL0, timer_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
    	
    	nrf_drv_timer_enable(&timer);
    	
    }
    
Reply
  • Below is my implementation of a microsecond timer. This is old code (SDK 10 for NRF51), so it will not run right away, but should point you in the right direction.

    #include "nrf.h"
    #include "nrf_drv_timer.h"
    #include "bsp.h"
    
    #include "debug.h"
    
    #include "timer.h"
    
    uint64_t timer_micros = 0;
    
    uint32_t timer_ticks; // set in timer_init()
    uint32_t timer_interval = 1000000; // us
    uint64_t timer_last = 0;
    
    // COMPARE0 is used for overflow
    // COMPARE3 is used for reading the timer
    
    int pin_state = 0;
    
    void timer_event_handler(nrf_timer_event_t event_type, void* p_context)
    {
    	if ( event_type != NRF_TIMER_EVENT_COMPARE0 )
    		return;
    
    	if ( pin_state == 0 ) {
    		pin_state = 1;
    		nrf_gpio_pin_set(PIN_TIMER);
    	} else {
    		pin_state = 0;
    		nrf_gpio_pin_clear(PIN_TIMER);
    	}
    	
    	timer_micros = timer_micros + timer_ticks;
    	
    	if ( timer_micros >= timer_last + timer_interval ) {
    		timer_last = timer_micros;
    		timer_callback();
    	}
    }
    
    // Run on TIMER1
    // Timer must be enabled in nrf_drv_config.h
    const nrf_drv_timer_t timer = NRF_DRV_TIMER_INSTANCE(1);
    nrf_drv_timer_config_t timer_config;
    
    uint64_t timer_read(void)
    {
    	uint32_t ticks = nrf_drv_timer_capture(&timer, NRF_TIMER_CC_CHANNEL3);
    	uint64_t ret = timer_micros + ticks;
    	return ret;
    }
    
    void timer_init(void)
    {
    	// TIMER0 is 32-bit, TIMER1 & 2 are 16-bit
    	timer_config.bit_width = NRF_TIMER_BIT_WIDTH_16;
    	timer_config.frequency = NRF_TIMER_FREQ_1MHz;
    	timer_config.interrupt_priority = 1; // 0 = highest, 3 = lowest
    	timer_config.mode = NRF_TIMER_MODE_TIMER;
    	
    	
    	uint32_t err_code = NRF_SUCCESS;
    	err_code = nrf_drv_timer_init(&timer, &timer_config, timer_event_handler);
    	if ( err_code != NRF_SUCCESS )
    		_ERROR("nrf_drv_timer_init() failed");
    	
    	uint32_t time_ms = 50;
    	timer_ticks = nrf_drv_timer_ms_to_ticks(&timer, time_ms);
    	if ( timer_ticks > 65535 )
    		_ERROR("Timer frequency too high");
    	
    	_DEBUG ("Timer: interrupt every %d ms, %d ticks per interrupt\n", time_ms, timer_ticks);
    	
    	nrf_drv_timer_extended_compare(
    		 &timer, NRF_TIMER_CC_CHANNEL0, timer_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
    	
    	nrf_drv_timer_enable(&timer);
    	
    }
    
Children
Related