Alltså... jag förstår att det är data från en GPS och att de kommer med 1 sekunds intervall.
Dessa dekodas till verkliga värden och när den del är klart ligger dessa värden i minnet.
När de är konverterat passar du på att sätt en flagga! Denna flagga betyder "nu ska det räknas på detta" och uträkningen utförs. När den uträkning är avklarat nollar rutinen flaggan.
Då behövs ingen interrupt eller liknande, det hela kan ligga i main-loop och bara uppdatera just när nya värden är läst in.
Om din main-loop kan ta upp till 1 sekund eller mer att göra är det en del andra fel i den och hela strukturen ska göras om från grunden!
Själva styrdelen kan fint göras medelst interrupt men basen är att man inte kan vara säker på att GPS-data och interrupten passar överens! In interrupten kan man även ha en time-out som varna om det inte finns nya data, det kan vara så enkelt som att man för varje omvandling av GPS-data ställer en räknare till 2. I 1-sek-ISR'n räknar man sedan denna räknare ner ett steg om den är större än noll. Om den då når noll är det ingen nya GPS-data och lämplig uppgift ska då utföras (larm?).
Det låter som att hela programstrukturen är ganska osäker än så länge, det behöver inte vara ett stort problem om det är för att testa underrutiner och dylikt men är det såhär det ska fungera i verkliga livet får du problem!
Ursprungsfrågan om hur du får rätt värde när du jämför två kurser har inget med asm eller annat att göra, det är en ren matte-fråga. Kan du lösa den för alla värden på papper kan du göra det samma i ASM eller C eller vilket programmeringsspråk som helst egentligen.
Problemet med ASM i detta fall är att det snabbt blir ganska svårt att överskåda och med en kass struktur i programmet blir det rent av en katastrof.
Mycket ofta/alltid består ett µC-program av:
* Startkod. Kan vara att nollställa minnet eller liknande. I C är denna biten oftast innan själva C-programmet börjar.
* Sedan börjar själva programmet, i C med "void main(void)".
* Initiering av hårdvara utförs.
* Initiering av värden utförs.
* Sedan kommer den eviga loopen som oftast kallas "main-loop". I den kan de ske mycket eller lite, helt beroende på strukturen.
I många fall använder man interruptrutiner (ISR = Interrupt Service Routine) för att ta hand om saker, det kan vara timerinterrupt, serieportshändelser, AD-omvandlingar som blir klara osv. Alla dessa ISR ska vara snabba och effektiva! Inget väntande!
Main-loop bör vara snabb och effektiv! Om det väntas på ett villkor för att en sak ska hända kan man likaväl bara hoppa förbi den bit om saken inte är klar, sedan kan den ta hand om resten under tiden.
Jag brukar mäta main-loop tiden i mina projekt om jag kan och den har väl i ett extremfall varit upp i 200ms...
Vill man att en sak ska ske efter en viss tid och exakt timing inte är det viktigaste (tänk en display med "Välkommen, nu startar programmet" som ska visas i 5 sekunder -eller en lampa som ska blinka i sakta mak) kan man ha en timer-ISR som sker med lagom mellanrum. Jag har ofta 10Hz men andra värden kan användas.
Om man då har en variabel ("Delay") som timer-ISR'n använder på följande sätt:
if(Delay) Delay--; // På icke-C: om Delay>0 räkna ner Delay med en.
Då kan man annorstädes i koden skriva:
Show_Sign_On = true; // Placeras innan main-loop t.ex.
I main-loop kan man då ha en snudd:
Kod: Markera allt
if(Show_Sign_On)
{
Show_Sign_On = false;
Do_The_Show_Sign_On(); // Skriv ut vad som ska skrivas till displayen som välkomsthälsning
Delay = 50; // Ger 5 sekunders delay vid 10Hz
}
Detta ger ju bara en start av visningen men resten ska ju inte stå still för det:
Kod: Markera allt
if(!Delay) // Betyder "om Delay inte är > 0"
{
<Skriv den normala uppdatering på displayen>
}
Då kan hela main-loop köra full fart utan problem och är inte vissa saker klar kan man hoppa vidare fram till de är det. Såklart gäller detta många andra saker, det kan vara att man bara behöver reagera på en ändring an en ingång eller liknande, är den inte ändrat går programmet bara vidare.