Forum: Mikrocontroller und Digitale Elektronik Timer CTC Mode


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 Robert (Gast)


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

von eProfi (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Gib halt für beide Fälle die Register-Werte aus (z.B. über die 
Serielle).
Ggf. vorher / nachher.

von molteee (Gast)


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

von Jacko (Gast)


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

von Johann L. (gjlayde) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Robert schrieb:
>   OCR5AH = 0;                        // Timer 5 Compare Value
>   OCR5AL = 249;

Auch wenn's mit dem Problem nix zu tun hat:  Es gibt keinen Grund, das 
Byte-weise zu setzen.  Machst du mit normalen Variablen ja auch nicht...
1
OCR5A = 249;

von Robert (Gast)


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

von Robert (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Steht aber 0x01 drin. Bzw. dann 0x41.

von spess53 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hi

>Nach dem Start sollte doch 0x00 in diesem stehen.

Nach einem Reset steht da 0x00. Das ist ein Unterschied.

MfG Spess

von S. Landolt (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Arduino - aha.
Dann bleibt nur zu wiederholen:

eProfi schrieb:
> Gib halt für beide Fälle die Register-Werte aus (z.B. über die
> Serielle).
> Ggf. vorher / nachher.

von Robert (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Laut Datenblatt: Initial Value 0x00.
Ich verstehe darunter Startwert. Nach einem Reset steh bei mir immer 
noch 0x01 drin.

von S. Landolt (Gast)


Bewertung
0 lesenswert
nicht lesenswert
> Laut Datenblatt: Initial Value 0x00.
Datenblatt des Arduino?

von spess53 (Gast)


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

von Robert (Gast)


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

von Robert (Gast)


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

von S. Landolt (Gast)


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

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.