Timer0 och PIC16F877A
Timer0 och PIC16F877A
Jag försöker göra en 1 sekunds timer med hjälp av den inbyggda Timer0 och avbrott. Men dom enda resultaten jag får är en för snabb timer eller ingen som fungerar.
Är det någon som råkar ha kod för detta, helst i C men det ska nog gå att konvertera i värsta fall.
Är det någon som råkar ha kod för detta, helst i C men det ska nog gå att konvertera i värsta fall.
#define TIMER0_PRESCALAR 0b111 //1:256
#define TIMER0_HOW_MANY_INTS 46 //ceiling(TIMER0_INTERVAL/((1/PIC_CLK) * TIMER0_PRESCALAR)/255)
int TMR0_BIG_VALUE = TIMER0_HOW_MANY_INTS;
bit ReadTemp_Part2_Done;
bit ReadTemp_INT_recived;
//Testa timer0
while(1)
{
ReadTemp_INT_recived=0;
OPTION|=TIMER0_PRESCALAR;
TMR0_BIG_VALUE = 1;TIMER0_HOW_MANY_INTS;
TMR0=0x00;
T0IE=1;
while(!ReadTemp_INT_recived);
lcd_clear();
lcd_hexa(testtmr++);
};
void interrupt ISR()
{
//Timer0
if (T0IF)
{
if (!(TMR0_BIG_VALUE--))
{
//Stänger av den gamla timningen för tillfället...
T0IF=0;
//Säger till huvudkoden att temperaturen kan hämtas...
ReadTemp_INT_recived = 1;
}
else
{
//Sätter igång en ny TMR0...
OPTION|=TIMER0_PRESCALAR;
TMR0=0x00;
T0IF=0;
}
}
}
#define TIMER0_HOW_MANY_INTS 46 //ceiling(TIMER0_INTERVAL/((1/PIC_CLK) * TIMER0_PRESCALAR)/255)
int TMR0_BIG_VALUE = TIMER0_HOW_MANY_INTS;
bit ReadTemp_Part2_Done;
bit ReadTemp_INT_recived;
//Testa timer0
while(1)
{
ReadTemp_INT_recived=0;
OPTION|=TIMER0_PRESCALAR;
TMR0_BIG_VALUE = 1;TIMER0_HOW_MANY_INTS;
TMR0=0x00;
T0IE=1;
while(!ReadTemp_INT_recived);
lcd_clear();
lcd_hexa(testtmr++);
};
void interrupt ISR()
{
//Timer0
if (T0IF)
{
if (!(TMR0_BIG_VALUE--))
{
//Stänger av den gamla timningen för tillfället...
T0IF=0;
//Säger till huvudkoden att temperaturen kan hämtas...
ReadTemp_INT_recived = 1;
}
else
{
//Sätter igång en ny TMR0...
OPTION|=TIMER0_PRESCALAR;
TMR0=0x00;
T0IF=0;
}
}
}
Väldigt dåligt med kommenterar !! Det är inte lätt
att gissa vad *du* trodde att du gjorde när du skrev koden...
Men ett par saker i alla fall...
Varför sätter du om OPTION i ISR'en ?
Varför sätter du TMR0 = h'00' i ISR'en ?
> //Stänger av den gamla timningen för tillfället...
> T0IF=0;
Vad är det du stänger av här ?
> Men dom enda resultaten jag får är en för snabb timer eller ingen som fungerar.
Helt slumpmässigt ?
Eller när inträffar det ena resp det andra ?
att gissa vad *du* trodde att du gjorde när du skrev koden...
Men ett par saker i alla fall...
Varför sätter du om OPTION i ISR'en ?
Varför sätter du TMR0 = h'00' i ISR'en ?
> //Stänger av den gamla timningen för tillfället...
> T0IF=0;
Vad är det du stänger av här ?
> Men dom enda resultaten jag får är en för snabb timer eller ingen som fungerar.
Helt slumpmässigt ?
Eller när inträffar det ena resp det andra ?
jag använder bara dom kommentarer jag tycker är nödvändiga i C, eftersom det är bara jag som ska se koden (i 99% av fallen) så blir det bara dumt att kommentera för mycket.
>Varför sätter du om OPTION i ISR'en ?
>Varför sätter du TMR0 = h'00' i ISR'en ?
>
>> //Stänger av den gamla timningen för tillfället...
>> T0IF=0;
>
>Vad är det du stänger av här ?
jag trodde att det inte gick att få 1 sekunds delay på PIC16F877A @20 MHz med Timer0 så jag körde flera avbrott för att 1 sekund så timer:n startas om 46 ggr och det trodde jag skulle bli 1 sekund.
>Helt slumpmässigt ?
>Eller när inträffar det ena resp det andra ?
nej jag testade att skriva om koden (detta är revision 2 så att säga) och den första koden gav för kort delay...
>Varför sätter du om OPTION i ISR'en ?
>Varför sätter du TMR0 = h'00' i ISR'en ?
>
>> //Stänger av den gamla timningen för tillfället...
>> T0IF=0;
>
>Vad är det du stänger av här ?
jag trodde att det inte gick att få 1 sekunds delay på PIC16F877A @20 MHz med Timer0 så jag körde flera avbrott för att 1 sekund så timer:n startas om 46 ggr och det trodde jag skulle bli 1 sekund.
>Helt slumpmässigt ?
>Eller när inträffar det ena resp det andra ?
nej jag testade att skriva om koden (detta är revision 2 så att säga) och den första koden gav för kort delay...
> jag trodde...
Sluta tro och börja läsa databladet istället...
TMR0 (med max prescaler) ger maximalt 256*256 Tcy delay.
256 från prescalern och 256 från TMR0.
Prescaler = 256
TMR0 = 256
256 * 256 = 65.536
20 Mhz -> Tcy = 0.2 us
1 / (0.2 us * 65.536) = (ca) 76
Så det går åt 76 interrupt för att få (ca) 1 sek vid 20 Mhz.
Jag kanske har missat något. Hur fick du 46 ?
> eftersom det är bara jag som ska se koden...
Att posta kod som bara *du* ska läsa verkar lite konstigt...
> Men dom enda resultaten jag får är en för snabb timer
Och hur mycket är "för snabb" !?
Sluta tro och börja läsa databladet istället...
TMR0 (med max prescaler) ger maximalt 256*256 Tcy delay.
256 från prescalern och 256 från TMR0.
Prescaler = 256
TMR0 = 256
256 * 256 = 65.536
20 Mhz -> Tcy = 0.2 us
1 / (0.2 us * 65.536) = (ca) 76
Så det går åt 76 interrupt för att få (ca) 1 sek vid 20 Mhz.
Jag kanske har missat något. Hur fick du 46 ?
> eftersom det är bara jag som ska se koden...
Att posta kod som bara *du* ska läsa verkar lite konstigt...
> Men dom enda resultaten jag får är en för snabb timer
Och hur mycket är "för snabb" !?
> Sluta tro och börja läsa databladet istället...
har läst databladet! skrev "trodde" för att visa att jag antog att det var så men det verkade vara fel.
använde samma uträkning som du men visste inte att jag skulle ha två 256 termer utan använde bara den för prescalar samt att jag körde på 0,75 sekunder då. Sen hur fick du 0.2 us (1/(20*1000*1000) = 0,00000005 = 0,05 us), går timer klockan 4 ggr segare än klockfrekvensen?
Hur hade du löst detta?
har läst databladet! skrev "trodde" för att visa att jag antog att det var så men det verkade vara fel.
använde samma uträkning som du men visste inte att jag skulle ha två 256 termer utan använde bara den för prescalar samt att jag körde på 0,75 sekunder då. Sen hur fick du 0.2 us (1/(20*1000*1000) = 0,00000005 = 0,05 us), går timer klockan 4 ggr segare än klockfrekvensen?
Hur hade du löst detta?
Fosc = 20 Mhz
Fcy = Fosc/4 = 5 Mhz (d.v.s 5 "MIPS", som Microchip kallar det...)
Tcy = 1/Fcy = 1/5Mhz = 0.2 us (d.v.s en "instruction cycle")
> går timer klockan 4 ggr segare än klockfrekvensen?
Se "FIGURE 5.1 : BLOCK DIAGRAM OF THE TIMER0/WDT PRESCALER"
i databladet. Högst upp i figuren, där står "CLKO (= FOSC/4)".
Och i texten straxt ovanför figuren : "In Timer mode, the Timer0
module will increment every instruction cycle (without prescaler)."
> Hur hade du löst detta?
Med assembler...
Med det är klart att det går med C också, jag har bara lite svårt
att hänga med i vad du gör.
Och kanske med TMR1 vilken ger längre tid mellan interrupt (256*256*8 ),
eller med TMR2, vilken kan ge en mer exakt tid eftersom man kan sätta
värdet där den "börjar om" (inte bara FF som för TMR0). Det beror på
hur "nära" 1 sek du behöver ligga.
Jag förstår fortfarande inte riktigt hur du fick "46"
Fcy = Fosc/4 = 5 Mhz (d.v.s 5 "MIPS", som Microchip kallar det...)
Tcy = 1/Fcy = 1/5Mhz = 0.2 us (d.v.s en "instruction cycle")
> går timer klockan 4 ggr segare än klockfrekvensen?
Se "FIGURE 5.1 : BLOCK DIAGRAM OF THE TIMER0/WDT PRESCALER"
i databladet. Högst upp i figuren, där står "CLKO (= FOSC/4)".
Och i texten straxt ovanför figuren : "In Timer mode, the Timer0
module will increment every instruction cycle (without prescaler)."
> Hur hade du löst detta?
Med assembler...
Med det är klart att det går med C också, jag har bara lite svårt
att hänga med i vad du gör.
Och kanske med TMR1 vilken ger längre tid mellan interrupt (256*256*8 ),
eller med TMR2, vilken kan ge en mer exakt tid eftersom man kan sätta
värdet där den "börjar om" (inte bara FF som för TMR0). Det beror på
hur "nära" 1 sek du behöver ligga.
Jag förstår fortfarande inte riktigt hur du fick "46"
- Greve Hamilton
- EF Sponsor
- Inlägg: 544
- Blev medlem: 4 september 2004, 15:03:35
- Ort: GBG
- Greve Hamilton
- EF Sponsor
- Inlägg: 544
- Blev medlem: 4 september 2004, 15:03:35
- Ort: GBG
sodjan; Hehe, reagerade lite på att det verkade fungera "lite", även utan GIE, men jag såg det hur som helst inte i koden, så... 
Seven11; Här har du både hur man ska räkna och hur det kan se ut:
http://www.mikroe.com/forum/viewtopic.p ... =interrupt
Seven11; Här har du både hur man ska räkna och hur det kan se ut:
http://www.mikroe.com/forum/viewtopic.p ... =interrupt
använde TMR1 istället (slipper slösa kraft på en massa avbrott)...
här är koden om någon nångång skulle behöva:
TimerX.c :
TimerX.h :
main.c (avbrottsdelen) :
kompilerat med Hi-Tech PICC Lite
här är koden om någon nångång skulle behöva:
TimerX.c :
Kod: Markera allt
#include <pic.h>
#include "TimerX.h"
void init_Timer1()
{
//Ställer in avbrotsbitar
GIE=1;
PEIE = 1;
TMR1IE = 1;
//Ställer in Timer1 kontrollregister
T1CKPS1 = 1;
T1CKPS0 = 1; //1:8 prescalar
T1OSCEN = 0; //ingen oscillator
TMR1CS = 0; //Använder Fosc/4 som insignal
TMR1ON = 1;
TMR1L = 0x00;
TMR1H = 0x00;
}
Kod: Markera allt
void init_Timer1();
main.c (avbrottsdelen) :
Kod: Markera allt
void interrupt ISR()
{
//Timer1
if (TMR1IF)
{
//Stänger av den gamla timningen för tillfället...
TMR1IF=0;
//Meddelar alla "applikationer"
}
}....ermer utan använde bara den för prescalar samt att jag körde på 0,75 sekunder då. Sen hur fick du 0.2 us (1/(20*1000*1000) = 0,00000005 = 0,05 us), går timer klockan 4 ggr segare än klockfrekvensen?
......
Tycker något behöver förtydligas...
Ja, de anger en klockfrekvens men den är tillmyglad för de har konstruerat "machincecykles" eller något som består av fyra "Quarters" som är 1 Hertz långa.
Så när man kör 40MHz så blir det bara 10Mhz egentligen trots att Microchip påstår att alla instruktioner går att göra på en klockcykel, enligt mig är en klockcykel 1 Hertz men tydligen inte enligt Microchip.
Dessutom är instruktionerna så begränsade att det tar lika lång tid att köra ett program eftersom varje sak som ska göras måste byggas upp av en rad instruktioner.
Bort med all c och c++ assembler är enklare
......
Tycker något behöver förtydligas...
Ja, de anger en klockfrekvens men den är tillmyglad för de har konstruerat "machincecykles" eller något som består av fyra "Quarters" som är 1 Hertz långa.
Så när man kör 40MHz så blir det bara 10Mhz egentligen trots att Microchip påstår att alla instruktioner går att göra på en klockcykel, enligt mig är en klockcykel 1 Hertz men tydligen inte enligt Microchip.
Dessutom är instruktionerna så begränsade att det tar lika lång tid att köra ett program eftersom varje sak som ska göras måste byggas upp av en rad instruktioner.
Bort med all c och c++ assembler är enklare
nanopile> Tycker något behöver förtydligas...
Japp, du kan ju börja med *ditt* inlägg...
Var får du "1 Hertz" från t.ex ??
När det gäller olika begrepp och uttryck som används
för PIC processorerna, så tycker jag att det är mycket enklare
att köra med den modell som Microchip har valt. Att påstå att
de "myglar" eller "påstår" saker o.s.v är ju bara löjligt...
Jag tänkte be om förtydligande på en del andra saker du skrev,
men det är så förvirrat det hela så jag får inte till någon bra fråga...
Det enda som var vettigt var sista raden.

Japp, du kan ju börja med *ditt* inlägg...
Var får du "1 Hertz" från t.ex ??
När det gäller olika begrepp och uttryck som används
för PIC processorerna, så tycker jag att det är mycket enklare
att köra med den modell som Microchip har valt. Att påstå att
de "myglar" eller "påstår" saker o.s.v är ju bara löjligt...
Jag tänkte be om förtydligande på en del andra saker du skrev,
men det är så förvirrat det hela så jag får inte till någon bra fråga...
Det enda som var vettigt var sista raden.
