Sida 1 av 1
GCC och timer....
Postat: 3 mars 2007, 13:49:55
av erikbrannlund
Hej!
Jag tror att jag blir knäpp.
Jag har försökt att få snurr på en atmega644 timer men icke sa nicke att jag får till ngt som liknar 1 sekund.
Det här är den sista variant på koden som jag försökt (knyckt från JELU:s ethernet demo projekt).
Kod: Markera allt
volatile unsigned char timerCounter;
volatile unsigned char tcount = 0;
volatile uint8_t sec_flag = 0;
void initTimer(void)
{
TCNT1 = (uint16_t) -625; // timer reload value
TCCR1A = _BV(WGM11);
TCCR1B = 3; // 64 presc. -> 62500 Hz, 16 uS
TIMSK1 = _BV(TOIE0);
sei(); /* enable interrupts */
timerCounter = 0;
}
//
// ticks every 10 mS
//
SIGNAL(SIG_OVERFLOW1)
{
TCNT1 = (uint16_t) -625; // timer reload value
timerCounter++; // inc timeout tick
if (++tcount == 100) // one second tick
{
tcount = 0;
sec_flag = 1;
sec++;
}
}
Jag har uppenbarligen inte gjort allting rätt.
Kopplingen sitter förresten i STK-500 om det kan spela ngn roll.
/Erik
Postat: 3 mars 2007, 14:07:46
av MicaelKarlsson
Vet inte om det hjälper, men det behandlar timers i alla fall:
jättelång adress
lång adress
lång adress
lång adress
Postat: 3 mars 2007, 14:16:01
av cykze
Hur ser deklarationen för "sec" ut?
Hur vet du att koden inte fungerar? Vad händer?
Jag har inte kollat databladet, men ska det inte vara:
TIMSK1 = _BV(TOIE1);
Postat: 3 mars 2007, 14:26:26
av syltkaka
Du säger att du inte kommer i närheten av en sekund, hur nära?
Får du något interrupt överhuvudtaget?
Inte för att det kanske gör någon skillnad men jag tror att SIGNAL() är ett gammalt skrivsätt. Det nya är
Sen förstår jag inte varför du använder PWM. Är det inte enklare och använda CTC? Vidare, det är riskabelt att skriva nya värden till TCNT1 om man nu vill att timern ska gå som tänkt.
Precis som cykze säger så är det också missledande att använda TOIE0 då detta avser timer0. Funktionen är dock densamma.
Postat: 3 mars 2007, 15:57:57
av erikbrannlund
cykze:
- sec är deklarerad som uint32_t med det kan väl inte påverka timern.
- Naturligtvis ska det vara TOEI1 (klipp och klistra kan ställa till mycket oreda).
syltkaka:
- Hur nära? Jag har inte suttit och testat i ngn större utsträckning men det är i alla fall så pass fel att jag "känner" att siffran borde slagit om tidigare. 2-3 ggr kanske.
- Använder jag PWM det var mer än jag visste och vad är CTC (är inte det en tillverkare av vedpannor)
Jag är helt grön på AVR och tänkte försöka göra "ngt riktigt" istället för alla dessa "Hello world" som man ska börja med. Dessutom tror jag att jag är förbi det eftersom jag kan skriva ut datum och tid på LCD:n. Fast nu är ju tiden ur led...
/Erik
Postat: 3 mars 2007, 17:37:31
av cykze
>
sec är deklarerad som uint32_t med det kan väl inte påverka timern.
Man bör deklarera alla variabler som används både innefrån interrupt-rutiner och utanför som "volatile". Detta för att kompilatorn inte ska optimera bort dom på något sätt. Dessutom får du tänka dig för när du delar variabler mellan interrupt och "resten". Dvs så att en interrupt inte kan inträffa när variabeln används någonstans i programmet. En interrupt kan ju inträffa när som helst.
Kolla sidan 129 i databladet. Där finns en tabell som visar vilka timer-lägen som finns. Det du vill ha är CTC. Men då får du ändra från TOIE1 till OCIE1A och från SIG_OVERFLOW1 till TIMER1_COMPA_vect. Sen ändrar du i OCR1A istället för TCNT1, och tar bort minustecknet framför 625. TCNT-raden i interrupt-rutinen ska bort. CTC nollställer TCNT automatiskt.
Något sånt här borde det bli. Jag vet inte frekvens du kör AVR:en från, så om tiden blir rätt vet jag inte.
Kod: Markera allt
volatile uint32_t sec = 0;
volatile unsigned char timerCounter;
volatile unsigned char tcount = 0;
volatile uint8_t sec_flag = 0;
void initTimer(void)
{
OCR1A = 625; // timer compare value
TCCR1A = _BV(WGM12); // CTC
TCCR1B = 3; // 64 presc. -> 62500 Hz, 16 uS
TIMSK1 = _BV(OCIE1A);
sei(); /* enable interrupts */
timerCounter = 0;
}
//
// ticks every 10 mS
//
ISR(TIMER1_COMPA_vect)
{
timerCounter++; // inc timeout tick
if (++tcount == 100) // one second tick
{
tcount = 0;
sec_flag = 1;
sec++;
}
}
Testa och se om det fungerar. Jag har inte testat koden så jag vet inte om det fungerar.
Postat: 3 mars 2007, 18:28:33
av erikbrannlund
Hmm!
Nu börjar(?) jag att få lite bättre koll på det här men min tid verkar inte rätt.
Alltså är min gissning om frekvensen inte riktig. Alltså ställer jag några dumma(?) frågor i form av påståenden.
Jag kör alltså på STK-500. Alla "jumprar" står i samma läge som vid köpet.
- Det betyder att klockan till timern snurrar med processorns default hastighet?
- Klockans default hastighet är 8 MHz?
Jag antar att ngt i ovanstående resonemang är fel men vad?
/Erik
Postat: 3 mars 2007, 21:12:07
av syltkaka
Angående klockan. Se avdelning 7.2.1 sid. 29 samt 7.11.1 sid. 38.
Datablad
Postat: 3 mars 2007, 22:56:08
av Stinrew
Jag har en gissning.
Jag tror att du inte klickat i internal RC-oscillator(8MHz), utan att uCn går på STK500ns egen oscillator(som är default på 3,686MHz).
Postat: 4 mars 2007, 00:21:57
av erikbrannlund
Hej!
Efter att först låtit den snurra ett tag på "hög" fart utan prescaler med parallell tidtagning och lite räknande kom jag fram till ~1MHz. I praktiken går den lite fortare. Sedan efter syltkakas svar så tittade jag i manualen och såg det jag missat förra gången. Ja jag vet j****a blindstyre. Default är 8Mhz:en neddelad till 1MHz.
Tack för hjällpen alla!!!!
/Erik
P.S
Det blir säkert inte den sista dumma frågan.
D.S
Postat: 4 mars 2007, 00:55:00
av $tiff
Du är varken den första eller sista som råkar ut för detta. Det är väldigt lurigt att nya AVR skalar ner klockan med 8 som default.
Det finns inga dumma frågor, bara dåliga formuleringar

Postat: 4 mars 2007, 01:02:57
av Stinrew
Sant, men clkdiv-8 har ju en egen ruta i AVRstudio. Så det är ju iaf lätt att se/ändra(när man väl hittat felet).