-
Notifications
You must be signed in to change notification settings - Fork 76
Open
Description
Hi,
yesterday I did some easy application, which needs to generate 2 millisecond pulse. Very easy, so I used:
digitalWrite(MyPin, HIGH);
delay(2);
digitalWrite(MyPin, LOW);
Nothing special, but I was surprised, that pulse is not 2ms, but 1ms > pulse > 2ms. So I go to delay()
implementation and found, that it count number of milliseconds from SysTick
(System Counter). But the first millisecond is not properly rounded.
To demonstrate issue, let us have time scale like following. It present 2 milliseconds of time, each millisecond is split to "J" tenths.
0 1 2
| | |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| | | | | | | | | | | | | | | | | | | | |
A B C D E F G H I J A B C D E F G H I J A
situation - when delay(2)
is called in time 0.A, it will take almost 2ms. in case delay(2)
is called in time 0.J, it will take 1.1 ms only.
so, looking how to "fix" it. It seems, it will be easy fix like:
uint64_t m0 = GetTick();
__IO uint32_t u0 = SysTick->CNT;
uint64_t m1 = GetTick();
__IO uint32_t u1 = SysTick->CNT; //may be a interruption
if (m1 != m0) {
do { // full millisecond
yield();
} while (getCurrentMillis() - m1 < ms);
do { // remaining partial millisecond
yield();
} while ((SysTick->CNT < u1 ) && (getCurrentMillis() - m1 < (ms + 1)));
} else {
do { // full millisecond
yield();
} while (getCurrentMillis() - m0 < ms);
do { // remaining partial millisecond
yield();
} while ((SysTick->CNT < u0 ) && (getCurrentMillis() - m0 < (ms + 1)));
}
I need to check and spent some time on it.
Metadata
Metadata
Assignees
Labels
No labels