Timer Probleme mit ATtiny1606

#7680301
Lesenswert?

Hallo,

ich versuche gerade ein Programm auf den ATtiny1606 zu portieren. Im ursprünglichen Projekt, geschrieben für ATmega328, Wird der Timer gestartet und im weiteren Programmverlauf gestoppt, das Interval neu berechnet und neu gestartet.

Das versuche ich gerade bei dem 1606 mit dem TCA0 zu konfigurieren. Leider wird der Interrupt scheinbar nicht korrekt ausgeführt und wenn, dann hat die Variable timerInterval keinen Einfluss auf die Zeit. Hier mein Versuch.

1
void startTimer(uint32_t timerInterval)
2
{
3
  if ( timerInterval > 0 )
4
  {
5
      TCA0.SINGLE.CTRLA = 0;                                        // Stop timer
6
      TCA0.SINGLE.INTFLAGS = TCA_SINGLE_CMP0_bm;                    // Clear interrupt flag
7

8
      TCA0.SINGLE.CTRLB  = TCA_SINGLE_ALUPD_bm;                     // enabled Auto Lock Update
9
      TCA0.SINGLE.CTRLB  = TCA_SINGLE_WGMODE_FRQ_gc;                // Frequency Mode
10
      TCA0.SINGLE.CTRLA  = TCA_SINGLE_CLKSEL_DIV8_gc;               // Prescaler
11
            
12
      if (timerInterval > 65535) {
13
          TCA0.SINGLE.CMP0H = (65535 >> 8);
14
          TCA0.SINGLE.CMP0L = (65535 & 0xFF);
15
      } else {
16
          TCA0.SINGLE.CMP0H = (timerInterval >> 8);
17
          TCA0.SINGLE.CMP0L = (timerInterval & 0xFF);
18
      }
19

20
      TCA0.SINGLE.INTCTRL = TCA_SINGLE_CMP0_bm;
21
      TCA0.SINGLE.CTRLA |= TCA_SINGLE_ENABLE_bm;                    // enable TCA module
22
      timerOn = true;                                                              
23
       
24
  }
25

26
}
27

28
void stopTimer()
29
{
30
  TCA0.SINGLE.CTRLA = 0;                            // Stop timer
31
  TCA0.SINGLE.INTCTRL = 0;                          // Disable interrupts
32
  timerOn = false;
33
  
34
}
35

36
ISR (TCA0_CMP0_vect)
37
{
38
  TCA0.SINGLE.INTFLAGS = TCA_SINGLE_CMP0_bm;  // Clear interrupt flag
39
}

Bin jetzt bereits knapp eine Woche dabei diesen Timer zu bändigen, aber ohne Erfolg. Hoffe, Ihr könnt mir helfen.

VG Matze

#7680386
Lesenswert?

Das hier war mein Code zum testen....

1
#define COIL_PIN A1  // Beispiel: Pin A1 für die Spule
2
#define timerInterval 2000
3
bool timerOn = false;
4

5
void setup() {
6
  pinMode(COIL_PIN, OUTPUT);  // Setzen des Pins als Ausgang
7
  
8
  takeOverTCA0();                                               // This replaces disabling and resettng the timer, required previously.
9
  TCA0.SINGLE.CTRLA = 0;                                        // disable TCA0 and set divider to 1
10
  TCA0.SINGLE.CTRLESET = TCA_SINGLE_CMD_RESET_gc|0x03;           // set CMD to RESET to do a hard reset of TCA0.
11
  
12
  TCA0.SINGLE.CTRLB  = TCA_SINGLE_WGMODE_FRQ_gc;                // Frequency Mode
13
  TCA0.SINGLE.CTRLA  = TCA_SINGLE_CLKSEL_DIV8_gc;               // Prescaler
14

15
  TCA0.SINGLE.INTCTRL = TCA_SINGLE_CMP0_bm;
16
  
17
  sei();
18
  startTimer();
19
}
20

21
void loop() {
22
  if (!timerOn) {
23
    startTimer();
24
  }
25
}
26

27
void startTimer() {
28
  if ( timerInterval > 0 )
29
  {
30
      
31
      if (timerInterval > 65535) {
32
          TCA0.SINGLE.CMP0BUF = 65535;
33
      } else {
34
          TCA0.SINGLE.CMP0BUF = timerInterval;
35
      }
36
     
37
      TCA0.SINGLE.CTRLA |= TCA_SINGLE_ENABLE_bm;                    // enable TCA module
38
      TCA0.SINGLE.INTFLAGS = TCA_SINGLE_CMP0_bm;                    // Clear interrupt flag
39
      timerOn = true;                                                              
40
       
41
  }
42
}
43

44
void stopTimer() {
45
  TCA0.SINGLE.CTRLA = 0;  // Stop timer
46
  TCA0.SINGLE.INTCTRL = 0;  // Disable interrupts
47
  timerOn = false;
48
  
49
}
50

51
// Interrupt Service Routine für den Timer
52
ISR(TCA0_CMP0_vect) {
53
  digitalWriteFast(COIL_PIN, !digitalReadFast(COIL_PIN));
54
   
55
  stopTimer();
56
    
57
}
#7680403
Lesenswert?

Autsch - Arduino: da bin ich eigentlich überfordert. Aber:

Wenn der TCA-Interrupt in stopTimer abgeschaltet wird, dann sollte er in startTimer wieder eingeschaltet werden, sonst läuft das Ganze nur einmalig.

Ähnlich verhält es sich mit dem Prescaler: auch er verschwindet mit dem ersten stopTimer.

PS: Also 'überfordert' in dem Sinne, dass ich es hier nicht so ohne weiteres laufen lassen kann.

#7680412
Lesenswert?

Ja, dass kann nicht jeder.

Yô, bis ich das auf 'normales' C umgeschrieben habe, mit meinen Assemblerkenntnissen ... ist der Antrieb schon fast erloschen.

an Matthias M.: Läge COIL_PIN nicht so ungeschickt, käme man ganz ohne start-stop-ISR aus.

Nachtrag: "Antrieb erloschen" - und wieder höre ich meinen alten Geschichtslehrer poltern: "Ihnen fehlt der intellektuelle Impetus!" (Friede seiner Asche)

#7680427
Lesenswert?

Georg M. schrieb:

1
>   takeOverTCA0();
2
>

Was ist das? Das sehe ich zum ersten Mal.

Das ist das Problem wenn man Crossposting macht. Der TO programmiert mit Arduino und verwendet den megaTinyCore von SpenceKonde. Besagte Funktion resetet alle Timer Register, die das Arduino Framework vorbelegt. https://github.com/SpenceKonde/megaTinyCore/blob/master/megaavr/extras/TakingOverTCA0.md

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