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

📄 aaa.c

📁 用51单片机编译成的频率计的源程序
💻 C
📖 第 1 页 / 共 3 页
字号:

    // NOTE: USER CODE MUST WAIT AT LEAST 20 MS before calling ADC_Read (Using the ADC)
}



/******************************************************************************
*                       ADC_Init(channel)
*功能描述:ADC初始化,选择模拟通道输入,初始化时钟,关闭ADC中断
*参    数:channel - uchar 选择ADC通道
*注    意:当ADC通道改变得时候,此子程序一定要被调用
*****************************************************************************/
void ADC_Init (unsigned char channel) 
{
    unsigned char temp;
    ACON = 0;                           

    temp = (0x01) << channel;           // 选择通道
    P1SFS0 |= temp;         
    P1SFS1 |= temp;                     // 设置P1口相应位为ADC输入

    ADCPS =(0x08 + 1);  // 使能ADC时钟,设置时钟频率
    _nop_();
    ACON = 0x20;                        // 允许ADC转换


    // NOTE: USER CODE MUST WAIT AT LEAST 20 MS before calling ADC_Read (Using the ADC)
}

/******************************************************************************
*                      uint  ADC_Read(channel)
*功能描述:读A/D转换后的数据
*参    数:channel,初始化程序中选择的通道
*返 回 值:ADC转换结果,12位
*注    意:该子程序调用前,ADC_Init()必须先被调用
*******************************************************************************/
unsigned int ADC_Read( unsigned char channel )
{
    unsigned int  temp_ADC_result;  
    ACON &= 0xE0;                        //清除输入通路  ~(00101110B) = (11010001B)

    ACON |= (channel<<2);                 //选择通路
    _nop_ ();
    _nop_ ();   

    ACON |= 0x02;                           //开始ADC转换
    _nop_ ();                               //延时一个机器周期: ADST: 1->0

    while( (ACON & 0x01) != 1 );            //等待转换结束

      // Note: For increased ADC accuracy, the while loop above should be
      //       replaced with code that puts the MCU into Idle mode via PCON
      //       and makes use of the ADC interrupt to exit the Idle mode.
      //       The user would need to enable the ADC int and define the ADC ISR.

    temp_ADC_result = (ADAT1<<8)+ADAT0;     //Calculate ADC conversion result

    return (temp_ADC_result);
}


/*******************************************************************************
*    int sin_angle(long angle )
*功能描述:角度换算函数,使角度值控制在180以内
*
********************************************************************************/

int sin_angle(long angle )
{
	int Mod_data;

	Mod_data = (int)angle/180;
	switch (Mod_data )
	{
	case 0:
		 M_angle = sin_table[angle];
	     break;
	case 1:
		 M_angle = -sin_table[angle - 180];
		 break;
    case 2:
	     M_angle = sin_table[angle - 360];
		 break;
	case 3:
		 M_angle = -sin_table[angle - 540];
 	     break;
	}

	return(M_angle);
}

/*******************************************************************************
*             void first(void )
*第一个采样点计算函数,在K=0时计算
*******************************************************************************/
void first(void )		
{

	U_angle = K*180/N;			//U相在K=0时计算
	V_angle = U_angle + 120;
	W_angle = U_angle + 240;


	U_Toff = ((Half_Ts * (0xffff - M*(sin_angle(U_angle))))>>16);
	V_Toff = ((Half_Ts * (0xffff - M*(sin_angle(V_angle))))>>16);
	W_Toff = ((Half_Ts * (0xffff - M*(sin_angle(W_angle))))>>16);



	P_flag = 0;

}

/*------------------------------------------------------------------------------
timer0_isr()

This function is an interrupt service routine for TIMER 0.  It should never
be called by a C or assembly function.  It will be executed automatically
when TIMER 0 overflows.

This ISR stops timer0, adjusts the counter so that another interrupt occurs in
10ms, and then restarts the timer.
------------------------------------------------------------------------------*/

//定时器0中断服务程序
//定时器0用于产生采样周期的定时中断,采样周期Ts	=1/2载波周期 = 278 时钟周期
static void timer0_isr (void) interrupt TF0_VECTOR using 1
{
  TR0 = 0;						/* stop timer 0 */
  TL0 = (timer0_value & 0x00FF);
  TH0 = (timer0_value >> 8);
  TR0 = 1;						/* start timer 0 */
  

////////////////////////////////////////////
////将上一次定时器中断计算的延时值送入TCM0,TCM1,TCM2的比较寄存器
//
//
////取当前PCA0的计数值
	PCA0 = PCACL0 + (PCACH0  << 8 );
//
////实际延时时间应加上PCA0的当前计数值
//
	U_Toff += PCA0;
	V_Toff += PCA0;
	W_Toff += PCA0;
	U_Ton += PCA0;
	V_Ton += PCA0;
	W_Ton += PCA0;
//
//
////偶数顶点采样使用Toff,奇数底点采样使用Ton
  	if ( P_flag==0)
	{
		CAPCOML0 = (U_Toff & 0x00FF);
		CAPCOMH0 = (U_Toff >> 8);
	 	
		CAPCOML1 = (V_Toff & 0x00FF);
		CAPCOMH1 = (V_Toff >> 8);

		CAPCOML2 = (W_Toff & 0x00FF);
		CAPCOMH2 = (W_Toff >> 8);
	}
	else 
	{
		CAPCOML0 = (U_Ton & 0x00FF);
		CAPCOMH0 = (U_Ton >> 8);
	 	
		CAPCOML1 = (V_Ton & 0x00FF);
		CAPCOMH1 = (V_Ton >> 8);

		CAPCOML2 = (W_Ton & 0x00FF);
		CAPCOMH2 = (W_Ton >> 8);	
	}											 //66

////////////////////////////////////////////

//下一个采样点
	
	
 	P_flag = ~P_flag;		//奇偶点变换

	K++;					//下一个采样点值

	Tm++;
	U_angle = K*180/N;
	V_angle = U_angle + 120;
	W_angle = U_angle + 240;




	if (P_flag == 0)
	{
//		U_Toff =k1* ((Half_Ts * (0xffff - M*(sin_angle(U_angle))))>>16);
//		V_Toff =k1* ((Half_Ts * (0xffff - M*(sin_angle(V_angle))))>>16);
//		W_Toff =k1* ((Half_Ts * (0xffff - M*(sin_angle(W_angle))))>>16);
		U_Toff =((Half_Ts * (0xffff - M*(sin_angle(U_angle))))>>16);
		V_Toff =((Half_Ts * (0xffff - M*(sin_angle(V_angle))))>>16);
		W_Toff =((Half_Ts * (0xffff - M*(sin_angle(W_angle))))>>16);
	}
	else
	{
		U_Ton =((Half_Ts * (0xffff + M*(sin_angle(U_angle))))>>16);
		V_Ton =((Half_Ts * (0xffff + M*(sin_angle(V_angle))))>>16);
		W_Ton =((Half_Ts * (0xffff + M*(sin_angle(W_angle))))>>16);

	
	}

//	if (P_flag == 0)
//	{
//		U_Toff = (417 * (0x400000 - M*(sin_angle(U_angle))))>>22;
//		V_Toff = (417 * (0x400000 - M*(sin_angle(V_angle))))>>22;
//		W_Toff = (417 * (0x400000 - M*(sin_angle(W_angle))))>>22;
//	}
//	else
//	{
//		U_Ton = (417 * (0x400000 + M*(sin_angle(U_angle))))>>22;
//		V_Ton = (417 * (0x400000 + M*(sin_angle(V_angle))))>>22;
//		W_Ton = (417 * (0x400000 + M*(sin_angle(W_angle))))>>22;
//	
//	
//	}
//	aa=0;

	
	if ( K==2*N )
	{ K=0;

//	  P_flag = 0;
	 }

	 
}
  
/****************************************************************************
*死区指令延时,应实测,要考虑中断影响
* 10个temp 延时约6us
****************************************************************************/
void delay1()					  
{								  
	char temp;					 

	EA=0;					
	temp = 0;
	temp = 0;
	temp = 0;
	temp = 0;
	temp = 0;
	temp = 0;
	temp = 0;
	temp = 0;
	temp = 0;
	temp = 0;
	temp = 0;
	temp = 0;
	temp = 0;
	temp = 0;
	temp = 0;
	temp = 0;
	temp = 0;
	temp = 0;

	EA=1;

}
/***************************************************************************
*定时器0初始化
***************************************************************************/
void timer0_init (void)
{
 	EA = 0;					/* disable interrupts */

  	TR0 = 0;				/* stop timer 0 */
  	TMOD &= 0xF0;			/* clear timer 0 mode bits - bottom 4 bits */
  	TMOD |= 0x01;			/* put timer 0 into 16-bit no prescale */

    timer0_value = 0x10000-Ts;		//采样周期=1/2载波周期	
  	TL0 = (timer0_value & 0x00FF);
  	TH0 = (timer0_value >> 8);

 // 	PT0 = 1;				/* set high priority interrupt for timer 0 */
 	PT0 = 0;
  	ET0 = 1;				/* enable timer 0 interrupt */
  	TR0 = 1;				/* start timer 0 */
  	EA = 1;					/* enable interrupts */
}



/***************************************************************************
*PCA中断服务程序
***************************************************************************/
static void PCA_isr (void) interrupt PCA_VECTOR using 1 

{
	unsigned char PCA_status;


	PCA_status = PCASTA;			//读PCA中断状态


	if ( PCA_status & 0x01)			//TCM0中断,U相
	{

		if (P_flag==0)
		{
			P4_3 = 1;				//偶数采样中断到,关V4 延时 开V1
			delay1();
			P4_0 = 0;
		}
		else 
		{
			P4_0 = 1;				//奇数采样中断到,关V1 延时 开V4
			delay1();
			P4_3 = 0;
		}
	PCASTA &= 0xFE;

	}
	
	if ( PCA_status & 0x02)			//TCM1中断,V相
	{

		if (P_flag==0)
		{
			P4_5 = 1;				//偶数采样中断到,关V6 延时 开V3
			delay1();
			P4_2 = 0;
		}
		else 
		{
			P4_2 = 1;				//奇数采样中断到,关V3 延时 开V6
			delay1();
			P4_5 = 0;
		}
	PCASTA &= 0xFD;
	}

	if ( PCA_status & 0x04)			//TCM2中断,W相
	{

		if (P_flag==0)
		{
			P4_4 = 1;				//偶数采样中断到,关V5 延时 开V2
			delay1();
			P4_1 = 0;
		}
		else 
		{
			P4_1 = 1;				//奇数采样中断到,关V2 延时 开V5
			delay1();
			P4_4 = 0;
		}
	PCASTA &= 0xFB;
	}

	
//	PCASTA &= 0x00;					 //清PCA中断状态

}

//PCA0初始化
void PCA_init()
{

	unsigned int PCA0;
	//0.1 Configure pins as PCA function
//	P4SFS0=0xff;
//	P4SFS1=0;

	//0.2 initialize PCA0 counter
	PCACL0=PCACH0=0;
	PCACL1=PCACH1=0;

	//1.2 select PCA0CLK as PCA0 clock source
	//PCA0时钟为fosc,timer0_isr中Toff,Ton计数值*12 再写入比较寄存器
//	CCON2=0x10;				
	CCON2=0x12;	   //fosc/4

	//Stop PCA0 counter
	PCACON0=0x00;

	//3. Set TCM0 operationg mode,16bit soft timer , enable softimer interrupt
//	TCMMODE0=0x48;
	TCMMODE0=0xC8;
	TCMMODE1=0xC8;
		
	TCMMODE2=0xC8;		


	CAPCOML0 = (PCA0 & 0x00FF);
	CAPCOMH0 = (PCA0 >> 8);


	// 开PCA中断
	IEA |= 0x20;
	IPA |= 0X20;	  // set high priority interrupt for PCA0 
	
	 //5. Start PCA0 counter
	 PCACON0|=0x40;

}


/******************************************************************************
*                       uint getVA(channel)
*功能描述:读取输出电压,电流值
*参    数:channel,选择读取通道
*****************************************************/


void getVA (uchar channel)
{ 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -