Forum: Mikrocontroller und Digitale Elektronik Timer2 Atmega328


von Kai (Gast)


Lesenswert?

Guten morgen,
ich habe ein Problem mit dem Timer2 bei einem Atmega328. Dieser hat 
einen 16MHz quarz angeschlossen.
1
TCCR0A & ~(1 << WGM00) | (1 << WGM01) & ~(1 << WGM02);
2
TCCR0B | (1 << CS00) | (1 << CS01) & ~(1 << CS02);
3
OCR0A = 250 - 1;
4
TIMSK0 | (1 << OCIE0A));
5
6
TCCR2A & ~(1 << WGM20) | (1 << WGM21) & ~(1 << WGM22);
7
TCCR2B & ~(1 << CS20) & ~(1 << CS21) | (1 << CS22);
8
OCR2A = 250-1;
9
TIMSK2 | (1 << OCIE2A));
1
void TIMER0_COMPA_vect(void)
2
{
3
    static uint16_t millis = 0;
4
    static uint8_t seconds = 0;
5
    static uint8_t minutes = 0;
6
    static uint8_t hours = 0;
7
    millis++;
8
    if(millis >= 1000)
9
    {
10
        //PORTB ^= ( 1 << PORTB5 );
11
        seconds++;
12
        millis = 0;
13
        if(seconds >= 10 )
14
        {
15
            minutes++;
16
            seconds = 0;
17
            if(minutes >= 10)
18
            {
19
                hours++;
20
                minutes = 0;
21
                if(hours >= 10)
22
                {
23
                    hours = 0;
24
                }
25
            }
26
        }
27
    }
28
}
29
30
31
void TIMER2_COMPA_vect(void)
32
{
33
    static uint16_t millis = 0;
34
    static uint8_t seconds = 0;
35
    millis++;
36
    if(millis >= 1000)
37
    {
38
        PORTB ^= ( 1 << PORTB5 );
39
        seconds++;
40
        millis = 0;
41
    }
42
}

eigentlich sollten so beide Timer gleich laufen. Wenn ich zur Probe eine 
LED in Timer0 blinken lasse, blinkt diese auch im Sekundentakt. Aber in 
der ISR vom Timer2 wird die LED nicht getoggelt. Hier bleibt diese aus 
(habe dazu natürlich das Togglen aus der ISR vom Timer0 herausgenommen).

Nach Beitrag "Atmega328p Timer2 will nicht" liegt es daran 
dass der Timer2 zwei Teiler mehr hat als Timer0. Aber im Datenblatt 
finde ich für Teiler nur das Register TCCR2B.

Wo finde ich den zweiten?

Gruß Kai

von Bastian W. (jackfrost)


Lesenswert?

Du initialisierst die CS20 - 21 Bits mit null , da läuft der Timer ja 
nicht.
Du musst das ja wie bei TCRR0B machen mit |= 1<<CS2x

Wenn du mit dem Atmel Studio schreibst , simulier es , halte die CPU an 
und schau dir die Register an, dann siehst du ob die Initialisierung 
passt.

Gruß JackFrost

: Bearbeitet durch User
von Kai (Gast)


Lesenswert?

Bastian W. schrieb:
> Du initialisierst die CS20 - 21 Bits mit null , da läuft der Timer ja
> nicht.

Aber ich setze doch CS22 auf 1
(1 << CS22) -> clkT2S/64 (From prescaler)

von sing sang song (Gast)


Lesenswert?

Kai schrieb:
> [code]
> TCCR0A & ~(1 << WGM00) | (1 << WGM01) & ~(1 << WGM02);
> TCCR2A & ~(1 << WGM20) | (1 << WGM21) & ~(1 << WGM22);
> [code]

WGM02 und WGM22 ist schon mal Mist. Man sollte schon schauen, wo sich 
die Bits befinden. Wenn es auch nicht das Problem sein wird.

von Kai (Gast)


Lesenswert?

Bzw. Die Initialierung muss anders sein
1
TCCR0A |= (1 << WGM01);
2
TCCR0B |= (1 << CS00) | (1 << CS01);
3
OCR0A = 250 - 1;
4
TIMSK0 |= (1 << OCIE0A));
5
6
TCCR2A |= (1 << WGM21);
7
TCCR2B |= (1 << CS22);
8
OCR2A = 250-1;
9
TIMSK2 |= (1 << OCIE2A));

Im obigen Beispiel wurden die Register gar nicht gesetzt. Jetzt schreibe 
ich nur die Bits auf, die ich auch setzen möchte. Allerdings geht es 
immer noch nciht.

von Bastian W. (jackfrost)


Lesenswert?

Kai schrieb:
> Bastian W. schrieb:
>> Du initialisierst die CS20 - 21 Bits mit null , da läuft der Timer ja
>> nicht.
>
> Aber ich setze doch CS22 auf 1
> (1 << CS22) -> clkT2S/64 (From prescaler)

Nein , mit deiner Zeile
1
TCCR2B & ~(1 << CS20) & ~(1 << CS21) | (1 << CS22);

Verundest du das Register mit dem Bit CS22. Das Ergebnis ist 0 da CS22 
im Register nicht gesetzt ist.

Ist die Zeile eine copy Paste Zeile von der darüber ?

von Bastian W. (jackfrost)


Lesenswert?

Schau mal im Simulator ob der Timer zählt.

von Kai (Gast)


Lesenswert?

Bastian W. schrieb:
> enn du mit dem Atmel Studio schreibst , simulier es , halte die CPU an
> und schau dir die Register an, dann siehst du ob die Initialisierung
> passt.

Das kann ich leider nicht machen. Der Atmega ist auf einem Arduino und 
ich Flashe diesen über USB. Habe versucht, den Mikrocontroller mit 
meinem Diamex-ProgS zu flashen, bekomme diesen aber nicht zu laufen.

Habe als Selected debugger STK500 mit dem Interface: ISP gewählt.
Bekomme aber den Error
Failed to open \\.\COM4. Error 0x2

Im Gerätemanager taucht dieser unter USB-Geräte auf. Bei Speicherort 
steht Port_#0001.Hub_#0004
Desweiteren ist die LED vom Programmer die ganze Zeit am Blinken

von Bastian W. (jackfrost)


Lesenswert?

Kai schrieb:
> TIMSK0 |= (1 << OCIE0A));
>TIMSK2 |= (1 << OCIE2A));

Bei beiden Zeilen ist eine schließende Klammer zu viel. Compiliert die 
Arduion IDE dann überhaupt ?

Mit diesem Programm laufen beide Timer mit dem Simulator
1
#define F_CPU 8000000Ul
2
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
#include <string.h>
6
#include <util/delay.h>
7
#include <stdlib.h>
8
9
10
11
12
ISR(TIMER0_COMPA_vect)
13
{
14
  static uint16_t millis = 0;
15
  static uint8_t seconds = 0;
16
  static uint8_t minutes = 0;
17
  static uint8_t hours = 0;
18
  millis++;
19
  if(millis >= 1000)
20
  {
21
    //PORTB ^= ( 1 << PORTB5 );
22
    seconds++;
23
    millis = 0;
24
    if(seconds >= 10 )
25
    {
26
      minutes++;
27
      seconds = 0;
28
      if(minutes >= 10)
29
      {
30
        hours++;
31
        minutes = 0;
32
        if(hours >= 10)
33
        {
34
          hours = 0;
35
        }
36
      }
37
    }
38
  }
39
}
40
41
42
ISR(TIMER2_COMPA_vect)
43
{
44
  static uint16_t millis = 0;
45
  static uint8_t seconds = 0;
46
  millis++;
47
  if(millis >= 1000)
48
  {
49
    PORTB ^= ( 1 << PORTB5 );
50
    seconds++;
51
    millis = 0;
52
  }
53
}
54
55
int main()
56
{
57
  TCCR0A |= (1 << WGM01);
58
  TCCR0B |= (1 << CS00) | (1 << CS01);
59
  OCR0A = 250 - 1;
60
  TIMSK0 |= (1 << OCIE0A);
61
62
  TCCR2A |= (1 << WGM21);
63
  TCCR2B |= (1 << CS22);
64
  OCR2A = 250-1;
65
  TIMSK2 |= (1 << OCIE2A);
66
  sei();
67
  while(1)
68
  {
69
    
70
  }
71
72
}

Gruß JackFrost

von Karl M. (Gast)


Lesenswert?

Guten Morgen und ein gutes neues Jahr.

Es wurde schon versucht "mit Hilfe zur Selbsthilfe" dir weiter zu 
helfen.

Manchmal sieht man den "Wald vor lauter Bäumen nicht", so lautet ein 
Sprichwort.
Es ist dir nicht aufgefallen, dass z.B. diese Zeile nichts an TCCR0A 
ändert !
1
TCCR0A & ~(1 << WGM00) | (1 << WGM01) & ~(1 << WGM02)

Register löschen
1
TCCR0A = 0; // clean up

Bit setzen:
1
TCCR0A = TCCR0A | (1 << WGM00)

Bit löschen:
1
TCCR0A = TCCR0A & (uint8_t)~(1 << WGM00);

ps. ich habe bewusst die Anweisung in der Zeile nicht in der 
Kurzschreibweise geschrieben.
1
TCCR0A |= (1 << WGM00)
1
TCCR0A &= (uint8_t)~(1 << WGM00);

von Kai (Gast)


Lesenswert?

Bastian W. schrieb:
>> TIMSK0 |= (1 << OCIE0A));
>>TIMSK2 |= (1 << OCIE2A));

Das kam daher, dass ich den Code aus meinem Ersten Post kopiert und 
angepasst habe. In AtmelStudio waren die Klammern weg.

Bastian W. schrieb:
> Bei beiden Zeilen ist eine schließende Klammer zu viel. Compiliert die
> Arduion IDE dann überhaupt

Ich Programmiere in AtmelStudio. Aber auch hier wäre es zu einem 
Compiler-Fehler gekommen.

Karl M. schrieb:
> Es ist dir nicht aufgefallen, dass z.B. diese Zeile nichts an TCCR0A
> ändert !

Daher habe ich das ja nochmal umgeschrieben.


Allerdings bekomme ich den Controller immer noch nicht über den 
Programmer geflasht. Das COM-Problem habe ich gelöst, allerdings bekomme 
ich jetzt den Error
Failed to launch program.
Error: Failed to start programming session before chip erase witz eeprom 
preserve: Failed to enter programming mode. ispEnterProgMode: Error 
status received: Got 0xc0, expected 0x00 (Command has failed to execute 
on the tool)

von Bastian W. (jackfrost)


Lesenswert?

Wenn du im Atmelstudio schreibst,kannst du doch simulieren. Das hat 
nichts mit dem Programm zu tun. Schau mal ob dein Programm in der 
Simulation überhaupt läuft. Welches Studio verwendest du ? 4.19 , 6.x 
oder 7.x ?

Gruß JackFrost

von Kai (Gast)


Lesenswert?

Bastian W. schrieb:
> Welches Studio verwendest du ? 4.19 , 6.x
> oder 7.x ?

Ich benutze Version 7.0.943

von Kai (Gast)


Lesenswert?

Das mit der Simulation kannte ich so noch gar nicht.
Das Problem ist, TCCR2B gar nicht gesetzt wird.
1
TCCR2B |= (1 << CS22);
Alle anderen werden gesetzt. Wenn ich das Bit dann nachträglich setze, 
wird auch in die ISR gesprungen.

von Bastian W. (jackfrost)


Lesenswert?

Poste mal den ganzen Code deiner main.c als Datei hier um Forum ?
Bei meinem Beispiel ist das Bit gesetzt.

Gruß JackFrost

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.