PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] 16bit Timer Atmega2560 läuft zu schnell



QuadV
17.12.2013, 23:13
Hallo Zusammen

Ich versuche nun schon seit (zu) langer Zeit einen Timer zum laufen zu kriegen. Ich bin eigentlich bloss etwas am rumspielen. Ich wollte einen der Timer so einstellen dass ich jede sekunde ein Interrupt erhalte. Das ganze Funktioniert eigentlich, nur viel zu schnell. Statt einer Sekunde habe ich eta 200mS... Ich habe nun das Datenblatt gefühlte 20mal durchgelesen und gefühlte 100 webseiten angeschaut, aber ich kriegs nicht hin. Ich weiss dass der uC mit der definierten Frequenz läuft, ich habe vorhin ein paar ausgaben am UART gemacht. Kann mir jemand sagen was ich falsch mache?


#define F_CPU 16000000UL

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


int main(void)
{
uint16_t Timer = (16000000/1024) -1;
TCCR3A = (1<<WGM31); //CTC Mode
TCCR3B = (1<<CS32) | (1<<CS30); //prescaler 1024

OCR3AH = (Timer>>8); //t = 1s
OCR3AL = Timer;

TIMSK3 |= (1<<OCIE3A); //Compare interupt aktivieren
sei();
DDRL = 0xFF;
while(1)
{
//TODO:: Please write your application code
}
}

ISR(TIMER3_COMPA_vect)
{
PORTL ^= (1<<PL0);
}

Martinius11
18.12.2013, 00:49
Guten Abend,

ich glaube dir mal das der Code so passt und vermute, dass du die Fuses nicht richtig gesetzt hast.

radbruch
18.12.2013, 07:24
Hallo

Laut Tabelle auf Seite 148 im Datenblatt des Mega2560 bedeutet WGM31 gesetzt den Mode 2 (PWM, Phase Correct, 9-bit). CTC-Mode 4 wird mit WGM32 gesetzt im TCCR3B ausgewählt:

http://www.atmel.com/images/doc2549.pdf

Ich hoffe, ich liege richtig mit dieser Aussage.

Gruß

mic

QuadV
18.12.2013, 08:34
Guten Abend,

ich glaube dir mal das der Code so passt und vermute, dass du die Fuses nicht richtig gesetzt hast.

Guten Morgen

Vielen Dank für die Antwort. Ich dachte zuerst auch dass es daran liegen könnte. Aber eben der UART funktioniert einwandfrei und wenn der uC mit einer falschen Frequenz laufen würde, würde ja die Baudrate nicht stimmen. Ich habe trotzallem gestern noch ein _delayms(1000) ausprobiert und das funktioniert.

MFG QuadV

- - - Aktualisiert - - -


Hallo

Laut Tabelle auf Seite 148 im Datenblatt des Mega2560 bedeutet WGM31 gesetzt den Mode 2 (PWM, Phase Correct, 9-bit). CTC-Mode 4 wird mit WGM32 gesetzt im TCCR3B ausgewählt:

http://www.atmel.com/images/doc2549.pdf

Ich hoffe, ich liege richtig mit dieser Aussage.

Gruß

mic

Danke, das dürfte es sein! Ich habe auf der Seite 131 geschaut, das sind allerdings 8Bit Timer... Oh mann... Wer lesen kann ist im Vorteil! Ich werde dies am Abend gleich ausprobieren! Danke vielmals für den Hinweis!

QuadV
19.12.2013, 00:20
Hallo

Laut Tabelle auf Seite 148 im Datenblatt des Mega2560 bedeutet WGM31 gesetzt den Mode 2 (PWM, Phase Correct, 9-bit). CTC-Mode 4 wird mit WGM32 gesetzt im TCCR3B ausgewählt:

http://www.atmel.com/images/doc2549.pdf

Ich hoffe, ich liege richtig mit dieser Aussage.

Gruß

mic

So nun konnte ich endlich noch etwas daran machen... Also ich habe den Fehler mit dem WGM bit behoben. Ich setzte nun das WGM32 bit. Nun habe ich aber folgendes problem dass egal welchen wert ich meiner variable Timer gebe, die frequenz gleich bleibt! Und zwar etwa bei 0.3Hz..

Ich habe nun um zu schauen mal das ganze auf den 8 Bit Timer angewendet und da funktioniert es einwandfrei, nur kann ich da natürlich keine 1Hz erreichen. Gibt es irgendwas bei den 16bit Timern was ich berücksichtigen muss? Ich bin kurz vor der Verzweiflung...

Hier der ensprechende Code:
#define F_CPU 16000000UL

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


int main(void)
{
uint16_t Timer = ((F_CPU/1024) -1); //egal was, frequenz bleibt gleich
TCCR3A = (1<<WGM32); //CTC Mode
TCCR3B = (1<<CS32) | (1<<CS30); //prescaler 1024

OCR3AH = (uint8_t) (Timer>>8); //t = 1s
OCR3AL = (uint8_t) Timer;

TIMSK3 |= (1<<OCIE3A); //Compare interupt aktivieren

uint16_t Timer2 = 255; //Frequenz ändert sich
TCCR0A = (1<<WGM01); //CTC Mode
TCCR0B = (1<<CS02) | (1<<CS00); //prescaler 1024

OCR0A = Timer2;

TIMSK0 |= (1<<OCIE0A); //Compare interupt aktivieren

DDRL = 0xFF;
sei();

while(1)
{
//TODO:: Please write your application code
}
}

ISR(TIMER3_COMPA_vect)
{
PORTL ^= (1<<PL0);
}

ISR(TIMER0_COMPA_vect)
{
PORTL ^= (1<<PL1);
}

radbruch
19.12.2013, 08:32
Nur keine Panik. Schau mal hier:

https://www.roboternetz.de/community/attachment.php?attachmentid=26971&d=1387438265

QuadV
19.12.2013, 08:49
Nur keine Panik. Schau mal hier:

https://www.roboternetz.de/community/attachment.php?attachmentid=26971&d=1387438265

Haha... Danke für den Hinweis... Naja, war vielleicht nicht die beste Idee um halb eins am morgen noch schnell etwas daran zu machen...