00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "TimerOne.h"
00015
00016 TimerOne Timer1;
00017
00018 ISR(TIMER1_OVF_vect)
00019 {
00020 Timer1.isrCallback();
00021 }
00022
00023 void TimerOne::initialize(long microseconds)
00024 {
00025 TCCR1A = 0;
00026 TCCR1B = _BV(WGM13);
00027 setPeriod(microseconds);
00028 }
00029
00030 void TimerOne::setPeriod(long microseconds)
00031 {
00032 long cycles = (F_CPU * (long long)microseconds) / 2000000;
00033 if(cycles < RESOLUTION) clockSelectBits = _BV(CS10);
00034 else if((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11);
00035 else if((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11) | _BV(CS10);
00036 else if((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12);
00037 else if((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12) | _BV(CS10);
00038 else cycles = RESOLUTION - 1, clockSelectBits = _BV(CS12) | _BV(CS10);
00039 ICR1 = pwmPeriod = cycles;
00040 TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));
00041 TCCR1B |= clockSelectBits;
00042 }
00043
00044 void TimerOne::setPwmDuty(char pin, int duty)
00045 {
00046 unsigned long dutyCycle = pwmPeriod;
00047 dutyCycle *= duty;
00048 dutyCycle >>= 10;
00049 if(pin == 1 || pin == 9) OCR1A = dutyCycle;
00050 else if(pin == 2 || pin == 10) OCR1B = dutyCycle;
00051 }
00052
00053 void TimerOne::pwm(char pin, int duty, long microseconds)
00054 {
00055 if(microseconds > 0) setPeriod(microseconds);
00056 if(pin == 1 || pin == 9) {
00057 DDRB |= _BV(PORTB1);
00058 TCCR1A |= _BV(COM1A1);
00059 }
00060 else if(pin == 2 || pin == 10) {
00061 DDRB |= _BV(PORTB2);
00062 TCCR1A |= _BV(COM1B1);
00063 }
00064 setPwmDuty(pin, duty);
00065 start();
00066 }
00067
00068 void TimerOne::disablePwm(char pin)
00069 {
00070 if(pin == 1 || pin == 9) TCCR1A &= ~_BV(COM1A1);
00071 else if(pin == 2 || pin == 10) TCCR1A &= ~_BV(COM1B1);
00072 }
00073
00074 void TimerOne::attachInterrupt(void (*isr)(), long microseconds)
00075 {
00076 if(microseconds > 0) setPeriod(microseconds);
00077 isrCallback = isr;
00078 TIMSK1 = _BV(TOIE1);
00079 sei();
00080 start();
00081 }
00082
00083 void TimerOne::detachInterrupt()
00084 {
00085 TIMSK1 &= ~_BV(TOIE1);
00086 }
00087
00088 void TimerOne::start()
00089 {
00090 TCCR1B |= clockSelectBits;
00091 }
00092
00093 void TimerOne::stop()
00094 {
00095 TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));
00096 }
00097
00098 void TimerOne::restart()
00099 {
00100 TCNT1 = 0;
00101 }