Timer CTC Mode

Gast #5056945
Lesenswert?

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 #5057643
Lesenswert?

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 #5057713
Lesenswert?

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
Lesenswert?

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
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren