Sida 1 av 2
Timer0 på en Mega16 gör ingenting
Postat: 13 mars 2007, 19:44:30
av MicaelKarlsson
Jag har testat denna kod (för WinAVR) i min Mega16 som sitter i en STK500:
Kod: Markera allt
#include <avr/io.h>
#include <avr/signal.h>
ISR(TIMER0_OVF_vect)
{
PORTB ^= 0xFF;
TCNT0=0;
}
int main ( void )
{
// Setup timer0
TCCR0 = (1<<CS02)|(1<<CS00); //Timer clock = system clock/1024.
TIMSK = 1; //Enable Timer0 Overflow. Interrupt
DDRB = 0xFF; //Set Port B as output.
PORTB=0xFF;
while (1)
{
asm volatile ("nop"::);
}
}
Det verkar som om timern startar i AVRStudio men det blir inte mycket blinkande.
Har stirrat mig blind på koden, vad är det för fel?
Har kikat på denna app-note:
http://atmel.com/dyn/resources/prod_doc ... oc2505.pdf
Men inget funkar.

Postat: 13 mars 2007, 19:50:58
av Millox
Du vill nog använda |= istället för ^=. Du kommer annars att mata in 0x00 i registret hela tiden.
Postat: 13 mars 2007, 19:54:46
av Micke_s
Vad sägs om att slå på att interrupt kan hända, globala interruptflaggan?
Postat: 13 mars 2007, 20:32:34
av syltkaka
Urklipp ur "signal.h"
Kod: Markera allt
#warning "This header file is obsolete. Use <avr/interrupt.h>."
#include <avr/interrupt.h>
Det är helt rätt att skriva '^=' om du vill att dem ska blinka.
EDIT: Tillägg
Postat: 14 mars 2007, 17:43:49
av MicaelKarlsson
Har ändrat i koden (se nedan) men med samma usla resultat.
Kod: Markera allt
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/delay.h>
#define bit_flip(p,m) ((p) ^= (m))
ISR(TIMER0_OVF_vect)
{
bit_flip(PORTB,1);
}
int main ( void )
{
// Setup timer0
TCCR0 = (1<<CS02)|(1<<CS00); //Timer clock = system clock/1024.
TIMSK =0x00; //Enable Timer0 Overflow Interrupt.
TCNT0=0;
DDRB = 0xFF; //Set Port B as output
sei();
while (1)
{
asm volatile ("nop"::);
}
}
Har kompilerat den för en Mega162 och Mega32 med samma usla resultat.
Någon som kan testa om koden fungerar?
Gjorde en test med följande i while(1)-loopen:
Kod: Markera allt
// _delay_us(150); //Bara för test.
// bit_flip(PORTB,1);
och den blinkar som den skall. Varför i hela fridens namn får jag inte igång timern? Vad är det jag missat?
Jag blir nog snart flintskallig
EDIT
Kod: Markera allt
SIGNAL(TIMER0_OVF_vect) //<---- Där var felet!!
{
//PORTB ^= 0xFF;
TCNT0=150;
bit_flip(PORTB,1);
}
Har hittat felet:
Kompilatorn fattade inte ISR men när jag gick över till SIGNAL gick det som smort!
Kanske dags att uppdatera!

Postat: 14 mars 2007, 22:30:32
av syltkaka
Vilken version av WinAVR hade du då?
Känns konstigt att kombinationen av att använda interrupt.h och SIGNAL skulle fungera men uppenbarligen så fungerade det.
Postat: 15 mars 2007, 11:56:49
av MicaelKarlsson
Det är du inte ensam om syltkaka! Men SIGNAL finns med i interrupt.h
Kör (körde) med WinAVR-20060421, skall uppdatera i dag (15 mars)
Postat: 15 mars 2007, 12:06:40
av thepirateboy
Jag provade också koden och den hoppade aldrig in i interruptet. Jag kör senaste WinAVR (tror jag). Mycket märklig bugg...
Postat: 15 mars 2007, 12:12:56
av MicaelKarlsson

Mysko, skall uppdatera och se vad som händer.
Edit:
Uppdaterade WinAVR till 20070122 och då rasade AVRStudio 4.12 så efter en stunds uppdaterande så fungerar nu allt (tror jag) som det skall och följande kod blinkar fint.
Kod: Markera allt
#include <avr/io.h>
#include <avr/interrupt.h>
#define bit_flip(p,m) ((p) ^= (m))
ISR(TIMER0_OVF_vect)
{
TCNT0=0;
bit_flip(PORTB,1);
}
int main ( void )
{
// Setup timer0
TIMSK |= (1 << TOIE0); // Enable timer0 overflow interupt.
TCCR0 |= (1 << CS00)|(1 << CS02); // CK/1024
TCNT0 = 0; // set timer counter to 0;
sei(); //Enable interupts.
DDRB = 0xFF; // Configure PortB as output
PORTB = 0xFF;
while (1)
{
asm volatile ("nop"::);
}
}
Så om ni får problem med att något inte fungerar som det skall så kan ni ta en titt i lss-filen.
Postat: 15 mars 2007, 17:44:16
av cykze
Varför har du "nop" i while-loopen? Den gör ju ingenting.
Postat: 15 mars 2007, 17:48:26
av MicaelKarlsson
Den bara "slank med". Som du säger, den gör ju inget så jag har inte fått ut tummen och raderat raden.
Postat: 15 mars 2007, 19:56:21
av sodjan
> Varför har du "nop" i while-loopen?
Jag vet inte hur det är i just *detta* fall, men många
kompilatorer plockar helt enkelt bort tomma loopar.
Att lägga en asm NOP där förhindrar det.
Postat: 16 mars 2007, 14:31:09
av MicaelKarlsson
sodjan: Har testat med och utan:
Och du har rätt, se nedan:
Utan
asm NOP i while(1)
Kod: Markera allt
int main ( void )
{
de: 89 b7 in r24, 0x39 ; 57
e0: 81 64 ori r24, 0x41 ; 65
e2: 89 bf out 0x39, r24 ; 57
// Setup timer0
TIMSK |= (1 << TOIE0); // Enable timer0 overflow interupt.
TCCR0 |= (1 << CS00); // CK/1
e4: 83 b7 in r24, 0x33 ; 51
e6: 81 60 ori r24, 0x01 ; 1
e8: 83 bf out 0x33, r24 ; 51
TCNT0= 0; // set timer counter to 0;
f0: 12 be out 0x32, r1 ; 50
sei(); //Enable interupts.
f4: 78 94 sei
DDRB = 0xFF; // Configure PortB as output
f6: 8f ef ldi r24, 0xFF ; 255
f8: 87 bb out 0x17, r24 ; 23
PORTB = 0xFF;
fa: 88 bb out 0x18, r24 ; 24
fc: ff cf rjmp .-2 ; 0xfc <main+0x1e>
och med asm volatile ("nop":: );
Kod: Markera allt
int main ( void )
{
de: 89 b7 in r24, 0x39 ; 57
e0: 81 64 ori r24, 0x41 ; 65
e2: 89 bf out 0x39, r24 ; 57
// Setup timer0
TIMSK |= (1 << TOIE0); // Enable timer0 overflow interupt.
TCCR0 |= (1 << CS00); // CK/1
e4: 83 b7 in r24, 0x33 ; 51
e6: 81 60 ori r24, 0x01 ; 1
e8: 83 bf out 0x33, r24 ; 51
TCCR2 |= (1 << CS22)|(1 << COM20); // CK/64 (1 << CS21)|
ea: 85 b5 in r24, 0x25 ; 37
ec: 84 61 ori r24, 0x14 ; 20
ee: 85 bd out 0x25, r24 ; 37
TCNT0= 0; // set timer counter to 0;
f0: 12 be out 0x32, r1 ; 50
sei(); //Enable interupts.
f4: 78 94 sei
DDRB = 0xFF; // Configure PortB as output
f6: 8f ef ldi r24, 0xFF ; 255
f8: 87 bb out 0x17, r24 ; 23
PORTB = 0xFF;
fa: 88 bb out 0x18, r24 ; 24
while (1)
{
asm volatile ("nop"::);
fc: 00 00 nop
fe: fe cf rjmp .-4 ; 0xfc <main+0x1e>
Som synes försvinner while(1) {} helt och hållet.
Kanske skall tillägga att kodsnuttarna är hämtade från .lss-filen som WinAVR skapar vid kompilering av C-koden.
Postat: 16 mars 2007, 14:49:14
av Micke_s
Den försvinner inte alls eller kan vara så att avr gcc lägger till en loop längst ner i main också.
loopar till sig själv hela tiden.
Postat: 16 mars 2007, 15:24:17
av syltkaka
Då är frågan hur det ser ut om man tar bort while-loopen helt och hållet.