📄 timer.c
字号:
timer.c
Go to the documentation of this file.00001
00002 //*****************************************************************************
00003 //
00004 // File Name : 'timer.c'
00005 // Title : System Timer function library
00006 // Author : Pascal Stang - Copyright (C) 2000-2002
00007 // Created : 11/22/2000
00008 // Revised : 5/6/2002
00009 // Version : 1.1
00010 // Target MCU : Atmel AVR Series
00011 // Editor Tabs : 3
00012 //
00013 // This code is distributed under the GNU Public License
00014 // which can be found at http://www.gnu.org/licenses/gpl.txt
00015 //
00016 //*****************************************************************************
00017
00018 #ifndef WIN32
00019 #include <io.h>
00020 #include <sig-avr.h>
00021 #include <interrupt.h>
00022 #include <progmem.h>
00023 #endif
00024
00025 #include "global.h"
00026 #include "timer.h"
00027
00028 // Program ROM constants
00029 // the prescale division values stored in 2^n format
00030 // STOP, CLK, CLK/8, CLK/64, CLK/256, CLK/1024
00031 short __attribute__ ((progmem)) TimerPrescaleFactor[] = {0,0,3,6,8,10};
00032
00033 // Global variables
00034 // time registers
00035 volatile unsigned long Timer0PauseReg;
00036 volatile unsigned long Timer0Reg0;
00037 volatile unsigned long Timer0Reg1;
00038 volatile unsigned long Timer2Reg0;
00039 volatile unsigned long Timer2Reg1;
00040
00041 typedef void (*voidFuncPtr)(void);
00042 volatile static voidFuncPtr TimerIntFunc[TIMER_NUM_INTERRUPTS];
00043
00044 // delay for a minimum of <us> microseconds
00045 // the time resolution is dependent on the time the loop takes
00046 // e.g. with 4Mhz and 5 cycles per loop, the resolution is 1.25 us
00047 void delay(unsigned short us)
00048 {
00049 unsigned short delay_loops;
00050 register unsigned short i;
00051
00052 delay_loops = (us+3)/5*CYCLES_PER_US; // +3 for rounding up (dirty)
00053
00054 // one loop takes 5 cpu cycles
00055 for (i=0; i < delay_loops; i++) {};
00056 }
00057
00058 void timerInit(void)
00059 {
00060 u08 intNum;
00061 // detach all user functions from interrupts
00062 for(intNum=0; intNum<TIMER_NUM_INTERRUPTS; intNum++)
00063 timerDetach(intNum);
00064
00065 // initialize all timers
00066 timer0Init();
00067 timer1Init();
00068 timer2Init();
00069 // enable interrupts
00070 sei();
00071 }
00072
00073 void timer0Init()
00074 {
00075 // initialize timer 0
00076 timer0SetPrescaler( TIMER0PRESCALE ); // set prescaler
00077 outp(0, TCNT0); // reset TCNT0
00078 sbi(TIMSK, TOIE0); // enable TCNT0 overflow interrupt
00079
00080 Timer0Reg0 = 0; // initialize time registers
00081 Timer0Reg1 = 0; // initialize time registers
00082 }
00083
00084 void timer1Init(void)
00085 {
00086 // initialize timer 1
00087 timer1SetPrescaler( TIMER1PRESCALE ); // set prescaler
00088 outp(0, TCNT1H); // reset TCNT1
00089 outp(0, TCNT1L);
00090 sbi(TIMSK, TOIE1); // enable TCNT1 overflow
00091 }
00092
00093 void timer2Init(void)
00094 {
00095 // initialize timer 2
00096 timer2SetPrescaler( TIMER2PRESCALE ); // set prescaler
00097 outp(0, TCNT2); // reset TCNT2
00098 sbi(TIMSK, TOIE2); // enable TCNT2 overflow
00099
00100 Timer2Reg0 = 0; // initialize time registers
00101 Timer2Reg1 = 0; // initialize time registers
00102 }
00103
00104 void timer0SetPrescaler(u08 prescale)
00105 {
00106 // set prescaler on timer 0
00107 outp( (inp(TCCR0) & ~TIMER_PRESCALE_MASK) | prescale, TCCR0);
00108 }
00109
00110 void timer1SetPrescaler(u08 prescale)
00111 {
00112 // set prescaler on timer 1
00113 outp( (inp(TCCR1B) & ~TIMER_PRESCALE_MASK) | prescale, TCCR1B);
00114 }
00115
00116 void timer2SetPrescaler(u08 prescale)
00117 {
00118 // set prescaler on timer 2
00119 outp( (inp(TCCR2) & ~TIMER_PRESCALE_MASK) | prescale, TCCR2);
00120 }
00121
00122 void timerAttach(u08 interruptNum, void (*userFunc)(void) )
00123 {
00124 // make sure the interrupt number is within bounds
00125 if(interruptNum < TIMER_NUM_INTERRUPTS)
00126 {
00127 // set the interrupt function to run
00128 // the supplied user's function
00129 TimerIntFunc[interruptNum] = userFunc;
00130 }
00131 }
00132
00133 void timerDetach(u08 interruptNum)
00134 {
00135 // make sure the interrupt number is within bounds
00136 if(interruptNum < TIMER_NUM_INTERRUPTS)
00137 {
00138 // set the interrupt function to run nothing
00139 TimerIntFunc[interruptNum] = 0;
00140 }
00141 }
00142
00143 void timerPause(unsigned short pause_ms)
00144 {
00145 // pauses for exactly <pause_ms> number of milliseconds
00146
00147 // calculate delay for [pause_ms] milliseconds
00148 u16 prescaleDiv = 1<<(PRG_RDB(TimerPrescaleFactor+inp(TCCR0)));
00149 u32 pause = (pause_ms*(F_CPU/(prescaleDiv*256)))/1000;
00150
00151 Timer0PauseReg = 0;
00152 while(Timer0PauseReg < pause);
00153 }
00154
00155 void timer0ClearOverflowCount(void)
00156 {
00157 // clear the timer overflow counter registers
00158 Timer0Reg0 = 0; // initialize time registers
00159 Timer0Reg1 = 0; // initialize time registers
00160 }
00161
00162 long timer0GetOverflowCount(void)
00163 {
00164 // return the current timer overflow count
00165 // (this is since the last timer0ClearOverflowCount() command was called)
00166 return Timer0Reg0;
00167 }
00168
00169 void timer2ClearOverflowCount(void)
00170 {
00171 // clear the timer overflow counter registers
00172 Timer2Reg0 = 0; // initialize time registers
00173 Timer2Reg1 = 0; // initialize time registers
00174 }
00175
00176 long timer2GetOverflowCount(void)
00177 {
00178 // return the current timer overflow count
00179 // (this is since the last timer2ClearOverflowCount() command was called)
00180 return Timer2Reg0;
00181 }
00182
00183
00184 void timer1PWMInit(u08 bitRes)
00185 {
00186 // configures timer1 for use with PWM output
00187 // on pins OC1A and OC1B
00188
00189 // enable Timer1 as 8,9,10bit PWM
00190 if(bitRes == 9)
00191 { // 9bit mode
00192 sbi(TCCR1A,PWM11);
00193 cbi(TCCR1A,PWM10);
00194 }
00195 else if( bitRes == 10 )
00196 { // 10bit mode
00197 sbi(TCCR1A,PWM11);
00198 sbi(TCCR1A,PWM10);
00199 }
00200 else
00201 { // default 8bit mode
00202 cbi(TCCR1A,PWM11);
00203 sbi(TCCR1A,PWM10);
00204 }
00205
00206 // set clear-timer-on-compare-match
00207 sbi(TCCR1B,CTC1);
00208 // set PWM1A as non-inverted PWM
00209 sbi(TCCR1A,COM1A1);
00210 cbi(TCCR1A,COM1A0);
00211 // set PWM1B as non-inverted PWM
00212 sbi(TCCR1A,COM1B1);
00213 cbi(TCCR1A,COM1B0);
00214 // clear output compare value A
00215 outp(0, OCR1AH);
00216 outp(0, OCR1AL);
00217 // clear output compare value B
00218 outp(0, OCR1BH);
00219 outp(0, OCR1BL);
00220 }
00221
00222 void timer1PWMOff(void)
00223 {
00224 // turn off PWM on OC1A and OC1B
00225 cbi(TCCR1A,PWM11);
00226 cbi(TCCR1A,PWM10);
00227 // clear (disable) clear-timer-on-compare-match
00228 cbi(TCCR1B,CTC1);
00229 // set PWM1A (OutputCompare action) to none
00230 cbi(TCCR1A,COM1A1);
00231 cbi(TCCR1A,COM1A0);
00232 // set PWM1B (OutputCompare action) to none
00233 cbi(TCCR1A,COM1B1);
00234 cbi(TCCR1A,COM1B0);
00235 }
00236
00237 void timer1PWMASet(u16 pwmDuty)
00238 {
00239 // set PWM (output compare) duty for channel A
00240 // this PWM output is generated on OC1A pin
00241 // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM
00242 // pwmDuty should be in the range 0-511 for 9bit PWM
00243 // pwmDuty should be in the range 0-1023 for 10bit PWM
00244 outp( (pwmDuty>>8), OCR1AH); // set the high 8bits of OCR1A
00245 outp( (pwmDuty&0x00FF), OCR1AL); // set the low 8bits of OCR1A
00246 }
00247
00248 void timer1PWMBSet(u16 pwmDuty)
00249 {
00250 // set PWM (output compare) duty for channel B
00251 // this PWM output is generated on OC1B pin
00252 // NOTE: pwmDuty should be in the range 0-255 for 8bit PWM
00253 // pwmDuty should be in the range 0-511 for 9bit PWM
00254 // pwmDuty should be in the range 0-1023 for 10bit PWM
00255 outp( (pwmDuty>>8), OCR1BH); // set the high 8bits of OCR1B
00256 outp( (pwmDuty&0x00FF), OCR1BL); // set the low 8bits of OCR1B
00257 }
00258
00259 // interrupt handler for tcnt0 overflow interrupt
00260 SIGNAL(SIG_OVERFLOW0)
00261 {
00262 Timer0Reg0++; // increment low-order counter
00263 if(!Timer0Reg0) // if low-order counter rollover
00264 Timer0Reg1++; // increment high-order counter
00265
00266 // increment pause counter
00267 Timer0PauseReg++;
00268
00269 // if a user function is defined, execute it too
00270 if(TimerIntFunc[TIMER0OVERFLOW_INT])
00271 TimerIntFunc[TIMER0OVERFLOW_INT]();
00272 }
00273
00274 // interrupt handler for tcnt1 overflow interrupt
00275 SIGNAL(SIG_OVERFLOW1)
00276 {
00277 // if a user function is defined, execute it
00278 if(TimerIntFunc[TIMER1OVERFLOW_INT])
00279 TimerIntFunc[TIMER1OVERFLOW_INT]();
00280 }
00281
00282 // interrupt handler for tcnt2 overflow interrupt
00283 SIGNAL(SIG_OVERFLOW2)
00284 {
00285 Timer2Reg0++; // increment low-order counter
00286 if(!Timer2Reg0) // if low-order counter rollover
00287 Timer2Reg1++; // increment high-order counter
00288
00289 // if a user function is defined, execute it
00290 if(TimerIntFunc[TIMER2OVERFLOW_INT])
00291 TimerIntFunc[TIMER2OVERFLOW_INT]();
00292 }
00293
00294 // interrupt handler for CutputCompare1A match (OC1A) interrupt
00295 SIGNAL(SIG_OUTPUT_COMPARE1A)
00296 {
00297 // if a user function is defined, execute it
00298 if(TimerIntFunc[TIMER1OUTCOMPAREA_INT])
00299 TimerIntFunc[TIMER1OUTCOMPAREA_INT]();
00300 }
00301
00302 // interrupt handler for OutputCompare1B match (OC1B) interrupt
00303 SIGNAL(SIG_OUTPUT_COMPARE1B)
00304 {
00305 // if a user function is defined, execute it
00306 if(TimerIntFunc[TIMER1OUTCOMPAREB_INT])
00307 TimerIntFunc[TIMER1OUTCOMPAREB_INT]();
00308 }
00309
00310 SIGNAL(SIG_INPUT_CAPTURE1)
00311 {
00312 // if a user function is defined, execute it
00313 if(TimerIntFunc[TIMER1INPUTCAPTURE_INT])
00314 TimerIntFunc[TIMER1INPUTCAPTURE_INT]();
00315 }
00316
00317
00318 // added by MG
00319
00320 // interrupt handler for OutputCompare2 match (OC2) interrupt
00321 SIGNAL(SIG_OUTPUT_COMPARE2)
00322 {
00323
00324 // if a user function is defined, execute it
00325 if(TimerIntFunc[TIMER2OUTCOMPARE_INT])
00326 TimerIntFunc[TIMER2OUTCOMPARE_INT]();
00327 }
00328
00329
00330
00331 void timer2SetRTCMode(void)
00332 {
00333 sbi(ASSR,AS2);
00334 }
00335
00336 void timer2EnableOutputCompare(void)
00337 {
00338 sbi(TIMSK, OCIE2);
00339 }
00340
00341 void timer2SetOutCompare(u08 compare) /* Set Output Compare value */
00342 {
00343 outp(compare,OCR2);
00344 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -