Timer0 på en Mega16 gör ingenting

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
MicaelKarlsson
Inlägg: 4669
Blev medlem: 18 juni 2004, 09:16:07
Ort: Aneby
Kontakt:

Timer0 på en Mega16 gör ingenting

Inlägg 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. :(
Millox
Inlägg: 559
Blev medlem: 10 december 2005, 22:10:43
Ort: Östhammar

Inlägg av Millox »

Du vill nog använda |= istället för ^=. Du kommer annars att mata in 0x00 i registret hela tiden.
Användarvisningsbild
Micke_s
EF Sponsor
Inlägg: 6741
Blev medlem: 15 december 2005, 21:31:34
Ort: Malmö

Inlägg av Micke_s »

Vad sägs om att slå på att interrupt kan hända, globala interruptflaggan?

Kod: Markera allt

 sei();  //i winavr.
syltkaka
Inlägg: 188
Blev medlem: 9 december 2006, 18:55:09
Ort: Göteborg

Inlägg 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
Användarvisningsbild
MicaelKarlsson
Inlägg: 4669
Blev medlem: 18 juni 2004, 09:16:07
Ort: Aneby
Kontakt:

Inlägg 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 :twisted:


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! :D :D

Kanske dags att uppdatera! 8)
syltkaka
Inlägg: 188
Blev medlem: 9 december 2006, 18:55:09
Ort: Göteborg

Inlägg 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.
Användarvisningsbild
MicaelKarlsson
Inlägg: 4669
Blev medlem: 18 juni 2004, 09:16:07
Ort: Aneby
Kontakt:

Inlägg 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)
thepirateboy
EF Sponsor
Inlägg: 2109
Blev medlem: 27 augusti 2005, 20:57:58
Ort: Borlänge

Inlägg av thepirateboy »

Jag provade också koden och den hoppade aldrig in i interruptet. Jag kör senaste WinAVR (tror jag). Mycket märklig bugg...
Användarvisningsbild
MicaelKarlsson
Inlägg: 4669
Blev medlem: 18 juni 2004, 09:16:07
Ort: Aneby
Kontakt:

Inlägg av MicaelKarlsson »

:? Mysko, skall uppdatera och se vad som händer. :pray:

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.
Användarvisningsbild
cykze
EF Sponsor
Inlägg: 1539
Blev medlem: 8 april 2004, 10:40:28
Ort: Uppsala

Inlägg av cykze »

Varför har du "nop" i while-loopen? Den gör ju ingenting.
Användarvisningsbild
MicaelKarlsson
Inlägg: 4669
Blev medlem: 18 juni 2004, 09:16:07
Ort: Aneby
Kontakt:

Inlägg 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.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg 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.
Användarvisningsbild
MicaelKarlsson
Inlägg: 4669
Blev medlem: 18 juni 2004, 09:16:07
Ort: Aneby
Kontakt:

Inlägg av MicaelKarlsson »

sodjan: Har testat med och utan:

Kod: Markera allt

 asm volatile ("nop"::); 
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.
Användarvisningsbild
Micke_s
EF Sponsor
Inlägg: 6741
Blev medlem: 15 december 2005, 21:31:34
Ort: Malmö

Inlägg 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å.

Kod: Markera allt

  fc:   ff cf          rjmp   .-2         ; 0xfc <main+0x1e> 
loopar till sig själv hela tiden.
syltkaka
Inlägg: 188
Blev medlem: 9 december 2006, 18:55:09
Ort: Göteborg

Inlägg av syltkaka »

Då är frågan hur det ser ut om man tar bort while-loopen helt och hållet.
Skriv svar