Hur kan man mäta exekveringstiden i main? Jag använder 16C745 men vill typ sampla med 100Hz. Jag har försökt lägga in delayer men får inte nån kontrolll över det.
Hur kan man konfigurera timern så att önskat resultat kan fås?
Mäta tiden i main()
Kolla databladet för att se hur Timer1 fungerar. Timer1 är på 16-bitar så det räcker för att dela ner frekvensen till 100Hz, den har även en prescaler som man kan ställa in. Sedan kommer ett avbrott varje gång timern räknat fram ett varv.
Vilken kompilator har du? Avbrottshantering kan se lite olika ut för olika kompilatorer, men du kanske har en manual som beskriver det?
/Johan
Vilken kompilator har du? Avbrottshantering kan se lite olika ut för olika kompilatorer, men du kanske har en manual som beskriver det?
/Johan
Det beror ju på kristallfrekvens osv men i grova drag:
Räkna ut pre- och postscale samt timervärde.
Programmera in dessa värden.
Sen beror det ju på om du vill ha en interrupt som ska sampla eller om du vill köra "manuellt", interrupt metoden medför att man tillåter timer-interrupten samt global interrupt (GIE-bitten), den "manuella" metoden medför att du måste kolla timerns "overflow"-flagga och reagerar på den. I denna reaktion ska du komma ihåg att, som det första, nolla flaggan igen.
Räkna ut pre- och postscale samt timervärde.
Programmera in dessa värden.
Sen beror det ju på om du vill ha en interrupt som ska sampla eller om du vill köra "manuellt", interrupt metoden medför att man tillåter timer-interrupten samt global interrupt (GIE-bitten), den "manuella" metoden medför att du måste kolla timerns "overflow"-flagga och reagerar på den. I denna reaktion ska du komma ihåg att, som det första, nolla flaggan igen.
Så här skrev jag min kod för att få konstant tid (90mS) om man är riktig noga får man räkna bort initiering instruktionerna för timern också men i mitt fall spelade det ingen roll. Processorn som jag använde är 16F870
while (1) {
/* Start the timer on 90mS so we get constant time while loop */
TMR1ON = OFF ; /* Timer1 off */
TMR1IF = 0; /* clear Timer1 overflow bit */
TMR1H = 0x50; /* set time 90mS (0xFFFF -0xAFC8)*/
TMR1L = 0x38; /* set time */
TMR1ON = ON ; /* Timer1 is started */
IR_send(); /* Send IR data to Pioneer GPS */
Keyboard();
Joystick();
Rear_camera();
asm ("clrwdt");
while (!TMR1IF) { /* waiting if timer1 is overflow */
asm ("clrwdt");
}
}
while (1) {
/* Start the timer on 90mS so we get constant time while loop */
TMR1ON = OFF ; /* Timer1 off */
TMR1IF = 0; /* clear Timer1 overflow bit */
TMR1H = 0x50; /* set time 90mS (0xFFFF -0xAFC8)*/
TMR1L = 0x38; /* set time */
TMR1ON = ON ; /* Timer1 is started */
IR_send(); /* Send IR data to Pioneer GPS */
Keyboard();
Joystick();
Rear_camera();
asm ("clrwdt");
while (!TMR1IF) { /* waiting if timer1 is overflow */
asm ("clrwdt");
}
}
Ett annat trick man kan använda är att utnyttja CCP-modulen (om den inte redan används till annat). Jag har gjort det för att få exakta timer-interrupt till en realtidsklocka (annars riskerar man småfel på grund av andra interrupt osv).
Jag citerar från databladet:
Jag citerar från databladet:
Dessutom kan man få en "special event" att köra igång AD-omvandlaren automatiskt!The special event trigger output of CCP1 resets the TMR1
register pair. This allows the CCPR1 register to effectively
be a 16-bit programmable period register for Timer1.
Det har jag aldrig testat själv, men det låter som den perfekta lösningen på att sampla i konstant och exakt hastighet.The special event trigger output of CCP2 starts an A/D
conversion (if the A/D module is on) and resets the
TMR1 register pair and starts an A/D conversion (if the
A/D module is enabled).