PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ATmega32-16 MHz und ein vergessener Überlaufteiler (gelöst)



vajk
25.09.2006, 01:24
Hallo !

Ich habe ein merkwürdiges Problem:


Kurzform : externer 16 MHz Quarz im Timer ohne Vorteiler ergibt NUR 31,25 kHz ???????? Wo kommt der Teiler von 512 her ????????
Eingestellt habe ich den explizit nicht (Code s.u.)



Meine Schaltung mit einem Atmega32 16 AU 0544D von Reichelt,
dessen FUSE-Bits so initialisiert sind: SPIEN, CKOPT,BOOTSZ1,BOOTSZ0,SUTO0


Ein anderes Testproggi, das nichts (mehr) anders macht als:



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

//-------------------------------------------------------
int main(void)
{
DDRD |= 0 | (1 << DDD1) | (1 << DDD0);

for(;;)
{
PORTD |= (1 << DDD0);
nop; nop; nop; nop; nop; nop;
nop; nop; nop; nop; nop; nop;
PORTD &=~ (1 << DDD0);
}

return(0);
}


Bringt am besagten Pin eine Frequenz von 889.090 kHz (ca. 1,1 us) also nur das ca. 1/18-tel der Quarzfrequenz von 16 MHz!!!!!

Sollte da nicht irgendwas mit in der Größenordnung von 62,5 nsec rauskommen ...

(Ausprobiert: umgestellt auf die intere 1 MHz ergibt genau 16 fach geringere Zeiten - also kommen die 16 MHz des externen Quarzes an - auch wenn ich den Quarz wechsel, ändert sich nichts)

edit: Wenn ich am Quarz mit 1:10-Tastkopf messe, sinds da 16 MHz !!!!! Wieso kommen die im Proz nicht an ? Wie gesagt, der externe Quarz wird verwendet! Kein ext. Quarz = kein Tick im Prozz - auch schon getestet :-)


Drauf gekommen bin ich eben, weil die Timerfunktion des 8-Bit-Timers, wenn man direkt ohe Vorteile laufen läßt, eine Frequenz von 31.25 kHz am Pin raus kommt.
Wenn ich den Vorteiler dann auf 64 stelle, kommt brav 1/64 von 31250 Hz = 490 Hz raus! Also ändert sich das Teilerverhalten nach Datasheet.

Hier der Code des timers:



im Make: MCU = atmega32 und F_CPU 16000000

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

//-------------------------------------------------------
static void avr_init(void)
{
// 8Bit - Timer bei 16 MHz ATmega32 -> siehe S.127

// CS00 = / 1 = 16000000 = 62,5 ns
// CS01 = / 8 = 0.5 us = 500 ns
// CS00 + CS01 = / 64 = 4 us / 250 = 1000 Hz
// CS02 = / 256 = 16 us
// CS00 + CS02 = /1024 = 64 us

TCCR0 = 1; // (1 << CS00)
TIMSK = 0 | (1 << TOIE0); // Timer Interrupt -> 8 Bit -> Overflow bei 256

DDRD |= 0 | (1 << DDD1) | (1 << DDD0);

sei(); // enable interrupts -> Global enable interrupt
}

//-------------------------------------------------------
SIGNAL(SIG_OVERFLOW0)
{
uint8_t tmp_sreg;
tmp_sreg = SREG;
cli(); // Interrupts aus

// zeigs mir am Oszi
if(PORTD & (1 << DDD1)) PORTD &=~ (1 << DDD1); else PORTD |= (1 << DDD1);

SREG = tmp_sreg; // Interrupts zuruecksetzen
}

//-------------------------------------------------------
int main(void)
{
avr_init();
for(;;)
{
}
return(0);
}




Hat jemand eine Idee, wo meine Prozessorschwingungen verbraucht werden können ?

Was mache ich falsch - oder hab ich einen Knoten im Kopf ?

Ist der atmega32 so anders im Verhalten als der 128er ? ... Hilfeeeeeee ???

Liebe Grüße,
Vajk

vajk
25.09.2006, 09:30
.. ergänzend, wenn ich nur eine Loop in main laufen lasse, mit Port an delay 1 us Portaus delay 1 us ... dann stimmt es auch am Oszi, brav 1 us (mit klassischem Einschwingverhalten des Rechtecksignals) ...

SprinterSB
25.09.2006, 10:06
Du hast einen ATmegs bei 16MHz und deinen Timer0-IRQ auf Overflow, Prescale=1. Also bist du bei 16/1/256 MHz. Da du in der ISR toggelst, siehst du eine Frequenz von 16/1/256/2 MHz = 31.25kHz. Ist doch alles in Butter, oder?

vajk
25.09.2006, 11:04
argl .. Brett-vom-Kopf-hab-wegzerrrrrr-die Overflow-Teilung von 256 hab ich in meinen Rechnungen nicht berücksichtig ... argl ... man(n) sollte nachts besser schlafen :-)