📄 timers.c
字号:
/*
OH2NLT DDS Synthesizer board timer & IRQ functions
Juha Niinikoski OH2NLT 28.03.2004
Pulse wheel fault found, OPTION register handling corrected 29.04.2004
SWR meter timers added 14.05.2004
*/
//**********************
// TMR0 used for delays
//**********************
/* Delays a multiple of 1 milliseconds at 16 MHz TMR0 timer */
void delay( char millisec )
{
PS2 = 1; /* prescaler divide by 32 */
PS1 = 0;
PS0 = 0;
T0CS = 0;
PSA = 0;
do {
TMR0 = 0;
while ( TMR0 < 125); // 125 * 8 = 1000
} while ( -- millisec > 0);
}
/* Delays a multiple microseconds + start delay at 16 MHz TMR0 timer */
void udelay( char usec )
{
PS2 = 0; /* prescaler divide by 4 = 1MHz clock for TMR0 */
PS1 = 1;
PS0 = 0;
T0CS = 0;
PSA = 0;
TMR0 = 0;
while ( TMR0 < usec )
{
}
}
//**************************************************
// TMR2 used for 1 mS interrupt generation
//***************************************************
// delays calculated for 16 MHz clock
static char pw_sample;
static char pw_state;
static long pw_data;
/* Init TMR2 for 1 mS interrupt generation */
void Init_timers(void) // set up timers & enable IRQs
{
PR2 = 249; // set TMR2 cycle time 1mS
T2CKPS1 = 1; // Prescaler = 16 = 250kHz clock for TMR2
TMR2ON = 1; // start TMR2
TMR2IE = 1; // enable TMR2 IRQ
PEIE = 1; // enable peripheral IRQs
pw_state = 0; // init pulse wheel
INTE = 1; // enable RB0 IRQs
GIE = 1; // enable interrupts
}
unsigned long get_pw_data(void) // read current pulse wheel data
{
unsigned long ltemp;
GIE = 0; // disable interrupts, do atomic operation
ltemp = pw_data; // take clean sample
GIE = 1; // enable interrupts
return ltemp;
}
void set_pw_data(unsigned long pd) // set pulse wheel seed data
{
GIE = 0; // disable interrupts, do atomic operation
pw_data = pd; // set clean value
GIE = 1; // enable interrupts
}
/* Pulse wheel interrupt handler */
void intf_handle(void)
{
// char x;
//IRQ_TEST = 1; // test loop time. Measured 18 ... 20us = 50kHz max IRQ rate
pw_sample = (PW_PORT & PW_MASK) >> 1; // save pw bits state
if(INTEDG == 1) // This should be rising edge
{
if(P_EDGE == 0) // something wrong, do nothing
{
INTF = 0;
// IRQ_TEST = 0;
return;
}
INTEDG = 0; // change polarity for next event
}
else
{
if(RB0 == 1)
{
INTF = 0;
// IRQ_TEST = 0;
return;
}
INTEDG = 1;
}
INTF = 0; // reset IRQ flag
INTE = 1;
/* Run pulse wheel state machine */
switch (pw_state) // run state machine
{
case 0:
if(pw_sample == 2) // count up
{
pw_state = 1;
pw_data = pw_data + f_step;
}
else
{
if(pw_sample == 1) // count down
{
pw_state = 3;
pw_data = pw_data - f_step;
}
}
break;
case 1:
if(pw_sample == 3) // count up
{
pw_state = 2;
pw_data = pw_data + f_step;
}
else
{
if(pw_sample == 0) // count down
{
pw_state = 0;
pw_data = pw_data - f_step;
}
}
break;
case 2:
if(pw_sample == 1) // count up
{
pw_state = 3;
pw_data = pw_data + f_step;
}
else
{
if(pw_sample == 2) // count down
{
pw_state = 1;
pw_data = pw_data - f_step;
}
}
break;
case 3:
if(pw_sample == 0) // count up
{
pw_state = 0;
pw_data = pw_data + f_step;
}
else
{
if(pw_sample == 3) // count down
{
pw_state = 2;
pw_data = pw_data - f_step;
}
}
break;
default:
pw_state = 0; // error, restart state machine
}
if(pw_data < MIN_DDS) // cut to limits
pw_data = MIN_DDS;
if(pw_data > MAX_DDS)
pw_data = MAX_DDS;
pw_ready = 1; // set data available flag
//IRQ_TEST = 0;
}
/* 1ms Timer handler */
void tmr2_handle(void) // TMR2 runs for 1mS general timing
{
TMR2IF = 0; // reset IRQ flag
if(max_timer != 0) // decrement display delay timer
{
max_timer--;
if(max_timer == 0)
{
fwd_max = 0; // set current values to max
rev_max = 0;
}
}
if(pwr_ph_timer != 0) // count down to 0 and stay there
pwr_ph_timer--; // power graph peak-hold timer
}
/* IRQ handler */
static void interrupt tmrint(void)
{
if(TMR2IF) // check if TMR2
tmr2_handle();
if(INTF) // check if pulse wheel
intf_handle();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -