Help with Free Running Timers
Ian Shannon Weber wrote 04/29/2020 at 00:51 • 0 pointsTechnical Context: I am working on a project that uses the PIC18F45K20. This is a project to learn more and help develop my skills. I am making a cable tester so I am firing an output and watching an input.
Problem: I am having issues comprehending how a free running timer works. I understand that provided that I have not overflowed my timer. When I call a function, get the time from my timer buffer if it is the "first" call, else see if CURRENT_TIME - START_TIME = DESIRED_ELAPSED_TIME. I am just not sure how to handle if my CURRENT_TIME is less than my START_TIME.
Does anybody have a guide or advice on how to understand this?
I have tried the following trail of logic and failed on some level:
If CURRENT_TIME is greater than START_TIME than does CURRENT_TIME minus START_TIME equal DESIRED_ELAPSED_TIME or more? If yes do some code.
Else If CURRENT_TIME is less than START_TIME than does 0xFFFF (16 bit timer maximum value) minus START_TIME plus CURRENT_TIME equal DESIRED_ELAPSED_TIME or more? If yes do some code.
Else return to main loop.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.
If START_TIME and CURRENT_TIME are both unsigned, calculating the difference will between the two will always be correct, even if CURRENT_TIME has overflows. This is because calculating the difference in that case will also overflow, resulting in a correct value.
Are you sure? yes | no
As said above, you have to track the timer overflow, either :
Set the timer and the overflow to 0 when you start counting, then with you end interrupt you read both value and do the math.
Else just save the current timer and overflow value when starting counting, then compare when you end it.
Be sure your overflow counter variable cannot be overflow itself : a 16 bits counter running at 16MHz is around 244ms, it can go fast.
Are you sure? yes | no
In order to correctly deal with timer overflow(s) you need a counter that tracks the number of overflows (usually you'd increment that in the timer overflow interrupt). Then when you get START_TIME, also get the current overflow count (or set it to zero if no other code depends on it). When you're checking to see how much time is passed you A) know if an overflow happened and B) how many overflows. In pseudocode that would look something like this:
When starting:
START_TIME = getTimerValue();
START_OVERFLOWS = getTimerOverflowCount();
When checking the elapsed time:
ELAPSED_TIME = (getTimerOverflowCount() - START_OVERFLOWS) * 0xFFFF + (getTimerValue() - START_TIME);
Are you sure? yes | no
Maybe a datatype and overflow issue. Similar discussed here: https://www.norwegiancreations.com/2018/10/arduino-tutorial-avoiding-the-overflow-issue-when-using-millis-and-micros/
Are you sure? yes | no