Forum: Mikrocontroller und Digitale Elektronik mega2561 neue timer registernamen


von Philipp Karbach (Gast)


Lesenswert?

Hallo,
gibt es eigentlich schon ein paar hier die mit dem mega256(0/1) 
arbeiten? Ich hab seit ca. einer woche ein modul mit diesem µC und komme 
ganz gut klar, allerdings verstehe ich die Änderungen bei den Timern 
nicht. Kriege nichtmal mein einfaches beispiel vom mega32 geportet. Weiß 
jemand rat?

#define CPU   16000000
#define TIMER   65535 - (CPU/1024)

volatile int second=0;

void timer_init (void) {
    TCCR1B = (1<<CS12) | (1<<CS10);
    TIMSK |= (1<<TOIE1);
    TCNT1 = TIMER;
    sei ();
}

SIGNAL (SIG_OVERFLOW1)
{
  second++;
  TCNT1 = TIMER;
}

int main()
{
  timer_init();

    TCCR0 = (_BV(WGM00) | _BV(COM01) | _BV(COM00) | _BV(CS00));

    for(;;);
    return 0;

}

Danke :).

von Matthias (Gast)


Lesenswert?

1
SIGNAL (SIG_OVERFLOW1)


Das ist "veraltet". In WinAVR wird das anders beschrieben: (glaub das 
war so)
1
ISR(USART_TXC_vect)

gucke aber mal lieber nach

von Philipp Karbach (Gast)


Lesenswert?

aha, ist mir nie aufgefallen. Ich habe versucht das mit der erhältlichen 
Tabelle zu porten, es lässt sich auch kompilieren nur leider zeigt es 
keinerlei funktion.

so sieht der port aus:

#define CPU 8000000
#define TIMER 65535 - (CPU/1024)

volatile int second=0;


SIGNAL (SIG_OVERFLOW0) {
  second++;
  TCNT0 = TIMER;
}
void timer_init (void) {
    TCCR1B = (1<<CS12) | (1<<CS10);
    TIMSK0 |= (1<<TOIE1);
    TCNT0 = TIMER;
    sei ();
}

int main()
{
  timer_init();
    TCCR0A = (_BV(WGM01)| _BV(WGM00) | _BV(WGM01) | _BV(COM0A1) | 
_BV(COM0A0) | _BV(COM0B1) | _BV(COM0B0));

    for(;;);
    return 0;
}

von Jörg X. (Gast)


Lesenswert?

1
#define CPU 8000000
2
#define TIMER 65535 - (CPU/1024)
3
/* da kommt nicht sinnvolles bei raus, der avr-gcc
4
rechnet konstanten per default als 16Bit-Ints
5
erster schritt ist also: */
6
#define CPU 8000000UL //das u ist nicht unbedingt notwendig, aber das L!
7
#define TIMER 65535 - (CPU/1024)
8
// eigentlich ist F_CPU üblich:
9
#define F_CPU 8000000UL
Und das sei() in der init-Funktion halte ich zumindest für keine so gute 
Idee, wenn die Initialisierung noch nicht fertig ist.

hth. Jörg

von Philipp Karbach (Gast)


Lesenswert?

Das mag wohl sein, aber mit dem Mega32 funktioniert es immer blendend, 
dennoch danke für die korrektur war mir dabei nicht so genau sicher. 
Weiß denn keiner wie das mit dem mega2561 geht? Ich versteh die Tabelle 
im Datenblatt nicht besonders, gerade weil ich nicht genau weiß welcher 
von den neuen Timern wie funktioniert..

von Gast (Gast)


Lesenswert?

Warum TCNT_NULL in der ISR?

von Jörg X. (Gast)


Lesenswert?

Die Tabelle ist doch wirklich leicht zu verstehen!

scnr --Jörg

ps.: Ich hab keine Ahnung welche Tabelle du meinst

von Gast (Gast)


Lesenswert?

murks zwischen Timer 1 und Timer 0

Timer0 wird konfiguriert und kriegt ne ISR, Timer kriegt den Takt.
thumbs up

Timer0 ist übrigens nur 8bit-->dein TIMER #define

von Philipp Karbach (Gast)


Lesenswert?

http://www.atmel.com/dyn/resources/prod_documents/2549S.pdf Seite 10 und 
folgende, wenn das alles so falsch ist warum berichtigt es dann keiner? 
Ich verstehe es eben noch nicht so ganz.

von Gast (Gast)


Lesenswert?


von Gast (Gast)


Lesenswert?

Philipp,
mir ist nicht mal klar, was du eigentlich machen willst. Aber auf jeden 
Fall solltest du dich auf EINEN Timer festlegen. Der AVR hat mehrere, 
Timer0, Timer1, Timer2 und Du arbeitest mal mit dem einen ein bisschen, 
dann mit dem anderen. Aber keiner wird zuende/richtig initialisiert.

statt  TCCR1B = (1<<CS12) | (1<<CS10);

ist auf JEDEN FALL

 TCCR0B = (1<<CS12) | (1<<CS10);

besser! :)

von Philipp Karbach (Gast)


Lesenswert?

das ist allerdings möglich dass keine vollständige initialisierung 
stattfindet, im moment versuche ich das beispiel für den mega32 auf den 
mega2561 zu portieren, es soll mit jedem überlauf die die second 
variable erhöhen und somit eine einfache Uhr bzw. die Laufzeit 
darzustellen.

von Philipp Karbach (Gast)


Lesenswert?

so ich habe jetzt eine funktionierende version hinbekommen, da war 
wirklich eine kleine verwechslung der register drin, danke nochmal, 
bitte korrigiert den code wenn er dennoch falsch ist:

#define CPU 8000000UL
#define TIMER 65535 - (CPU/1024)

SIGNAL (SIG_OVERFLOW1) {
  second++;
  TCNT1 = TIMER;
}

void timer_init (void) {
    TCCR1B = (1<<CS12) | (1<<CS10);
    TIMSK1 |= (1<<TOIE1);
    TCNT1 = TIMER;
    sei ();
}

int main()
{
  timer_init();
    TCCR0A = (_BV(WGM00) | _BV(COM0A1) | _BV(COM0A0) | _BV(CS00));
}

von Jörg X. (Gast)


Lesenswert?

Das Bit CS00 ist in TCCR0B nicht T...A. ;-)
Beim Timer1 wäre der CTC-Modus besser geeignet, als manuell das 
TCNT-Register nachzuladen:
1
    // timer1 zählt bis:
2
    ICR1 = F_CPU/1024;
3
    // Mode 12, "CTC mit ICR als TOP", prescaler 1024
4
    TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS12)|(1<<CS10);
Achja, schreib doch entweder die ganzer Timer initialisierung in eine 
(static inline) Funktion, oder alles in main(), aber so halb-und-halb 
ist irgendwie unschön ;)

hth. Jörg

von Matthias (Gast)


Lesenswert?

Was macht denn die main NACH der timer initialisierung...?
;-)

von Jörg X. (Gast)


Lesenswert?

@Matthias:
> Was macht...
Wir sehen hier doch nur das gekürzte Programm, in echt gibt's da 
natürlich 'ne Endlosschleife ;-)

scnr --Jörg

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.