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

comprehension question Timer

Hi,

maybe i have a silly question, but i didn't programm timers before. I know how they work. But how is it possible that there are only three Timers in the 51822 and so many parts of the programm part (PWM,BLE,GPIOTE...) which need a timer? How can i organize my timers?

and is it possible to run one timer and write a function like "get_actual_time" which gives me the time in the moment i call the function?

Best reagards, Nils :)

Parents
  • Hi Nils,

    I don't have any sample code of the round robin scheduler that I can share.

    But I have attached my code for setting up RTC1 for a 1ms interrupt, with two 32 bit counters for milliseconds and seconds since the "beginning of time" .

    To build the scheduler, you would add the timer_variables and bool stuff after line 73.

    You can use either of the two 32 bit counters to do some other neat things in your code, like this:

    [b] temp = RTC1_Milliseconds; while(RTC1_Milliseconds < (temp+37)) {} // wait here for 37 ms

    temp = RTC1_Seconds;
    {
        // lots of stuff goes in here that takes a long time to execute
    }
    printf("Execution time in seconds:  %6d\n", RTC1_Seconds - temp);[/b]
    

    The example code supplied refers to one of my header files, which must also be included in routines that use this stuff. the only relevant lines to this example in the header are:

    [b]extern uint32_t RTC1_Milliseconds; extern uint32_t RTC1_Seconds; [/b]

    Enjoy.

    RTC1_ms_timer.c

  • Hi Nils,

    I am delighted that my comments and example code are helping you.

    The PRESCALER register is set to 31 because the actual divide operation is the register value + 1. This is shown in the first formula in 18.1.2

    So if you want to divide by 32, you load PRESCALER with 31. Although 2 examples are given they are not clear enough about what is going on. Here is what I would add to the first example:

    round(32768/100) - 1 = round(327.68) - 1 = 328 - 1 = 327 So PRESCALER is set to 327, and the LFCLK is divided by 328 giving 99.9 Hz

    You wrote "Why restarts the rtc_counter if it is bigger then 42?" In my example code, I do not reset the rtc_counter if it is bigger than 42. The rtc_counter is never reset, it just keeps counting at 1024 Hz, due to the divide by 32 of the LFCLK (because PRESCALER is 31). In fact my code doesn't even care about the value in COUNTER. But every time COUNTER is incremented (every 976.5625 us), a TICK interrupt also occurs, and that is what I use for the rest of my code.

    So the RTC1 causes an interrupt at slightly faster than every millisecond (976.5625 us) and so on each tick, the "millisecond clock gains 23.4375 us". After 1 second of real time, the RTC1_Milliseconds value would be 1024 (which is no surprise, since the RTC1 is running at 1024 Hz).

    So how do you make it increase by 1000 every second, rather than 1024. We could just subtract 24 once per second, but that would be a big jump. Instead I decided to not do the increment (skip it) on 24 occurrences during the 1 second period, and spread these skips out evenly during the 1 second. So if you increment RTC1_Milliseconds every tick (at 1024 Hz) but after 41 of these, on the next tick we don't do the increment, then after 1024 interrupts (ticks) the RTC1_Milliseconds will have increased by 1000. RTC1_skip_increment_counter is what controls this.

Reply
  • Hi Nils,

    I am delighted that my comments and example code are helping you.

    The PRESCALER register is set to 31 because the actual divide operation is the register value + 1. This is shown in the first formula in 18.1.2

    So if you want to divide by 32, you load PRESCALER with 31. Although 2 examples are given they are not clear enough about what is going on. Here is what I would add to the first example:

    round(32768/100) - 1 = round(327.68) - 1 = 328 - 1 = 327 So PRESCALER is set to 327, and the LFCLK is divided by 328 giving 99.9 Hz

    You wrote "Why restarts the rtc_counter if it is bigger then 42?" In my example code, I do not reset the rtc_counter if it is bigger than 42. The rtc_counter is never reset, it just keeps counting at 1024 Hz, due to the divide by 32 of the LFCLK (because PRESCALER is 31). In fact my code doesn't even care about the value in COUNTER. But every time COUNTER is incremented (every 976.5625 us), a TICK interrupt also occurs, and that is what I use for the rest of my code.

    So the RTC1 causes an interrupt at slightly faster than every millisecond (976.5625 us) and so on each tick, the "millisecond clock gains 23.4375 us". After 1 second of real time, the RTC1_Milliseconds value would be 1024 (which is no surprise, since the RTC1 is running at 1024 Hz).

    So how do you make it increase by 1000 every second, rather than 1024. We could just subtract 24 once per second, but that would be a big jump. Instead I decided to not do the increment (skip it) on 24 occurrences during the 1 second period, and spread these skips out evenly during the 1 second. So if you increment RTC1_Milliseconds every tick (at 1024 Hz) but after 41 of these, on the next tick we don't do the increment, then after 1024 interrupts (ticks) the RTC1_Milliseconds will have increased by 1000. RTC1_skip_increment_counter is what controls this.

Children
No Data
Related