Timer1_non_volatile_provozieren.ino


1
// Devil-Elec
2
// https://www.mikrocontroller.net/topic/570524?goto=7735213
3
4
#include <util/atomic.h>
5
#include <Streaming.h>  // https://github.com/janelia-arduino/Streaming
6
Stream &out {Serial};
7
8
volatile unsigned long countVolatile;
9
unsigned long countNonVolatile;
10
11
class SimpleTimer
12
{
13
  private:
14
    unsigned long lastMillis;
15
    const unsigned long intervall;
16
17
  public:
18
    SimpleTimer (unsigned long i) :
19
      lastMillis {0},
20
      intervall  {i}
21
    {}
22
    
23
    bool expired (void) {
24
      bool state {false};
25
      const unsigned long ms {millis()};
26
      if (ms - lastMillis >= intervall) {
27
        lastMillis = ms;
28
        state = true;
29
      }
30
      return state;
31
    }
32
33
    void reset (void) {
34
      lastMillis = millis();
35
    }
36
};
37
38
SimpleTimer myTimer {1000};
39
40
void setup(void)
41
{
42
  Serial.begin(250000);
43
  Serial.println(F("\nuC Reset ####"));
44
  resetTimer1();
45
  changeTimer1Mode(0);
46
  TIMSK1 = (1<<TOIE1);  // Timer Overflow Interrupt
47
  startTimer1(1);
48
}
49
50
void loop(void)
51
{
52
  if (myTimer.expired()) {
53
    readOutTimer1(out);
54
  }
55
}
56
57
void stopTimer1 (void)
58
{
59
  // delete Clock Select Bits, Timer is stopped
60
  TCCR1B &= ~( _BV(CS12) | _BV(CS11) | _BV(CS10) );
61
}
62
63
void startTimer1 (const unsigned int prescaler)
64
{
65
  // set new Prescaler Clock Select Bits
66
  switch (prescaler) {
67
    case    1 : TCCR1B |= _BV(CS10);              break;
68
    case    8 : TCCR1B |= _BV(CS11);              break;
69
    case   64 : TCCR1B |= _BV(CS11) | _BV(CS10);  break;
70
    case  256 : TCCR1B |= _BV(CS12);              break;
71
    case 1024 : TCCR1B |= _BV(CS12) | _BV(CS10);  break;
72
    default :   break;  // otherwise timer remains stopped
73
  }
74
}
75
76
void changeTimer1Mode (const uint8_t mode)
77
{
78
  if ((mode <=15) && (mode != 13)) {
79
    stopTimer1();
80
    deleteTimer1Mode();
81
    switch (mode) {
82
      case  0 :                                                                     ; break;  // Normal
83
      case  1 :                                    TCCR1A |=              _BV(WGM10); break;  // PWM, Phase Correct  8-Bit 
84
      case  2 :                                    TCCR1A |= _BV(WGM11)             ; break;  // PWM, Phase Correct  9-Bit 
85
      case  3 :                                    TCCR1A |= _BV(WGM11) | _BV(WGM10); break;  // PWM, Phase Correct 10-Bit 
86
      case  4 : TCCR1B |=              _BV(WGM12);                                  ; break;  // CTC, OCRnA
87
      case  5 : TCCR1B |=              _BV(WGM12); TCCR1A |=              _BV(WGM10); break;  // Fast PWM  8 Bit
88
      case  6 : TCCR1B |=              _BV(WGM12); TCCR1A |= _BV(WGM11)             ; break;  // Fast PWM  9 Bit
89
      case  7 : TCCR1B |=              _BV(WGM12); TCCR1A |= _BV(WGM11) | _BV(WGM10); break;  // Fast PWM 10 Bit
90
      case  8 : TCCR1B |= _BV(WGM13)             ;                                  ; break;  // PWM, Phase & Frequency Correct, ICRn
91
      case  9 : TCCR1B |= _BV(WGM13)             ; TCCR1A |=              _BV(WGM10); break;  // PWM, Phase & Frequency Correct, OCRnA
92
      case 10 : TCCR1B |= _BV(WGM13)             ; TCCR1A |= _BV(WGM11)             ; break;  // PWM, Phase Correct, ICRn
93
      case 11 : TCCR1B |= _BV(WGM13)             ; TCCR1A |= _BV(WGM11) | _BV(WGM10); break;  // PWM, Phase Correct, OCRnA
94
      case 12 : TCCR1B |= _BV(WGM13) | _BV(WGM12);                                  ; break;  // CTC, ICRn
95
      case 13 : break;                                                                        // Reserved
96
      case 14 : TCCR1B |= _BV(WGM13) | _BV(WGM12); TCCR1A |= _BV(WGM11)             ; break;  // Fast PWM, ICRn
97
      case 15 : TCCR1B |= _BV(WGM13) | _BV(WGM12); TCCR1A |= _BV(WGM11) | _BV(WGM10); break;  // Fast PWM, OCRnA                                                        
98
      default : break; // otherwise no change of the configuration
99
    }
100
  }  
101
}
102
103
void deleteTimer1Mode (void)
104
{
105
  // delete all WGM Bits
106
  TCCR1A &= ~( _BV(WGM11) | _BV(WGM10) );
107
  TCCR1B &= ~( _BV(WGM13) | _BV(WGM12) );
108
}
109
110
void resetTimer1 (void)
111
{
112
  // delete all
113
  TCCR1B = 0;
114
  TCCR1A = 0;
115
  TCCR1C = 0;
116
  TIMSK1 = 0;
117
  ICR1   = 0;
118
  OCR1A  = 0;
119
  OCR1B  = 0;
120
}
121
122
ISR(TIMER1_OVF_vect)     // Interrupt Service Routine
123
{  
124
  countVolatile++;
125
  countNonVolatile++;
126
} 
127
128
void readOutTimer1 (Stream &out)     
129
{  
130
  unsigned long countVol {0};
131
  unsigned long countNonVol {0};
132
   
133
  ATOMIC_BLOCK (ATOMIC_RESTORESTATE) {    
134
      countVol = countVolatile;
135
      countNonVol = countNonVolatile;
136
  }
137
138
  out << "volatile     " << countVol    << endl;
139
  out << "non volatile " << countNonVol << endl;
140
  out.println();
141
}