⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timers.c

📁 AD9850 DDS chip driver
💻 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 + -