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

100us counter

OS in development environment :Windows7
HARD :(Taiyo Yuden)EBSHSN Series Evaluation Board : Central / Peripherals
CPU :(Nordic) nRF52832 / ARMR Cortex?-M4F 32 bit processor 28-pin Land Grid Array / 15GPIOs / SWD
Soft Ver:nRF5_SDK_15.2.0_9412b96

Please tell me the processing method to count variables by 100us without generating interrupt.

Please let me know if there is a sample program

Thank you very much.

Parents
  • Hello,

    What is it that you want to count? Is it a pulse with a period of 100µs?

    That would be possible to count using PPI and a timer. This way, it will work in the background without interrupting the CPU, and you can read out the TIMER registers from your application. 

    We don't have an example doing exactly this, but attached is another project that uses PPI. This can be modified to do what you want. I will try to give a brief explanation on what you have to do.

    So the attached project is a project that uses PPI + TIMER + GPIOTE to generate a PWM signal.

    PPI has two essential elements. EEP and TEP. EEP is the Event that triggers the PPI, while TEP is the task that is performed when the EEP occurs. 

    What you need is to have a PPI set up to trigger an EEP when the signal e.g. goes Low to High, and use the TEP to increment the timer.

    So in this case, you would also need PPI + GPIOTE + TIMER, but unlike the attached example, your GPIOTE is the input/EEP, and the timer is the task/TEP. So you would want to set the timer in counter mode instead of timer mode, and trigger the PPI with EEP = GPIOTE event, and perform the counting on the timer.

    Play around with the project, and see if you can see how it works, and how to modify it, and let me know if you are stuck.

    ppi_double_channel_pwm.zip

    Note: The project contains only a Keil file, and is written in SDK14.0.0, but it doesn't use any drivers, only the registers. So the main.c file should work in any compiler and any SDK. Just take any example from the SDK that you are using (SDK\examples\peripheral\...) and replace the main.c file.

    Best regards,

    Edvin

  • Counting the timer with a 100us interrupt will shift the timer without an interrupt.
    The following processing is performed without generating an interrupt. Please tell me what to do.
    1) Timer counts up every 100 μs
    2) Reset the timer (clear timer 0 at any timing)
    3) Addition to timer (offset addition to timer value)
    Thank you very much.

  • Does the attached program improve the accuracy of the counter?
    /**
    
    **/
    #include <stdint.h>
    
    #include "nrf_delay.h"
    #include "app_error.h"
    
    #include "nrf_drv_ppi.h"
    #include "nrf_drv_timer.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #define PPI_COUNT_TIMER1_COUNT		(10)									/* timer1 count 10 (10us * 10 = 100us) */
    #define PPI_COUNT_TIMER2_INTERVAL	(10)									/* timer2 interval in 10us */
    
    static const nrf_drv_timer_t t1_counter = NRF_DRV_TIMER_INSTANCE(1);		/* timer1 counter mode */
    static const nrf_drv_timer_t t2_cycle = NRF_DRV_TIMER_INSTANCE(2);			/* timer2 100us */
    
    static nrf_ppi_channel_t m_ppi_channel2;
    
    static uint16_t Control_counter = 0;								/* Control counter  [0-65535(0-6553.5ms)] (1count:100us) */
    
    
    /*-----------------------------------------*/
    /*--< Program operation processing area >--*/
    /*-----------------------------------------*/
    
    /*-< Timer event handler. Not used since Timer1 and Timer2 are used only for PPI. >-*/
    static void empty_timer_handler(nrf_timer_event_t event_type, void * p_context)
    {
    }
    
    void timer1_event_handler(nrf_timer_event_t event_type, void* p_context)
    {
                Control_counter ++;				/* Control_counter update */
    }
    
    /*-< Set timer1:CC1 to counter mode		(timer 1 initialization)	>-*/
    static void timer1_counter_init(void)
    {
    	nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    	timer_cfg.mode = NRF_TIMER_MODE_COUNTER;		/* NRF_TIMER_MODE_TIMER -> NRF_TIMER_MODE_COUNTER	*/
    
    	ret_code_t err_code = nrf_drv_timer_init(&t1_counter, &timer_cfg, timer1_event_handler);
    	APP_ERROR_CHECK(err_code);
    
    //	nrfx_timer_capture(&t1_counter, NRF_TIMER_CC_CHANNEL1);
        nrf_drv_timer_extended_compare(&t1_counter,
    									NRF_TIMER_CC_CHANNEL1,
    									COUNT_TIMER1_COUNT,
    									NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK, true);
    }
    
    /*-< Set timer2:CC2 to 100us timer mode		(timer 2 initialization)	>-*/
    static void timer2_cycle_init(void)
    {
        nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    	
    	ret_code_t err_code = nrf_drv_timer_init(&t2_cycle, &timer_cfg, empty_timer_handler);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_timer_extended_compare(&t2_cycle,
    									NRF_TIMER_CC_CHANNEL2,
    									nrf_drv_timer_us_to_ticks(&t2_cycle, PPI_COUNT_TIMER2_INTERVAL),
    									NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK, false);
    }
    
    /*-< PPI controls the process of counting at 100us	(PPI 100us(timer1) counter(timer2) initialization)	>-*/
    static void ppi_Sync_counter_init(void)
    {
    	uint32_t err_code = NRF_SUCCESS;
    
    	err_code = nrf_drv_ppi_init();
    	APP_ERROR_CHECK(err_code);
    
    	err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel2);
    	APP_ERROR_CHECK(err_code);
    
    	err_code = nrf_drv_ppi_channel_assign(m_ppi_channel2,
                                              nrf_drv_timer_event_address_get(&t2_cycle, NRF_TIMER_EVENT_COMPARE2),
                                              nrf_drv_timer_task_address_get(&t1_counter,  NRF_TIMER_TASK_COUNT));
    	APP_ERROR_CHECK(err_code);
    
    	err_code = nrf_drv_ppi_channel_enable(m_ppi_channel2);
    	APP_ERROR_CHECK(err_code);
    }
    
    /*--------------------*/
    /*-< Main process	>-*/
    /*--------------------*/
    int main(void)
    {
    	/* Initialize */
    	ppi_Sync_counter_init();	
    	timer1_counter_init();
    	timer2_cycle_init();	
    	
    	/* Start */
    	nrf_drv_timer_enable(&t1_counter);
    	nrf_drv_timer_enable(&t2_cycle);
    	
    	while (true)
    	{
    		/**/
    	}
    }
    
    /** @} */
    
  • Can you describe the behavior of the counter then? Does it never increment? How do you read the counter?

    If I am going to test the application, please provide the project (Segger embedded studio, Keil or gcc, or something else if you use that). Just .zip the project folder. 

  • "Processing content"
    1) Create 10us with timer2 in timer mode and count timer1.
    2) When timer1 counts 10, an interrupt is generated to count Control_counter.
    ※ Control_counter counts up every 100 μs.
    Timer_ppi.zip
  • An error like the attached image occurred when the PPI + timer function was incorporated into the program.
    The following content is added to the program.
    -----------
    #include "nrf_drv_ppi.h"
    #include "nrf_ppi.h"
    ------------
    Please tell me how to respond.


  • You must also add the .c files to your project. nrf_drv_ppi.c and nrfx_ppi.c.

    Also, make sure that NRFX_PPI_ENABLED is defined as 1 in sdk_config.h.

Reply Children
No Data
Related