|
 |
 |
 |
|
|
c't Projekte - c't-Bot und c't-Sim -
Mailinglisten
[Voriger (Datum)]
[Nächster (Datum)]
[Voriger (Thread)]
[Nächster (Thread)]
[Nach Datum][Nach Thread]
Absender: Jörg Schüler-Maroldt
Datum: Mo, 18.09.2006 15:21:58
Hallo,
die delay-Funktion im ct-Bot funktioniert so nicht sauber.
Der Fehler liegt in der timer.c / timer.h
Der Aufruf von timer_get_ms() und timer_get_s() nacheinander kann immer
durch einen Interrupt unterbrochen werden und beim Überlauf von time_ms
Differenzen von einer
Sekunde hervorrufen.
Es müßte deshalb eine Funtion geben die ms und s zusammen zurückliefert.
timer_get_time(uint16 *pSec, uint16 * pmSec, uint16 *puSec);
Was ihr eigentlich wollt ist jedoch folgendes:
// Global
volatile uint16 time_ms_tick;
//Private
static volatile uint16 time_micro_s;
// Timer Interrupt
void system_time_isr(void)
{
// Disable Interrupt
time_micro_s += TIMER_STEPS; /* Mikrosekundentimer erhoehen */
if (time_micro_s >= 1000)
{ /* Eine Mikrosekunde verstrichen? */
time_ms_tick++;
time_micro_s -= 1000;
}
// enable Interrupt
}
// Delay in ms
void delay(uint16 ms)
{
uint t1=time_ms_tick;
while ((time_ms_tick - t1) < ms)
{
asm volatile("nop");
}
}
Der Zugriff auf eine 16-Bit Variable (time_ms_tick) kann nicht unterbrochen
werden,
da es sich nur um eine Assembler-Anweisung handelt.
Für größere Zeiten als 65s sollte man eine 32-Bit Variable verwenden, muß
jedoch den Zugriff synchronisieren.
Bei 32-Bit Prozessoren (PC) geht`s natürlich ohne.
Falls der "time_ms_tick" überläuft rechnet die Delay-Funtion trotzdem
richtig.
Die "uint16 timer_get_ms_since(uint16 old_s, uint16 old_ms )"
ist damit hinfällig, da Sie die gleichen Probleme hat.
Die Zeitanzeige ist mit:
{
uint16 tNow=time_ms_tick;
printf("%d.%d s",tNow/1000,tNow%1000);
}
auch kein Problem, läuft jedoch nach 65s über.
Für genauere Auflosungen benötigt man evtl. auch noch "time_us_tick"
Ein Problem ist jedoch die Änderung der ct-Bot Software.
Ich würde vorschlagen als erstes die time_ms_tick Variable in timer.c
einzubauen
und delay() richtig zu implementieren.
timer_get_ms_since() usw. kann man dann für veraltet zu erklären und den
Code bereinigen.
Den Patch für den Code könnte ich machen, falls diese Begründung
einleuchtend ist.
Gruß
Jörg Schüler-Maroldt
|
|
|