www.pudn.com > RS485_USART-ok.rar > speed.c, change:2007-09-29,size:7557b


//*---------------------------------------------------------------------------- 
//*      Shenzhen ANCHE Tech CO.,LTD 
//*---------------------------------------------------------------------------- 
//*---------------------------------------------------------------------------- 
//* File Name           : drv_led.c 
//* Designer            : Tianlong Jing, at 2006 
//* Object              : led Library. 
//* 
//* 1.0 25/08/00 LLD    : Creation 
//* 2.0 10/12/01 PFi    : Access to Data Pointer/Counter Registers has been removed. 
//*                     : The RevA of the M558000 does not features DAC PDC. 
//*---------------------------------------------------------------------------- 
#include    "speed.h" 
 
 
SPEED_CAP_FIFO 	SpeedFIFO[2]; 
//static	float		Speed_Coef[FRAME_NUM]; 
 
// 车速脉冲宽度缓冲,排序用 
//static 	INT32U	SpeedPeriodBuf[SPEED_CAP_FIFO_BUF_SIZE-1]; 
 
//	INT32U		INTERRUPT_flag_test[3]={0}; 
 
 
//*---------------------------------------------------------------------------- 
// 速度脉冲输入中断处理--- Timer0 (FRAME RIGHT) 
//*---------------------------------------------------------------------------- 
void Speed_CAP0_Interrupt_Handler(void)__irq 
{ 
	AT91C_BASE_AIC->AIC_IVR   = 0;            // Debug variant of vector read (protect mode is used)   
	                                          // Clear  timer #0 interrupt                             
	AT91C_BASE_AIC->AIC_ICCR  = 1 << AT91C_ID_TC0; 
	AT91C_BASE_AIC->AIC_EOICR = 0;            // Signal end of interrupt          
	         
	Speed_1st_IRQ_Handle(AT91C_BASE_TC0);			// CAP0 --- Left Speed 
} 
 
void Speed_CAP2_Interrupt_Handler(void)__irq 
{ 
	AT91C_BASE_AIC->AIC_IVR   = 0;            // Debug variant of vector read (protect mode is used)   
	                                          // Clear  timer #0 interrupt                             
	AT91C_BASE_AIC->AIC_ICCR  = 1 << AT91C_ID_TC2; 
	AT91C_BASE_AIC->AIC_EOICR = 0;            // Signal end of interrupt          
	         
	Speed_2nd_IRQ_Handle(AT91C_BASE_TC2);			// CAP0 --- Left Speed 
} 
void Speed_Init(void) 
{ 
	//禁止TC0/TC2中断 
	AT91F_AIC_DisableIt(AT91C_BASE_AIC,AT91C_ID_TC0); 
	AT91F_AIC_DisableIt(AT91C_BASE_AIC,AT91C_ID_TC2); 
	//---------------------------------------------------------- 
	// 1 --- PIO periph Config 
	// Configure PIO controllers to periph mode of Timer0 
	AT91F_PIO_CfgPeriph( 
		AT91C_BASE_PIOB, // PIO controller base address 
		((unsigned int) AT91C_PB23_TIOA0   ) | 
		((unsigned int) AT91C_PB24_TIOB0   ), // Peripheral A 
		0); // Peripheral B 
	// Configure PIO controllers to periph mode of Timer2 
	AT91F_PIO_CfgPeriph( 
		AT91C_BASE_PIOB, // PIO controller base address 
		((unsigned int) AT91C_PB27_TIOA2   ) | 
		((unsigned int) AT91C_PB28_TIOB2   ), // Peripheral A 
		0); // Peripheral B 
	//---------------------------------------------------------- 
	// 2 --- clock config 
	AT91F_TC0_CfgPMC(); 
	AT91F_TC2_CfgPMC(); 
 
	//-----------------------------------------------------------  
	// 3 --- Capture Mode 
	//禁止记数时钟 
	AT91C_BASE_TC0->TC_CCR=AT91C_TC_CLKDIS;	// CLKDIS = 1 
	AT91C_BASE_TC2->TC_CCR=AT91C_TC_CLKDIS;	// CLKDIS = 1 
	//禁止中断 
	AT91F_TC_InterruptDisable(AT91C_BASE_TC0,0xFFFF); 
	AT91F_TC_InterruptDisable(AT91C_BASE_TC2,0xFFFF); 
	//设置TC模式(1024) --- WAVE(bit15) = 0 ==> Capture Mode 
	AT91C_BASE_TC0->TC_CMR=AT91C_TC_CLKS_TIMER_DIV3_CLOCK | 	// TIMER_CLOCK3 = MCK/32 
	                                             AT91C_TC_ETRGEDG_NONE |         //外部触发禁用 
	                                             AT91C_TC_LDRA_RISING |		// RA Loading on rising edge of TIOA 
	                                             AT91C_TC_LDRB_RISING;			// none RB Loading( on rising edge of TIOA) 
	//设置 timer0 中断 
	AT91F_AIC_ConfigureIt(AT91C_BASE_AIC,                          //基地址 
	                AT91C_ID_TC0,                            			//ID 
	                SPEED_CAP0_INTERRUPT_LEVEL,                	//中断优先级为6 
	                AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL,        	//内部高电平触发 
	                0 );                 			//中断处理函数 
     AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC0] = (unsigned int) Speed_CAP0_Interrupt_Handler ; 
 
					 
	// TIMER 2 
	AT91C_BASE_TC2->TC_CMR=AT91C_TC_CLKS_TIMER_DIV3_CLOCK | 	// TIMER_CLOCK3 = MCK/32 
	                                             AT91C_TC_ETRGEDG_NONE| 
	                                             AT91C_TC_LDRA_RISING |		// RA Loading on rising edge of TIOA 
	                                             AT91C_TC_LDRB_RISING;			// none RB Loading( on rising edge of TIOA) 
	//设置 timer2 中断 
	AT91F_AIC_ConfigureIt(AT91C_BASE_AIC,                          //基地址 
	                AT91C_ID_TC2,                            				//ID 
	                SPEED_CAP2_INTERRUPT_LEVEL,                		//中断优先级为6 
	                AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL,        	//内部高电平触发 
	                0 );            //中断处理函数 
 
	 AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC2] = (unsigned int) Speed_CAP2_Interrupt_Handler ; 
	  
 
	//设置记数值和中断 
	AT91C_BASE_TC0->TC_RC=0xffff; 
	AT91C_BASE_TC2->TC_RC=0xffff; 
	AT91C_BASE_TC0->TC_IER= AT91C_TC_COVFS | 
		                                      AT91C_TC_LDRAS | 
		                                      AT91C_TC_LDRBS; 
	AT91C_BASE_TC2->TC_IER= AT91C_TC_COVFS | 
		                                      AT91C_TC_LDRAS | 
		                                      AT91C_TC_LDRBS; 
 
	// 开中断 
	AT91F_AIC_EnableIt(AT91C_BASE_AIC,AT91C_ID_TC0); 
	AT91F_AIC_EnableIt(AT91C_BASE_AIC,AT91C_ID_TC2); 
	 
	// 开计数时钟,软件触发 
	AT91C_BASE_TC0->TC_CCR=AT91C_TC_CLKEN | AT91C_TC_SWTRG;		// CLKEN = 1 
	AT91C_BASE_TC2->TC_CCR=AT91C_TC_CLKEN | AT91C_TC_SWTRG;		// CLKEN = 1 
} 
 
 
 
void Speed_1st_IRQ_Handle(AT91PS_TC pTC) 
{ 
	 
	INT32U status; 
	 
  	//read and clear status  register; 
	status = pTC->TC_SR; 
	 
 
	if(status & AT91C_TC_COVFS)	// Counter Overflow Interrupt	 
		 
		return; 
	 
	else if  (status & AT91C_TC_LDRAS)	// RA Loading (TIOA captured) 
		 
		SpeedFIFO[FIRST].TC_Capt[0] = pTC->TC_RA; 
			 
	else  if (status & AT91C_TC_LDRBS) 
	        
	       SpeedFIFO[FIRST].TC_Capt[1]= pTC->TC_RB; 
	else 
		return ; 
	 
			 
		 
} 
 
 
void Speed_2nd_IRQ_Handle(AT91PS_TC pTC) 
{ 
	 
	INT32U status; 
	 
  	//read and clear status  register; 
	status = pTC->TC_SR; 
	 
 
	if(status & AT91C_TC_COVFS)	// Counter Overflow Interrupt	 
			 
		return ; 
	 
	else if  (status & AT91C_TC_LDRAS)	// RA Loading (TIOA captured) 
 
		SpeedFIFO[SECOND].TC_Capt[0] = pTC->TC_RA; 
			 
	else  if (status & AT91C_TC_LDRBS) // RB Loading (TIOA captured) 
	       
	       SpeedFIFO[SECOND].TC_Capt[1] = pTC->TC_RB; 
	else 
		return ; 
} 
			 
		 
INT32U freq_1st_Read(void)  //计算第一路频率 
{ 
	INT32U speed,freq; 
	if (SpeedFIFO[FIRST].TC_Capt[1]  > SpeedFIFO[FIRST].TC_Capt[0]) 
	{ 
	    speed = SpeedFIFO[FIRST].TC_Capt[1] - SpeedFIFO[FIRST].TC_Capt[0]; 
	    freq = (AT91B_MCK )  / 32 /speed;	 
	   
	} 
	else 
	{ 
	    speed = SpeedFIFO[FIRST].TC_Capt[0] - SpeedFIFO[FIRST].TC_Capt[1]; 
	    freq = (AT91B_MCK )  / 32 /speed;	 
	} 
		    return freq; 
 
} 
 
 
INT32U freq_2nd_Read(void) 
{ 
	INT32U speed,freq; 
	if (SpeedFIFO[SECOND].TC_Capt[0]  > SpeedFIFO[SECOND].TC_Capt[1]) 
	{ 
	    speed = SpeedFIFO[SECOND].TC_Capt[0] - SpeedFIFO[SECOND].TC_Capt[1]; 
	    freq = (AT91B_MCK )  / 32 /speed;	 
	   
	} 
	else 
	{ 
	    speed = SpeedFIFO[SECOND].TC_Capt[1] - SpeedFIFO[SECOND].TC_Capt[0]; 
	    freq = (AT91B_MCK )  / 32 /speed;	 
	} 
		    return freq; 
 
}