Timer CTC Mode

Gast #5056945
Hallo,

ich habe nun 2 Stunden einen Fehler gesucht und ihn endlich gefunden. 
Verstehe aber nicht so recht wieso es nicht funktioniert hatte. Ich will 
mir einen Takt von 500Hz an Pin OC5A ausgeben. Dies im CTC Mode.

//ATmega2560
1
//Dieser Code hat nicht funktioniert:
2
  TCCR5A |= (1<<COM5A0);                  // Portpin an Timer angekoppelt  => fclk                   
3
  TCCR5B |= ((1<<WGM52) | (1<<CS01) | (1<<CS00));        // Timer 5: Clear on Compare / Prescale: 64
4
  
5
  OCR5AH = 0;                        // Timer 5 Compare Value
6
  OCR5AL = 249;
7
  //OCR0AL  =  124;                      
8
  // fOC0B = fosc / ( 2 * Prescale * ( OCR0A + 1 ) )
9
  // fosc = 16 MHz => fOC0B = 1000 Hz ( OCR0A = 124 )
10
  // fosc = 16 MHz => fOC0B =  500 Hz ( OCR0A = 249 )
1
//Dieser schon:
2
  TCCR5A = (1<<COM5A0);                  // Portpin an Timer angekoppelt  => fclk                   
3
  TCCR5B |= ((1<<WGM52) | (1<<CS01) | (1<<CS00));        // Timer 5: Clear on Compare / Prescale: 64
4
  
5
  OCR5AH = 0;                        // Timer 5 Compare Value
6
  OCR5AL = 249;
7
  //OCR0AL  =  124;                      
8
  // fOC0B = fosc / ( 2 * Prescale * ( OCR0A + 1 ) )
9
  // fosc = 16 MHz => fOC0B = 1000 Hz ( OCR0A = 124 )
10
  // fosc = 16 MHz => fOC0B =  500 Hz ( OCR0A = 249 )

TCCR5A habe ich vorher nirgends benutzt. Müsste dann doch eigentlich 
seinen Initialwert von 0x00 haben.
Gast #5057107
eProfi schrieb:
> Gib halt für beide Fälle die Register-Werte aus (z.B. über die
> Serielle).
> Ggf. vorher / nachher.

Solange wieder kein kompletter, compilierbarer, auf das Problem 
gekürzter Code vorliegt kann man sich das Rat und Raten ersparen.
Gast #5057297
Ja und, ich will 440,0 Hz an Pin OBOE ausgeben.

Warum sollten wir jetzt auf die Suche gehen, welches
Datenblatt von welchem µC du wohl nicht richtig gelesen
hast?
Gast #5057643
Ich verwende einen Arduino Mega...

Dieses Programm geht nicht...
1
/* Interruptsteuerung */
2

3
#define ENAB_GLOBAL_INT     asm("sei")               // Set I-Bit in SREG
4
#define DISAB_GLOBAL_INT    asm("cli")                  // Reset I-Bit in SREG
5

6
/* Pin- und Portdefinitionen */
7

8
/********************************* Schrittmotor 1 *******************************************************************************************/
9
#define SM1_CLK_PIN    DDRL |= (1<<DDL3);PORTL |= (1<<PORTL3)   // Port L, Bit 3 => CLK Schrittmotor (Atmel -> Motor) -> OUTPUT, ON   //
10
/********************************************************************************************************************************************/
11

12
/*************************/
13
/******* Functions *******/
14
/*************************/
15
void Motor_Init (void);
16

17
void Motor_Init (void)
18
{
19
  SM1_CLK_PIN;
20

21
  TCCR5A |= (1<<COM5A0);                 // Portpin an Timer angekoppelt  => fclk                  
22
  TCCR5B |= ((1<<WGM52) | (1<<CS01) | (1<<CS00));       // Timer 5: Clear on Compare / Prescale: 64
23
  
24
                      
25
  OCR5A = 249;                      // Timer 5 Compare Value
26
  //OCR0A  =  124;                      
27
  // fOC0B = fosc / ( 2 * Prescale * ( OCR0A + 1 ) )
28
  // fosc = 16 MHz => fOC0B = 1000 Hz ( OCR0A = 124 )
29
  // fosc = 16 MHz => fOC0B =  500 Hz ( OCR0A = 249 )
30
  
31

32
  
33
  EICRA |=  ((1<<ISC31) | (1<<ISC30));          // INT 3 (Kanal A SM1): positive Flanke 
34
  
35
  //EICRA |=  ((1<<ISC30));               // INT 3 (Kanal A SM1): beide Flanken 
36
  //EICRA &= ~((1<<ISC31));
37
  
38
  EICRB |=  ((1<<ISC50) | (1<<ISC40));          // INT 4 (Kanal A SM2) u. INT 5 (Kanal A SM3): beide Flanken  
39
  EICRB &= ~((1<<ISC51) | (1<<ISC41));          
40
  }
41
  
42
  
43
  
44
void setup (void)
45
{
46
  DISAB_GLOBAL_INT;
47
  
48
  Motor_Init ();
49
}
50

51
void loop (void)
52
{
53

54
}

Dieses schon...
1
/* Interruptsteuerung */
2

3
#define ENAB_GLOBAL_INT     asm("sei")               // Set I-Bit in SREG
4
#define DISAB_GLOBAL_INT    asm("cli")                  // Reset I-Bit in SREG
5

6
/* Pin- und Portdefinitionen */
7

8
/********************************* Schrittmotor 1 *******************************************************************************************/
9
#define SM1_CLK_PIN    DDRL |= (1<<DDL3);PORTL |= (1<<PORTL3)   // Port L, Bit 3 => CLK Schrittmotor (Atmel -> Motor) -> OUTPUT, ON   //
10
/********************************************************************************************************************************************/
11

12
/*************************/
13
/******* Functions *******/
14
/*************************/
15
void Motor_Init (void);
16

17
void Motor_Init (void)
18
{
19
  SM1_CLK_PIN;
20

21
  TCCR5A = (1<<COM5A0);                 // Portpin an Timer angekoppelt  => fclk                  
22
  TCCR5B |= ((1<<WGM52) | (1<<CS01) | (1<<CS00));       // Timer 5: Clear on Compare / Prescale: 64
23
  
24
                      
25
  OCR5A = 249;                      // Timer 5 Compare Value
26
  //OCR0A  =  124;                      
27
  // fOC0B = fosc / ( 2 * Prescale * ( OCR0A + 1 ) )
28
  // fosc = 16 MHz => fOC0B = 1000 Hz ( OCR0A = 124 )
29
  // fosc = 16 MHz => fOC0B =  500 Hz ( OCR0A = 249 )
30
  
31

32
  
33
  EICRA |=  ((1<<ISC31) | (1<<ISC30));          // INT 3 (Kanal A SM1): positive Flanke 
34
  
35
  //EICRA |=  ((1<<ISC30));               // INT 3 (Kanal A SM1): beide Flanken 
36
  //EICRA &= ~((1<<ISC31));
37
  
38
  EICRB |=  ((1<<ISC50) | (1<<ISC40));          // INT 4 (Kanal A SM2) u. INT 5 (Kanal A SM3): beide Flanken  
39
  EICRB &= ~((1<<ISC51) | (1<<ISC41));          
40
  }
41
  
42
  
43
  
44
void setup (void)
45
{
46
  DISAB_GLOBAL_INT;
47
  
48
  Motor_Init ();
49
}
50

51
void loop (void)
52
{
53

54
}

Einziger Unterschied ist das Beschreiben von TCCR5A.

Nach dem Start sollte doch 0x00 in diesem stehen.
Gast #5057683
Hi

>Nach einem Reset steh bei mir immer noch 0x01 drin.

Hast du überhaupt die Möglichkeit den Controller direkt nach dem Reset 
anzuhalten und nach zu sehen?

MfG Spess
Gast #5057713
Nein..., Datenblatt des Atmel. Steht jedenfalls 0x01 drin und vorher 
mache ich nichts mit diesem Register. Ich frage mich einfach warum WGM50 
gesetzt ist.
Egal, dann ists halt so. Ich werde es mal mit dem STK500 probieren und 
schauen was dort passiert.
Gast #5057724
Gibt es einen bestimmten Grund warum das hier in diesem Programm auch so 
gemacht wird?
Würde es bei TCCR2A mit |= funktionieren?

https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Z%C3%A4hler_des_AVR
1
/* uC: ATMega48PA */
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4

5
//Variablen für die Zeit
6
volatile unsigned char sekunde;
7
volatile unsigned char minute;
8
volatile unsigned char stunde;
9

10
int main(void)
11
{
12
  // Timer 2 konfigurieren
13
  GTCCR |= (1 << TSM) | (1 << PSRASY);  //Timer anhalten, Prescaler Reset
14
  ASSR |= (1 << AS2);                   //Asynchron Mode einschalten
15
  TCCR2A = (1 << WGM21);                //CTC Modus
16
  TCCR2B |= (1 << CS22) | (1 << CS21);  //Prescaler 256
17
  // 32768 / 256 / 1 = 128                Intervall = 1s
18
  OCR2A = 128 - 1;
19
  TIMSK2 |= (1<<OCIE2A);                //Enable Compare Interrupt
20
  GTCCR &= ~(1 << TSM);                 //Timer starten
21
  sei();                                //Enable global Interrupts
22

23
  while(1)
24
  {
25
    /*Hier kann die aktuelle Zeit
26
      ausgeben werden*/
27
  }
28
}
29

30
/*
31
Der Compare Interrupt Handler 
32
wird aufgerufen, wenn 
33
TCNT2 = OCR2A = 128-1 
34
ist (128 Schritte), d.h. genau alle 1s
35
*/
36
ISR (TIMER2_COMPA_vect)
37
{
38
    TCCR2B = TCCR2B;              //Wird weiter unten im Text erklärt!
39
    sekunde++;
40
    if(sekunde == 60)
41
    {
42
      minute++;
43
      sekunde = 0;
44
    }
45
    if(minute == 60)
46
    {
47
      stunde++;
48
      minute = 0;
49
    }
50
    if(stunde == 24)
51
    {
52
      stunde = 0;
53
    }
54
    // Wird weiter unten im Text erklärt!
55
    while(ASSR & ((1<<TCN2UB) | (1<<OCR2AUB) | (1<<OCR2BUB) |
56
                  (1<<TCR2AUB) | (1<<TCR2BUB)));
57
}
Gast #5057735
> vorher mache ich nichts mit diesem Register
Schon; aber, wie es scheint, der Arduino.

Und ob dieser das TCCR2A anfasst, steht auf einem anderen Blatt.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.