first commit

0 parents
1 TimerThree Library
2 ==================
3
4 Paul Stoffregen's modified TimerThree. This version provides 2 main benefits:
5
6 1. Optimized inline functions - much faster for the most common usage
7 2. Support for more boards
8
9 http://www.pjrc.com/teensy/td_libs_TimerOne.html
10 https://github.com/PaulStoffregen/TimerThree
11
12 Original code
13
14 http://playground.arduino.cc/Code/Timer1
15
16 Open Source License
17
18 TimerThree is free software. You can redistribute it and/or modify it under
19 the terms of Creative Commons Attribution 3.0 United States License.
20 To view a copy of this license, visit
21
22 http://creativecommons.org/licenses/by/3.0/us/
23
24 Paul Stoffregen forked this version from an early copy of TimerOne/TimerThree
25 which was licensed "Creative Commons Attribution 3.0" and has maintained
26 the original "CC BY 3.0 US" license terms.
27
28 Other, separately developed updates to TimerOne have been released by other
29 authors under the GNU GPLv2 license. Multiple copies of this library, bearing
30 the same name but distributed under different license terms, is unfortunately
31 confusing. This copy, with nearly all the code redesigned as inline functions,
32 is provided under the "CC BY 3.0 US" license terms.
1 /*
2 * Interrupt and PWM utilities for 16 bit Timer3 on ATmega168/328
3 * Original code by Jesse Tane for http://labs.ideo.com August 2008
4 * Modified March 2009 by Jérôme Despatis and Jesse Tane for ATmega328 support
5 * Modified June 2009 by Michael Polli and Jesse Tane to fix a bug in setPeriod() which caused the timer to stop
6 * Modified Oct 2009 by Dan Clemens to work with timer3 of the ATMega1280 or Arduino Mega
7 * Modified April 2012 by Paul Stoffregen
8 * Modified again, June 2014 by Paul Stoffregen
9 *
10 * This is free software. You can redistribute it and/or modify it under
11 * the terms of Creative Commons Attribution 3.0 United States License.
12 * To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/us/
13 * or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
14 *
15 */
16
17 #include "TimerThree.h"
18
19 TimerThree Timer3; // preinstatiate
20
21 unsigned short TimerThree::pwmPeriod = 0;
22 unsigned char TimerThree::clockSelectBits = 0;
23 void (*TimerThree::isrCallback)() = TimerThree::isrDefaultUnused;
24
25 // interrupt service routine that wraps a user defined function supplied by attachInterrupt
26 #if defined(__AVR__)
27 ISR(TIMER3_OVF_vect)
28 {
29 Timer3.isrCallback();
30 }
31
32 #elif defined(__arm__) && defined(CORE_TEENSY)
33 void ftm2_isr(void)
34 {
35 uint32_t sc = FTM2_SC;
36 #ifdef KINETISL
37 if (sc & 0x80) FTM2_SC = sc;
38 #else
39 if (sc & 0x80) FTM2_SC = sc & 0x7F;
40 #endif
41 Timer3.isrCallback();
42 }
43
44 #endif
45
46 void TimerThree::isrDefaultUnused()
47 {
48 }
1 /*
2 * Interrupt and PWM utilities for 16 bit Timer3 on ATmega168/328
3 * Original code by Jesse Tane for http://labs.ideo.com August 2008
4 * Modified March 2009 by Jérôme Despatis and Jesse Tane for ATmega328 support
5 * Modified June 2009 by Michael Polli and Jesse Tane to fix a bug in setPeriod() which caused the timer to stop
6 * Modified April 2012 by Paul Stoffregen - portable to other AVR chips, use inline functions
7 * Modified again, June 2014 by Paul Stoffregen - support Teensy 3.1 & even more AVR chips
8 *
9 *
10 * This is free software. You can redistribute it and/or modify it under
11 * the terms of Creative Commons Attribution 3.0 United States License.
12 * To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/us/
13 * or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
14 *
15 */
16
17 #ifndef TimerThree_h_
18 #define TimerThree_h_
19
20 #if defined(ARDUINO) && ARDUINO >= 100
21 #include "Arduino.h"
22 #else
23 #include "WProgram.h"
24 #endif
25
26 #include "config/known_16bit_timers.h"
27
28 #define TIMER3_RESOLUTION 65536UL // Timer3 is 16 bit
29
30
31 // Placing nearly all the code in this .h file allows the functions to be
32 // inlined by the compiler. In the very common case with constant values
33 // the compiler will perform all calculations and simply write constants
34 // to the hardware registers (for example, setPeriod).
35
36
37 class TimerThree
38 {
39
40
41 #if defined(__AVR__)
42 public:
43 //****************************
44 // Configuration
45 //****************************
46 void initialize(unsigned long microseconds=1000000) __attribute__((always_inline)) {
47 TCCR3B = _BV(WGM33); // set mode as phase and frequency correct pwm, stop the timer
48 TCCR3A = 0; // clear control register A
49 setPeriod(microseconds);
50 }
51 void setPeriod(unsigned long microseconds) __attribute__((always_inline)) {
52 const unsigned long cycles = (F_CPU / 2000000) * microseconds;
53 if (cycles < TIMER3_RESOLUTION) {
54 clockSelectBits = _BV(CS30);
55 pwmPeriod = cycles;
56 } else
57 if (cycles < TIMER3_RESOLUTION * 8) {
58 clockSelectBits = _BV(CS31);
59 pwmPeriod = cycles / 8;
60 } else
61 if (cycles < TIMER3_RESOLUTION * 64) {
62 clockSelectBits = _BV(CS31) | _BV(CS30);
63 pwmPeriod = cycles / 64;
64 } else
65 if (cycles < TIMER3_RESOLUTION * 256) {
66 clockSelectBits = _BV(CS32);
67 pwmPeriod = cycles / 256;
68 } else
69 if (cycles < TIMER3_RESOLUTION * 1024) {
70 clockSelectBits = _BV(CS32) | _BV(CS30);
71 pwmPeriod = cycles / 1024;
72 } else {
73 clockSelectBits = _BV(CS32) | _BV(CS30);
74 pwmPeriod = TIMER3_RESOLUTION - 1;
75 }
76 ICR3 = pwmPeriod;
77 TCCR3B = _BV(WGM33) | clockSelectBits;
78 }
79
80 //****************************
81 // Run Control
82 //****************************
83 void start() __attribute__((always_inline)) {
84 TCCR3B = 0;
85 TCNT3 = 0; // TODO: does this cause an undesired interrupt?
86 resume();
87 }
88 void stop() __attribute__((always_inline)) {
89 TCCR3B = _BV(WGM33);
90 }
91 void restart() __attribute__((always_inline)) {
92 start();
93 }
94 void resume() __attribute__((always_inline)) {
95 TCCR3B = _BV(WGM33) | clockSelectBits;
96 }
97
98 //****************************
99 // PWM outputs
100 //****************************
101 void setPwmDuty(char pin, unsigned int duty) __attribute__((always_inline)) {
102 unsigned long dutyCycle = pwmPeriod;
103 dutyCycle *= duty;
104 dutyCycle >>= 10;
105 if (pin == TIMER3_A_PIN) OCR3A = dutyCycle;
106 #ifdef TIMER3_B_PIN
107 else if (pin == TIMER3_B_PIN) OCR3B = dutyCycle;
108 #endif
109 #ifdef TIMER3_C_PIN
110 else if (pin == TIMER3_C_PIN) OCR3C = dutyCycle;
111 #endif
112 }
113 void pwm(char pin, unsigned int duty) __attribute__((always_inline)) {
114 if (pin == TIMER3_A_PIN) { pinMode(TIMER3_A_PIN, OUTPUT); TCCR3A |= _BV(COM3A1); }
115 #ifdef TIMER3_B_PIN
116 else if (pin == TIMER3_B_PIN) { pinMode(TIMER3_B_PIN, OUTPUT); TCCR3A |= _BV(COM3B1); }
117 #endif
118 #ifdef TIMER3_C_PIN
119 else if (pin == TIMER3_C_PIN) { pinMode(TIMER3_C_PIN, OUTPUT); TCCR3A |= _BV(COM3C1); }
120 #endif
121 setPwmDuty(pin, duty);
122 TCCR3B = _BV(WGM33) | clockSelectBits;
123 }
124 void pwm(char pin, unsigned int duty, unsigned long microseconds) __attribute__((always_inline)) {
125 if (microseconds > 0) setPeriod(microseconds);
126 pwm(pin, duty);
127 }
128 void disablePwm(char pin) __attribute__((always_inline)) {
129 if (pin == TIMER3_A_PIN) TCCR3A &= ~_BV(COM3A1);
130 #ifdef TIMER3_B_PIN
131 else if (pin == TIMER3_B_PIN) TCCR3A &= ~_BV(COM3B1);
132 #endif
133 #ifdef TIMER3_C_PIN
134 else if (pin == TIMER3_C_PIN) TCCR3A &= ~_BV(COM3C1);
135 #endif
136 }
137
138 //****************************
139 // Interrupt Function
140 //****************************
141 void attachInterrupt(void (*isr)()) __attribute__((always_inline)) {
142 isrCallback = isr;
143 TIMSK3 = _BV(TOIE3);
144 }
145 void attachInterrupt(void (*isr)(), unsigned long microseconds) __attribute__((always_inline)) {
146 if(microseconds > 0) setPeriod(microseconds);
147 attachInterrupt(isr);
148 }
149 void detachInterrupt() __attribute__((always_inline)) {
150 TIMSK3 = 0;
151 }
152 static void (*isrCallback)();
153 static void isrDefaultUnused();
154
155 private:
156 // properties
157 static unsigned short pwmPeriod;
158 static unsigned char clockSelectBits;
159
160
161
162 #elif defined(__arm__) && defined(CORE_TEENSY)
163
164 #if defined(KINETISK)
165 #define F_TIMER F_BUS
166 #elif defined(KINETISL)
167 #define F_TIMER (F_PLL/2)
168 #endif
169
170 public:
171 //****************************
172 // Configuration
173 //****************************
174 void initialize(unsigned long microseconds=1000000) __attribute__((always_inline)) {
175 setPeriod(microseconds);
176 }
177 void setPeriod(unsigned long microseconds) __attribute__((always_inline)) {
178 const unsigned long cycles = (F_TIMER / 2000000) * microseconds;
179
180 /*
181 // This code does not work properly in all cases :(
182 // https://github.com/PaulStoffregen/TimerOne/issues/17
183 if (cycles < TIMER3_RESOLUTION * 16) {
184 if (cycles < TIMER3_RESOLUTION * 4) {
185 if (cycles < TIMER3_RESOLUTION) {
186 clockSelectBits = 0;
187 pwmPeriod = cycles;
188 }else{
189 clockSelectBits = 1;
190 pwmPeriod = cycles >> 1;
191 }
192 }else{
193 if (cycles < TIMER3_RESOLUTION * 8) {
194 clockSelectBits = 3;
195 pwmPeriod = cycles >> 3;
196 }else{
197 clockSelectBits = 4;
198 pwmPeriod = cycles >> 4;
199 }
200 }
201 }else{
202 if (cycles > TIMER3_RESOLUTION * 64) {
203 if (cycles > TIMER3_RESOLUTION * 128) {
204 clockSelectBits = 7;
205 pwmPeriod = TIMER3_RESOLUTION - 1;
206 }else{
207 clockSelectBits = 7;
208 pwmPeriod = cycles >> 7;
209 }
210 }else{
211 if (cycles > TIMER3_RESOLUTION * 32) {
212 clockSelectBits = 6;
213 pwmPeriod = cycles >> 6;
214 }else{
215 clockSelectBits = 5;
216 pwmPeriod = cycles >> 5;
217 }
218 }
219 }
220 */
221 if (cycles < TIMER3_RESOLUTION) {
222 clockSelectBits = 0;
223 pwmPeriod = cycles;
224 } else
225 if (cycles < TIMER3_RESOLUTION * 2) {
226 clockSelectBits = 1;
227 pwmPeriod = cycles >> 1;
228 } else
229 if (cycles < TIMER3_RESOLUTION * 4) {
230 clockSelectBits = 2;
231 pwmPeriod = cycles >> 2;
232 } else
233 if (cycles < TIMER3_RESOLUTION * 8) {
234 clockSelectBits = 3;
235 pwmPeriod = cycles >> 3;
236 } else
237 if (cycles < TIMER3_RESOLUTION * 16) {
238 clockSelectBits = 4;
239 pwmPeriod = cycles >> 4;
240 } else
241 if (cycles < TIMER3_RESOLUTION * 32) {
242 clockSelectBits = 5;
243 pwmPeriod = cycles >> 5;
244 } else
245 if (cycles < TIMER3_RESOLUTION * 64) {
246 clockSelectBits = 6;
247 pwmPeriod = cycles >> 6;
248 } else
249 if (cycles < TIMER3_RESOLUTION * 128) {
250 clockSelectBits = 7;
251 pwmPeriod = cycles >> 7;
252 } else {
253 clockSelectBits = 7;
254 pwmPeriod = TIMER3_RESOLUTION - 1;
255 }
256
257 uint32_t sc = FTM2_SC;
258 FTM2_SC = 0;
259 FTM2_MOD = pwmPeriod;
260 FTM2_SC = FTM_SC_CLKS(1) | FTM_SC_CPWMS | clockSelectBits | (sc & FTM_SC_TOIE);
261 }
262
263 //****************************
264 // Run Control
265 //****************************
266 void start() __attribute__((always_inline)) {
267 stop();
268 FTM2_CNT = 0;
269 resume();
270 }
271 void stop() __attribute__((always_inline)) {
272 FTM2_SC = FTM2_SC & (FTM_SC_TOIE | FTM_SC_CPWMS | FTM_SC_PS(7));
273 }
274 void restart() __attribute__((always_inline)) {
275 start();
276 }
277 void resume() __attribute__((always_inline)) {
278 FTM2_SC = (FTM2_SC & (FTM_SC_TOIE | FTM_SC_PS(7))) | FTM_SC_CPWMS | FTM_SC_CLKS(1);
279 }
280
281 //****************************
282 // PWM outputs
283 //****************************
284 void setPwmDuty(char pin, unsigned int duty) __attribute__((always_inline)) {
285 unsigned long dutyCycle = pwmPeriod;
286 dutyCycle *= duty;
287 dutyCycle >>= 10;
288 if (pin == TIMER3_A_PIN) {
289 FTM2_C0V = dutyCycle;
290 } else if (pin == TIMER3_B_PIN) {
291 FTM2_C1V = dutyCycle;
292 }
293 }
294 void pwm(char pin, unsigned int duty) __attribute__((always_inline)) {
295 setPwmDuty(pin, duty);
296 if (pin == TIMER3_A_PIN) {
297 *portConfigRegister(TIMER3_A_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
298 } else if (pin == TIMER3_B_PIN) {
299 *portConfigRegister(TIMER3_B_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
300 }
301 }
302 void pwm(char pin, unsigned int duty, unsigned long microseconds) __attribute__((always_inline)) {
303 if (microseconds > 0) setPeriod(microseconds);
304 pwm(pin, duty);
305 }
306 void disablePwm(char pin) __attribute__((always_inline)) {
307 if (pin == TIMER3_A_PIN) {
308 *portConfigRegister(TIMER3_A_PIN) = 0;
309 } else if (pin == TIMER3_B_PIN) {
310 *portConfigRegister(TIMER3_B_PIN) = 0;
311 }
312 }
313
314 //****************************
315 // Interrupt Function
316 //****************************
317 void attachInterrupt(void (*isr)()) __attribute__((always_inline)) {
318 isrCallback = isr;
319 FTM2_SC |= FTM_SC_TOIE;
320 NVIC_ENABLE_IRQ(IRQ_FTM2);
321 }
322 void attachInterrupt(void (*isr)(), unsigned long microseconds) __attribute__((always_inline)) {
323 if(microseconds > 0) setPeriod(microseconds);
324 attachInterrupt(isr);
325 }
326 void detachInterrupt() __attribute__((always_inline)) {
327 FTM2_SC &= ~FTM_SC_TOIE;
328 NVIC_DISABLE_IRQ(IRQ_FTM2);
329 }
330 static void (*isrCallback)();
331 static void isrDefaultUnused();
332
333 private:
334 // properties
335 static unsigned short pwmPeriod;
336 static unsigned char clockSelectBits;
337
338 #undef F_TIMER
339
340 #endif
341 };
342
343 extern TimerThree Timer3;
344
345 #endif
346
1 #ifndef known_16bit_timers_header_
2 #define known_16bit_timers_header_
3
4 // Wiring-S
5 //
6 #if defined(__AVR_ATmega644P__) && defined(WIRING)
7 #define TIMER1_A_PIN 5
8 #define TIMER1_B_PIN 4
9 #define TIMER1_ICP_PIN 6
10
11 // Teensy 2.0
12 //
13 #elif defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY)
14 #define TIMER1_A_PIN 14
15 #define TIMER1_B_PIN 15
16 #define TIMER1_C_PIN 4
17 #define TIMER1_ICP_PIN 22
18 #define TIMER1_CLK_PIN 11
19 #define TIMER3_A_PIN 9
20 #define TIMER3_ICP_PIN 10
21
22 // Teensy++ 2.0
23 #elif defined(__AVR_AT90USB1286__) && defined(CORE_TEENSY)
24 #define TIMER1_A_PIN 25
25 #define TIMER1_B_PIN 26
26 #define TIMER1_C_PIN 27
27 #define TIMER1_ICP_PIN 4
28 #define TIMER1_CLK_PIN 6
29 #define TIMER3_A_PIN 16
30 #define TIMER3_B_PIN 15
31 #define TIMER3_C_PIN 14
32 #define TIMER3_ICP_PIN 17
33 #define TIMER3_CLK_PIN 13
34
35 // Teensy 3.0
36 //
37 #elif defined(__MK20DX128__)
38 #define TIMER1_A_PIN 3
39 #define TIMER1_B_PIN 4
40 #define TIMER1_ICP_PIN 4
41
42 // Teensy 3.1 / Teensy 3.2
43 //
44 #elif defined(__MK20DX256__)
45 #define TIMER1_A_PIN 3
46 #define TIMER1_B_PIN 4
47 #define TIMER1_ICP_PIN 4
48 #define TIMER3_A_PIN 32
49 #define TIMER3_B_PIN 25
50 #define TIMER3_ICP_PIN 32
51
52 // Teensy 3.5 / Teensy 3.6
53 //
54 #elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
55 #define TIMER1_A_PIN 3
56 #define TIMER1_B_PIN 4
57 #define TIMER1_ICP_PIN 4
58 #define TIMER3_A_PIN 29
59 #define TIMER3_B_PIN 30
60 #define TIMER3_ICP_PIN 29
61
62 // Teensy-LC
63 //
64 #elif defined(__MKL26Z64__)
65 #define TIMER1_A_PIN 16
66 #define TIMER1_B_PIN 17
67 #define TIMER1_ICP_PIN 17
68 #define TIMER3_A_PIN 3
69 #define TIMER3_B_PIN 4
70 #define TIMER3_ICP_PIN 4
71
72 // Arduino Mega
73 //
74 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
75 #define TIMER1_A_PIN 11
76 #define TIMER1_B_PIN 12
77 #define TIMER1_C_PIN 13
78 #define TIMER3_A_PIN 5
79 #define TIMER3_B_PIN 2
80 #define TIMER3_C_PIN 3
81 #define TIMER4_A_PIN 6
82 #define TIMER4_B_PIN 7
83 #define TIMER4_C_PIN 8
84 #define TIMER4_ICP_PIN 49
85 #define TIMER5_A_PIN 46
86 #define TIMER5_B_PIN 45
87 #define TIMER5_C_PIN 44
88 #define TIMER3_ICP_PIN 48
89 #define TIMER3_CLK_PIN 47
90
91 // Arduino Leonardo, Yun, etc
92 //
93 #elif defined(__AVR_ATmega32U4__)
94 #define TIMER1_A_PIN 9
95 #define TIMER1_B_PIN 10
96 #define TIMER1_C_PIN 11
97 #define TIMER1_ICP_PIN 4
98 #define TIMER1_CLK_PIN 12
99 #define TIMER3_A_PIN 5
100 #define TIMER3_ICP_PIN 13
101
102 // Uno, Duemilanove, LilyPad, etc
103 //
104 #elif defined (__AVR_ATmega168__) || defined (__AVR_ATmega328P__)
105 #define TIMER1_A_PIN 9
106 #define TIMER1_B_PIN 10
107 #define TIMER1_ICP_PIN 8
108 #define TIMER1_CLK_PIN 5
109
110 // Sanguino
111 //
112 #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
113 #define TIMER1_A_PIN 13
114 #define TIMER1_B_PIN 12
115 #define TIMER1_ICP_PIN 14
116 #define TIMER1_CLK_PIN 1
117
118 // Wildfire - Wicked Devices
119 //
120 #elif defined(__AVR_ATmega1284P__) && defined(WILDFIRE_VERSION) && WILDFIRE_VERSION >= 3
121 #define TIMER1_A_PIN 5 // PD5
122 #define TIMER1_B_PIN 8 // PD4
123 #define TIMER1_ICP_PIN 6 // PD6
124 #define TIMER1_CLK_PIN 23 // PB1
125 #define TIMER3_A_PIN 12 // PB6
126 #define TIMER3_B_PIN 13 // PB7
127 #define TIMER3_ICP_PIN 9 // PB5
128 #define TIMER3_CLK_PIN 0 // PD0
129 #elif defined(__AVR_ATmega1284P__) && defined(WILDFIRE_VERSION) && WILDFIRE_VERSION < 3
130 #define TIMER1_A_PIN 5 // PD5
131 #define TIMER1_B_PIN 4 // PD4
132 #define TIMER1_ICP_PIN 6 // PD6
133 #define TIMER1_CLK_PIN 15 // PB1
134 #define TIMER3_A_PIN 12 // PB6
135 #define TIMER3_B_PIN 13 // PB7
136 #define TIMER3_ICP_PIN 11 // PB5
137 #define TIMER3_CLK_PIN 0 // PD0
138
139 // Mighty-1284 - Maniacbug
140 //
141 #elif defined(__AVR_ATmega1284P__)
142 #define TIMER1_A_PIN 12 // PD5
143 #define TIMER1_B_PIN 13 // PD4
144 #define TIMER1_ICP_PIN 14 // PD6
145 #define TIMER1_CLK_PIN 1 // PB1
146 #define TIMER3_A_PIN 6 // PB6
147 #define TIMER3_B_PIN 7 // PB7
148 #define TIMER3_ICP_PIN 5 // PB5
149 #define TIMER3_CLK_PIN 8 // PD0
150
151 #endif
152
153 #endif
1 #include <TimerThree.h>
2
3 // This example creates a PWM signal with 25 kHz carrier.
4 //
5 // Arduino's analogWrite() gives you PWM output, but no control over the
6 // carrier frequency. The default frequency is low, typically 490 or
7 // 3920 Hz. Sometimes you may need a faster carrier frequency.
8 //
9 // The specification for 4-wire PWM fans recommends a 25 kHz frequency
10 // and allows 21 to 28 kHz. The default from analogWrite() might work
11 // with some fans, but to follow the specification we need 25 kHz.
12 //
13 // http://www.formfactors.org/developer/specs/REV1_2_Public.pdf
14 //
15 // Connect the PWM pin to the fan's control wire (usually blue). The
16 // board's ground must be connected to the fan's ground, and the fan
17 // needs +12 volt power from the computer or a separate power supply.
18
19 const int fanPin = 14;
20
21 void setup(void)
22 {
23 Timer3.initialize(40); // 40 us = 25 kHz
24 Serial.begin(9600);
25 }
26
27 void loop(void)
28 {
29 // slowly increase the PWM fan speed
30 //
31 for (float dutyCycle = 30.0; dutyCycle < 100.0; dutyCycle++) {
32 Serial.print("PWM Fan, Duty Cycle = ");
33 Serial.println(dutyCycle);
34 Timer3.pwm(fanPin, (dutyCycle / 100) * 1023);
35 delay(500);
36 }
37 }
1 #include <TimerThree.h>
2
3 // This example uses the timer interrupt to blink an LED
4 // and also demonstrates how to share a variable between
5 // the interrupt and the main program.
6
7
8 const int led = LED_BUILTIN; // the pin with a LED
9
10 void setup(void)
11 {
12 pinMode(led, OUTPUT);
13 Timer3.initialize(150000);
14 Timer3.attachInterrupt(blinkLED); // blinkLED to run every 0.15 seconds
15 Serial.begin(9600);
16 }
17
18
19 // The interrupt will blink the LED, and keep
20 // track of how many times it has blinked.
21 int ledState = LOW;
22 volatile unsigned long blinkCount = 0; // use volatile for shared variables
23
24 void blinkLED(void)
25 {
26 if (ledState == LOW) {
27 ledState = HIGH;
28 blinkCount = blinkCount + 1; // increase when LED turns on
29 } else {
30 ledState = LOW;
31 }
32 digitalWrite(led, ledState);
33 }
34
35
36 // The main program will print the blink count
37 // to the Arduino Serial Monitor
38 void loop(void)
39 {
40 unsigned long blinkCopy; // holds a copy of the blinkCount
41
42 // to read a variable which the interrupt code writes, we
43 // must temporarily disable interrupts, to be sure it will
44 // not change while we are reading. To minimize the time
45 // with interrupts off, just quickly make a copy, and then
46 // use the copy while allowing the interrupt to keep working.
47 noInterrupts();
48 blinkCopy = blinkCount;
49 interrupts();
50
51 Serial.print("blinkCount = ");
52 Serial.println(blinkCopy);
53 delay(100);
54 }
1 Timer3 KEYWORD2
2 TimerThree KEYWORD1
3 initialize KEYWORD2
4 start KEYWORD2
5 stop KEYWORD2
6 restart KEYWORD2
7 resume KEYWORD2
8 pwm KEYWORD2
9 disablePwm KEYWORD2
10 attachInterrupt KEYWORD2
11 detachInterrupt KEYWORD2
12 setPeriod KEYWORD2
13 setPwmDuty KEYWORD2
14 isrCallback KEYWORD2
1 {
2 "name": "TimerThree",
3 "version": "1.1",
4 "keywords": "timer",
5 "description": "Allow to use the built-in 16 bit Timer3",
6 "repository":
7 {
8 "type": "git",
9 "url": "https://github.com/PaulStoffregen/TimerThree.git"
10 },
11 "frameworks": "arduino",
12 "platforms":
13 [
14 "atmelavr",
15 "teensy"
16 ]
17 }
1 name=TimerThree
2 version=1.1
3 author=Jesse Tane, Jérôme Despatis, Michael Polli, Dan Clemens, Paul Stoffregen
4 maintainer=Paul Stoffregen
5 sentence=Use hardware Timer3 for finer PWM control and/or running an periodic interrupt function
6 paragraph=
7 category=Timing
8 url=http://playground.arduino.cc/Code/Timer1
9 architectures=avr
10
1 ライブラリのインストールについては次を参照してください:http://www.arduino.cc/en/Guide/Libraries
1 #include <TimerThree.h>
2 #include <stdio.h>
3
4 //int TRIGGER_INTERVAL_MS = 34000;
5 struct Event_State {
6 int state ;
7 } _state;
8
9 void setup() {
10 // put your setup code here, to run once:
11 Serial.begin(9600);
12 Timer3.initialize(3000000);
13 Timer3.attachInterrupt(trigger);
14 }
15 void output(int skid,int data_renge,int type , char* datas,int crc){
16 int i = 0;
17 char buffer [50];
18 // this is fake datas .
19 i=sprintf (buffer, "000%d000%x0%d%s0%x", skid,data_renge,type,datas,crc);
20 for(int l= 0; l<=i; l++)
21 Serial.print(buffer[l]);
22
23 Serial.println();
24 }
25
26 void str_release(char* str){
27 int str_len = strlen( str );
28 memset( str , '\0' , str_len );
29 }
30
31 void trigger(){
32
33 _state.state = (_state.state+1) % 3 ;
34
35 if(_state.state == 0){
36 char data[5] = "0100";
37
38 output(1,8,3,data,16);
39 output(2,8,3,data,16);
40 output(3,8,3,data,16);
41 output(4,8,3,data,16);
42 output(5,8,3,data,16);
43 output(6,8,3,data,16);
44 output(7,8,3,data,16);
45
46 str_release(data);
47 }
48
49 if(_state.state == 1){
50 char data_2[5] = "0080";
51 char data_3[5] = "0060";
52 char data_4[5] = "0120";
53
54 output(2,8,3,data_2,16);
55 output(3,8,3,data_3,16);
56 output(4,8,3,data_4,16);
57
58 str_release(data_2);
59 str_release(data_3);
60 str_release(data_4);
61 }
62
63 if(_state.state == 2){
64 char data_5[5] = "0090";
65 char data_6[5] = "0100";
66 char data_7[5] = "0080";
67
68 output(5,8,3,data_5,16);
69 output(6,8,3,data_6,16);
70 output(7,8,3,data_7,16);
71
72 str_release(data_5);
73 str_release(data_6);
74 str_release(data_7);
75 }
76
77 _state.state++;
78 }
79
80 void loop() {
81 // put your main code here, to run repeatedly:
82
83
84 if(Serial.available()){}
85
86 }