Hallo,

Ik wil op me ATmega8 Timer0 gebruiken voor 1msec timer, ik heb hiervoor een prescaler nodig etc en wil overflow interupt gebruiken.

De code is de volgende :

//ICC-AVR application builder : 2/11/04 2:19:27 PM
// Target : M8
// Crystal: 1.0000Mhz

#include <iom8v.h>
#include <macros.h>

void port_init(void)
{
 PORTB = 0xFF;
 DDRB  = 0x00;
 PORTC = 0x00; //m103 output only
 DDRC  = 0x7F;
 PORTD = 0xFF;
 DDRD  = 0x00;
}

//TIMER0 initialisation - prescale:8
// WGM: Normal
// desired value: 1mSec
// actual value:  1.000mSec (0.0%)
void timer0_init(void)
{
 TCCR0 = 0x00; //stop
 TCNT0 = 0x83; //set count
 TCCR0 = 0x02; //start timer
}

#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
 PORTC = PORTC ^ 0xFF;
 TCNT0 = 0x83; //reload counter value
}

#pragma interrupt_handler int0_isr:2
void int0_isr(void)
{
 //external interupt on INT0
}

#pragma interrupt_handler int1_isr:3
void int1_isr(void)
{
 //external interupt on INT1
}

//call this routine to initialise all peripherals
void init_devices(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 port_init();
 timer0_init();

 MCUCR = 0x00;
 GICR  = 0xC0;
 TIMSK = 0x01; //timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialised
}

void main(void)
{
 init_devices();
 while(1);
}

Ik vermoed dat de clok niet om 1mhz draait, sterker nog, dat er geen clock draait, maar of dat kan :S dat weet ik niet.

Volgens de datasheet dient de ATmega8 standaard op 1MHz te draaien.

Bij goede code gebruik je in plaats van waardes als 0x02 de benaming van de registerbits zoals TOIE0 bijvoorbeeld. Dat leest (vooral voor anderen) makkelijker. Het debuggen gaat dan ook lekker snel.

Toevoeging:

TCCR0 = 1 << CS01;

TIMSK = 1 << TOIE0;

GICR = (1 << INT0) | (1 << INT1);

mag het ook in C source?
dan heb ik nl. wel een source voor je

Tuurlijk, mijn source is ook C

U may add me to ur msn

[Bericht gewijzigd door Parcye op ]

msn dood sinds laptop dood

maar zal ff oplichten:



SIGNAL (SIG_OVERFLOW0) 
{
	t++;
}

//programma start boven is subroutine

	//init_timer0;
	TCCR0 = 5; //prescaler set (default 1024)
	TIMSK = 1; //Enable overflow for counter 0
	_SEI();

	//wait for timer object
	for (i = 0; i <= 400; i++)
	{
		while (!t)
		{
		}
		t=0;
	}		

ik maak dus gebruik van de interrupt routine signal, vergeet niet hier een header file voor te maken

In feite do ik dat ook, op het moment dat de signal komt wordt mijn interrupt handler uitgevoerd... nadeel is, die interrupt komt helemaal niet.

#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
 PORTC = PORTC ^ 0xFF;
 TCNT0 = 0x83; //reload counter value
}

Het zelfde idee werkt prima op de ATmega8515

foutje mijnzijds, die header file hoeft er niet bij, de lus die je ziet is een wachtlus uiteraard.

Maar ik heb toevallig ook met de 8515 gewerkt en kijk f in de datasheet. de registers heten daar nl. heel vaak anders

Heb je de interrupt routine wel boven de source gezet?
heb je _sei wel aangeroepen? die is nodig das de signal Interrupt enable

[Bericht gewijzigd door High met Henk op ]

dat heb ik inmiddels helemaal door genomen, en alles klopt als een bus.

Ik heb dus het idee dat er een probleem zit buiten mijn code om, in de config bits, draait er bijvb wel een interne clock? Staat die niet uit toevallig?

Maar ik weet niet hoe ik dat moet zoeken

de Signal Enable Interrupt moet je aanzetten dus
en de TIMSK ook
das de overflow enable

[Bericht gewijzigd door High met Henk op ]

//call this routine to initialise all peripherals
void init_devices(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 port_init();
 timer0_init();

 MCUCR = 0x00;
 GICR  = 0xC0;
 TIMSK = 0x01; //timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialised
}

void main(void)
{
 init_devices();
 while(1);
}

Precies wat ik hier doe dus... toch?

ja, behalve het _ streepje voor sei, weet niet meer of dat van belang is, maar toch.

wat hebben deze registers met de timer te maken?
MCUCR = 0x00;
GICR = 0xC0;
de ene is een booter en de andere een power management register? houd je code overzichtelijk en plaats bij bosjes, scheelt later debuggen, commentaar is ook heel erg nuttig

BTW, het is dat streepje, dat MOET erbij

[Bericht gewijzigd door High met Henk op ]

MCUCR is voor INT 0 en INT 1 om aan te geven op welke flank deze moeten triggeren,

GICR is INT 0 en INT 1 inschakelen.

-> je hebt wel gelijk wat je zegt over code, maar dit is de default code door ICC gegenereerd volgens mijn wensen en voor de juiste AVR en omdat dat al niet werkte heb ik het helemaal na gekeken maar geen tijd genomen het verder te structuren en te voorzien van commentaar, normaal zet ik PRE en POST bij iedere functie en korte omschrijving... nu niet.

Maar doet tie het nu ook? met dat streppje erbij?

_SEI en SEI maakt geen verschil

hmm kijk maar eens in de datasheet, het streepje moet ervoor in de C-source.

init ook eens de prescaler?
en zet ook ens een streepje voor CLI
moet nl. ook officieel

maar waar staat dit nu ergens?


#pragma interrupt_handler timer0_ovf_isr:10

void timer0_ovf_isr(void)
{ PORTC = PORTC ^ 0xFF; 
TCNT0 = 0x83; //reload counter value}

als ik het uit mijn hoofd zeg, (kan er helemaal naast zitten, want wat je hier ziet is mijn 1e project met een AVR, maar is het zo dat bij de atmega de interrupt routine geen void mag zijn, void betekend immers zoiets als leeg, maar erachter heb je ook void staan, maybe cleart hij daarom de interrupt vector wel voor het proces

[Bericht gewijzigd door High met Henk op ]

Dan zou dat betekenen dat de tool van ImageCraft eigenlijk niet voldoet, echter lijkt me dat zeer vreemd aangezien het een veel gebruikte omgeving is...

Heb de _ er voor gezet maar de HEX file blijft het zelfde als zonder dus is het _ overbodig

En ik zet ook mijn prescaller in, op 2... dus dat is 8

datasheet denkt er anders over, vriendelijke compiler dus:P

maar als ik dan goed kijk zie ik slechts 1 verschil:
mijn interrupt routine heeft geen void ofiets en geen toevoeging en heet signal
jouw interrupt routine heeft wel een void en een toevoeging (void)
en heet timer0_ovf_isr
verder is het dezelfde source en mijn source werkt en de jouwe niet.

okeej, ik heb de standaard AVR compiler in gebruik en programmeer in programmers notepad, maar daar mag het toch helemaal niet aan liggen

Hier de code die ik gebruik voor een 1ms timer in een AT90S2313. Dit maakt gebruik van timer 1 met het output compare register. Het gaat natuurlijk om het principe. Dit is C code voor de AVRGCC compiler.


#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/timer.h>

volatile uint16_t timer; /* program timer, cpu clock divided by 6000 (8 x 750) */

SIGNAL(SIG_OUTPUT_COMPARE1A) /* timer 1 output compare interrupt handler */
{
	timer++;
}

void init()
{
	TCCR1A = 0; /* none */
	TCCR1B = 10; /* enable output compare, ck/8 */
	OCR1A = 750; /* output compare value 750 (6Mhz/8/750 = 1ms) */
	timer_enable_int(64); /* enable timer 1 ouput compare interrupt */

	timer = 0;	

	sei(); /* enable interrupts */
}

int main()
{
	init();
	
	for(;;)
	{
	}
		
	return (0);
}

Marcel

zou het niet moeten zijn dat die interrupt routine SIGNAL heet?

stomme Q, maar bij mij wertk het, bij jouw werkt het, alleen bij parcey niet, parcey, probeer het eens?

nieuw project aangemaakt en de code aangepast en gebruikt en het werkt...

nieuw project aangepast mijn code er in, het werkt

oude project, jullie code er in, het werkt niet
oude project, mijn code er in, het werkt niet

hmm, toch niet zo'n geweldig programma dus
ach PN heeft ook zo'n bug, die zet af en toe de source er nog een keer onder, blijven wazige dingen programmers

Probleem gevonden, hij wist niet welk device ik gebruikte dus de code had een eerste regel die was jump to begin... dus niet meer dan niets doen...

HEHEHE, ken je lang zoeken:
tip, kijk volgende keer eerst of je source loopt, hang er ff een led aan ofzo, kun je zelf fout zoeken, gewoon ff die pin aansturen