|
mid range pics have two timers, timer0 (8 bits) and timer1 (16 bits). the difficulties in using them come from determining various values.
the examples below give you a much simpler way to set up the timers. all you need to do is to tell the program timer parameters, and how long you want the timer to last and the rest is done by the compiler.
the program basically works by calculating the number of times a timer has to trigger (MaxCnt) based the mcu frequency (Fosc), prescaler setting (TMRScaler), and timer offset (TMROffset) determined by low long you want the timer to go (TimeuS).
here is an example where we want the LED on GPIO2 to blink once every 1 seconds (Timeus=1000000us).
the hex file is 0x6c words long, :)
==========code==============
//use a counter to help adjust timing
#include <htc.h>
__CONFIG (MCLRDIS & UNPROTECT & BORDIS & WDTDIS & INTIO & PWRTEN);
//hardware configuration
#define nLED 2 //LED on gpio2
#define Fosc 4000000UL //mcu runs at 4mhz
#define TMROffset 0x1a //Offset to Timer. May need manual tweaking
#define TMRCnt (0xff-TMROffset) //timer overflows, in ticks. 8bit timer here
#define TMRScaler 2 //timer set to overflow in 32 ticks
#define TMRTicks (TMRCnt*TMRScaler) //how many times to produce a Timer interrupt
#define TMRTimeuS (4*1000000UL/Fosc*TMRTicks) //how many us elapsed between Timer interrupts
#define TimeuS 1000000UL //desired time intervals, in us
#define MaxCnt (TimeuS / TMRTimeuS) //maximum count to achieve TimeuS
#define Error (+2) //error to correct for timing. May need manual tweaking
unsigned char sGPIO; //shadow gpio
void interrupt LED(void) {
static unsigned long TMRCounter=MaxCnt; //initialize t0 counter. "static" to retain value
TMR0+=TMROffset+Error; //advance TMR by TMRCnt
TMRCounter-=1; //decrement T0Counter by 1;
if (TMRCounter==0) {
TMRCounter=MaxCnt; //reset T0Counter
sGPIO ^=(1<<nLED); //flash nLED pin
}
T0IF=0; //clear the interrupt flag
}
void
main(void)
{
TRISIO=~(1<<nLED); //all gpio pins to input other than nLED
OPTION=0b11010000; //setting up the options register;
// 1 //GPPU: pull-up disabled
// 1 //INTEDG: interrupt on rising edge
// 0 //T0CS: timer0 source select - internal clock cycle
// 1 //T0SE: timer0 edge select - interrupt on high-to-low transisiton
// 0 //PSA: prescaler selected to timer0
// 100 //PS2..0: prescaler rate select - 100=32.
//timer0 prescaler rates:
//000 = 1:2, 001 = 1:4, 010 = 1:8, 011 = 1:16
//100 = 1:32, 101 = 1:64, 110 = 1:128, 111 = 1:256
//GPPU=1; INTEDG=1;T0CS=0;T0SE=1;PSA=0;
//T1CON=0b00010001; //setting up timer1
// 0 //unused
// 0 //TMR1GE: timer1 is not gated, if TMR1ON=1
// 01 //T1CKPS1..0: timer1 prescaler set to 1/2. 00=1:1, 01=1:2, 10=1:4, 11=1:8
// 0 //T1OSCEN: timer1 LP oscilator is off
// 0 //T1SYNC: ignored since TMR1CS=0;
// 0 //TMR1CS: timer1 clock source select bit to internal oscillator
// 1 //TMR1ON: turn timer1 on
sGPIO=0; //clear gpio pins
TMR0=TMROffset+Error; //load up the timer offset
T0IE=1; //enable timer 0 interrupt
ei(); //enable global interrupt. = GIE=1;
while (1){
//TODO Auto-generated main function
GPIO=sGPIO;
}
}
(原文件名:pic timer0.PNG) |
|