asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
Efficient timer based delays for 18F save code space |
Posted: Sun Feb 28, 2016 11:51 am |
|
|
various ranges and granularities in timing with one 18F counter
This lets you replace delay_ms(), delay_us();
and saves vast amount of code
if you have a lot of different delay requirements in your program.
in the 46/26K22 there are extra timers such as 4 and 6 that can
do a fine job with this too.
Code: |
#bit TMR2IF=0xF9E.1
// code originally for 18F46/26K22, 18F46/26-10/20 etc
// crystal oscillator at 2^23 hz -8.388608 mhz with HSPLL Fosc is 8.3886mhz
// using TMR 2
// 0-255 max count of misc fast short delay
// 0=5ms 1=2.5ms 2=1ms 3=500us 4=200us
// 5=100us 6=50us 7=25us 8=10us 9=5us 10=2.5us
#define ms5 0
#define ms2_5 1
#define ms1 2
#define us500 3
#define us200 4
#define us100 5
#define us50 6
#define us25 7
#define us10 8
#define us5 9
#define us2_5 10
#define justset 1
int1 oktime=1; // oktime can be changed to 0 inside an interrupt handler
// to abort either timer early
// 0-255 counts rate selector do setup only
//
// best (most accurate) practice is to adjust timer
// for more than 2 increments if possible so an example for 1msec delay
// vardelay(10,us100,0); // 1msec by counting 100usec 10x
void vardelay (int8 count, int8 rate, int8 setonly ){
switch(rate){
case 0:
setup_timer_2(T2_DIV_BY_16,225,12); break; //5 msec
case 1:
setup_timer_2(T2_DIV_BY_16,255,5); break; //2.5 msecs
case 2:
setup_timer_2(T2_DIV_BY_16,255,2); break; // 1msec
case 3:
setup_timer_2(T2_DIV_BY_16,255,1); break; // 500 usec
case 4:
setup_timer_2(T2_DIV_BY_4,200,2); break; //200 usecs per
case 5:
setup_timer_2(T2_DIV_BY_4,200,1); break; //100 usecs per
case 6:
setup_timer_2(T2_DIV_BY_1,200,2); break; //50 usecs per
case 7:
setup_timer_2(T2_DIV_BY_1,100,2); break; //25 usecs per
case 8:
setup_timer_2(T2_DIV_BY_1,40,2); break; //10 usecs per
case 9:
setup_timer_2(T2_DIV_BY_1,20,2); break; //5 usecs per
case 10:
setup_timer_2(T2_DIV_BY_1,10,2); break; //2.5 usecs per
default :
setup_timer_2(T2_DIV_BY_4,200,1); break; //100 usecs per deflt
} // switch end setup
if (setonly || !count) return;
set_timer2(0);tmr2if=0;
while(count&&oktime){
if (tmr2if){ tmr2if=0; --count;}
// else YOUR POLLED ACTION GOES HERE !!!
}
}
// if you FIRST call vardelay (dumi_count, your_rate,1)
// then this call can be used for repeat timing at "your_new_rate"
void vartimer(unsigned int8 count){
set_timer2(0);tmr2if=0;
while(count&&oktime){
if (tmr2if){ tmr2if=0; --count;}
// else YOUR POLLED ACTION GOES HERE !!!
}
}
|
|
|