PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : timer optimierungsabhängig o_O



sonium
14.01.2006, 10:56
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

int wait(time)
{
int i = 0;
TCNT0 = 0;
while(1)
{
if (TCNT0 % 16 == 0) i++;
if (i == time) return 0;
}
}

int main()
{

TCCR0 |= (1<<CS00)|(1<<CS02);
DDRC = 0xFF; // Alle Pins von Port C auf Write setzten
int time = 1000;
PORTC = 0xFF;
while(1)
{
PORTC |= (1<<2);
wait(time);
PORTC &= ~(1<<2);
wait(time);
}
return 0;
}


mit diesem Code sollte mein Atmega32 an nem 16Mhz Quarz Eigentlich einmal in der Sekunde blinken.
In wirklichkeit blinkt es aber um einiges schneller und die geschwindigkeit ist zudem noch Optimierungsabhängig.
Was ist los?

ebb
14.01.2006, 13:09
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/delay.h>
#include <avr/signal.h>

uint8_t second=0;
uint8_t secled=0;
uint8_t minute=0;
uint8_t hour=0;

SIGNAL (SIG_OVERFLOW1)
{
second ++;
PORTD ^= (1<<PD0);
if(second == 60)
{
second = 0;
minute ++;
};
if(minute == 60)
{
minute = 0;
hour ++;
};
if(hour == 24)
{
hour = 0;
};

};


int main(void)
{
DDRD = 0xff;
DDRB = 0xff;
OCR1AL = 0x8d;
OCR1AH = 0x5b;
TCNT1L = 0x73;
TCNT1H = 0xa4;
TIMSK |= (1 << TOIE1);
TCCR1B |= (1<<CS10)|(1<<CS11); //64
sei();
while(1)
{

};

}



so funzts mit meinem ATMEGA16 und 6Mhz Quarz, ich weiß zwar nicht wa sbei dir falsch ist , aber vielleicht hilft dir mein code

EDIT//

wenn ich das richtig sehe benutzt du den Timeroverflow ja gar nicht das musst du soviel ich weiß mit dem SIGNAL (SIG_OVERFLOW1)
{;} machen , also alles was in der { } ist führt er aus sobald der timer neu anfängt

sonium
14.01.2006, 14:58
Irgendwie wills mit Interupt nicht:

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

uint8_t timer = 0;
uint8_t msecond = 0;

SIGNAL (SIG_OVERFLOW0)
{
if (timer++ % 16 == 0) msecond++;
};

int wait(time)
{
TCNT0 = 0;
msecond = 0;
while(1)
{
if (msecond >= time) return 0;
}
}

int main()
{
TIMSK |= (1<<TOIE1);
TCCR0 |= (1<<CS00)|(1<<CS02);
DDRC = 0xFF;
int time = 1000;
PORTC = 0xFF;
sei();
while(1)
{
PORTC |= (1<<2);
wait(time);
PORTC &= ~(1<<2);
wait(time);
}
return 0;
}

Pascal
14.01.2006, 15:03
mit
TIMSK |= (1<<TOIE1); schaltest du den Interrupt für den timer1 frei, du verwendest aber den timer0
verwende statt TOIE1 also mal TOIE0