Main Page   Compound List   File List   Compound Members   File Members  

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 }

Generated at Mon Oct 14 00:10:51 2002 for avrlib by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001