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 | }
|