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

Reply
  • 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

Children
  • Hi Philip,

    thanks for this great answer you helped me pretty much with the understanding how to use the rtc or the timer.

    Thanks for this great example, perfect for me but i have some question.

    • Why is the prescaler 31, you want to devide the timervalue by 32 is 31 right?
    • Why restarts the rtc_counter if it is bigger then 42 ? why this value?

    Thank you for helping, i am a newbie who trys to understand all this stuff. It is a lot to learn but with such examples it works fine :)

  • 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.

  • Hi Philip,

    thanks for your answer, it works. But i changed the parameters like the preascaler. I messeured with the oscilloscope and when i take a prescaler with (idon#t know the exact value,i have to look on monday) 33 or 34 i get aa perfect millisecond. why don't i get the calculated time?

    best regards Nils

  • The accuracy of the frequency you get from RTC0 or 1 depends on the accuracy of LFCLK. In my example function RTC1_ms_timer.c , I have selected the RC oscillator on line 36. In the reference manual on page 54, LFCLKSRC has 3 possible choices. If you use either the synthesizer, or the 32768 Hz external crystal, you will have accuracy that depends on the crystal, probably around 60 ppm. On page 34 of the product spec, the spec fTOL,RC32k is given as +/- 2% , which is +/- 20000 ppm .

    There is also a calibration process that can use the 16MHz oscillator to temporarily (4 seconds according to fTOL,CAL,RC32k) improve accuracy of the RC oscillator to +/- 250 ppm. I've read the description in the ref manual at 12.1.3 , page 51, the information provided is insufficient for me to figure out how this should be used. I could not find any examples for this part of the chip.

    If you just want an approximate 1 ms tick, then the RC oscillator may be sufficient. If you need a more accurate tick, then use either the synthesizer (which needs the 16MHz crystal) or use the 32768 Hz crystal.

    Also, although you write "a perfect millisecond" , I suspect that it is just close, rather than perfect. Watch the signal on the oscilloscope, as you apply heat (hot air gun) or cold (can of instant freeze) to the chip, and you will see that it is temperature dependent. Probably also dependent on VCC.

  • Hi Philip,

    thanks for your usefull informations. Every time you telling me how to understand the things i realy get more and more points of reference (sorry for my english, i am german :D), thanks because this is great for a newbie. I just read the part you told me. Is it better , for tempreture compensating, to use an RC or an XTAL or to synth?

    Why does it depent on Vcc ?

    best regards Nils :)

Related