Forum: Mikrocontroller und Digitale Elektronik Timer2 Atmega328


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Kai (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Schau mal im Simulator ob der Timer zählt.

von Kai (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


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

Ich benutze Version 7.0.943

von Kai (Gast)


Bewertung
0 lesenswert
nicht 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)


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

Gruß JackFrost

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.