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.

  • Ok, so you basically want a timer that counts with a 100µs tick? Or do you want an external trigger? If it is every 100µs you can use the timer for this. I am not really sure what you are requesting here. Did you examine the PPI example that I sent?

Reply Children
  • I want a timer that counts in a cycle of 100 μs.
    I do not want an external trigger.

    I was counting with the following interrupt program, but sometimes I did not get an interrupt, so I asked a question.

    -------------------------------------------------------------

    #include <stdbool.h>
    #include <stdint.h>
    #include "nrf.h"
    #include "nrf_drv_timer.h"
    #include "bsp.h"
    #include "app_error.h"

    #define CONTROL_SAMPLE_RATE 100 /* Control counter sampling rate 100us */
    static const nrf_drv_timer_t Ctl_timer = NRF_DRV_TIMER_INSTANCE(4); /* Timer 4 setting */

    extern uint16_t Control_counter; /* Control counter [0-65535(0-6553.5ms)] (1count:100us) */


    *------------------------------*/
    /* Proguram Proc */
    /*------------------------------*/
    /** @brief Handler for timer4 (100us) events. */
    void timer4_event_handler(nrf_timer_event_t event_type, void* p_context)
    {
     switch (event_type)
     {
     case NRF_TIMER_EVENT_COMPARE4: /* timer 4 events */
      Control_counter ++; /* Control_counter update */
      break;

     default:
      break;
     }
    }

    void Conterl_timer_init(void)
    {
    uint32_t time_ticks;
    uint32_t err_code = NRF_SUCCESS;

     nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
     err_code = nrf_drv_timer_init(&Ctl_timer, &timer_cfg, timer4_event_handler);
     APP_ERROR_CHECK(err_code);

     time_ticks = nrf_drv_timer_us_to_ticks(&Ctl_timer, CONTROL_SAMPLE_RATE);

      nrf_drv_timer_extended_compare(
      &Ctl_timer, NRF_TIMER_CC_CHANNEL4, time_ticks, NRF_TIMER_SHORT_COMPARE4_CLEAR_MASK, true);
     nrf_drv_timer_enable(&Ctl_timer);
    }

    -------------------------------------------------------------

  • Ok, so you want to get an interrupt, but sometimes you do not get them?

    100µs is kind of fast, so it may be that you don't see your interrupts because they are not called due to a higher performance task? How do you determine that you don't get all the interrupts? 

    Do you use the softdevice in your project?

  • The presence or absence of an interrupt was confirmed by port output.
    I use soft devices.
    You need a timer that counts in less than 100 microseconds.

    Counting less than 100us in 1ms divisor


    I want to use a timer that is controlled by hardware, but I do not know how to use it.

  • Ok. so you have the timer set up, which fires every 100ms, and then you increment a counter in the interrupt, right?

    So if you have the timer events,  you can use PPI to connect your timer events to a counter. You need to use another timer, e.g. TIMER3 in counter mode, and have the PPI task to increment this counter. 

    So using PPI, you want to have the PPI.EEP (event end point) to be the timer 4 event, and the PPI.TEP (task end point) to be incrementing the timer.

    Did you examine the PPI example that I sent?

  • Is there a problem with the attached program?
    /**
    
    **/
    #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_EXAMPLE_TIMER0_INTERVAL			(100)	/* Timer interval in 100us */
    
    static const nrf_drv_timer_t m_timer0 = NRF_DRV_TIMER_INSTANCE(0);
    
    static nrf_ppi_channel_t m_ppi_channel1;
    
    static volatile uint32_t m_counter;
    
    
    static void timer0_event_handler(nrf_timer_event_t event_type, void * p_context)
    {
        ++m_counter;
    }
    
    /** @brief Function for initializing the PPI peripheral.	*/
    static void ppi_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_channel1);
        APP_ERROR_CHECK(err_code);
        err_code = nrf_drv_ppi_channel_assign(m_ppi_channel1,
                                              nrf_drv_timer_event_address_get(&m_timer0,
                                                                              NRF_TIMER_EVENT_COMPARE0),
                                              nrf_drv_timer_task_address_get(&m_timer0,
                                                                             NRF_TIMER_TASK_START));
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_ppi_channel_enable(m_ppi_channel1);
        APP_ERROR_CHECK(err_code);
    }
    
    /** @brief Function for Timer 0 initialization.	*/
    static void timer0_init(void)
    {
        nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
        timer_cfg.frequency = NRF_TIMER_FREQ_31250Hz;
        ret_code_t err_code = nrf_drv_timer_init(&m_timer0, &timer_cfg, timer0_event_handler);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_timer_extended_compare(&m_timer0,
                                       NRF_TIMER_CC_CHANNEL0,
                                       nrf_drv_timer_us_to_ticks(&m_timer0,
                                                                 PPI_EXAMPLE_TIMER0_INTERVAL),
                                       NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                       true);
    }
    
    
    /**
     * @brief Function for application main entry.
     */
    int main(void)
    {
        uint32_t old_val = 0;
        uint32_t err_code;
    
        ppi_init();
        timer0_init(); 
    
         /* Start */
        nrf_drv_timer_enable(&m_timer0);
    	
        while (true)
        {
    		/**/
        }
    }
    
    /** @} */
    

Related