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

📄 ad.c

📁 2407DSP开发应用程序实例(有14个常用模块程序)
💻 C
字号:

// 该程序用于进行A/D转换的演示,A/D转换的结果存于数足ADRESULT[16]中,
// 寄存器cesi用于测试每个A/D转换的结果 
#include       "register.h"
int        i=0X00,ADIa[32],ADUa[32];
//#pragma DATA_SECTION(ADUa,".stack");
//int	ADUa[32]={611,707,796,873,937,984,1013,1023,1013,984,937,873,796,707,611,512,412,
//				316,227,150,86,39,10,0,10,39,86,150,227,316,412,512};
int	ADIa[32]={707,796,873,937,984,1013,1023,1013,984,937,873,796,707,611,512,412,
				316,227,150,86,39,10,0,10,39,86,150,227,316,412,512,611}; 
//int ADUa1[16]={512,708,874,985,1023,985,874,708,512,316,150,39,0,39,150,316};
//int ADIa1[16]={512,708,874,985,1023,985,874,708,512,316,150,39,0,39,150,316};
unsigned int Iaxzh=710,Uaxzh=665,IaAv,UaAv,UaAv1,UbAv,Ubxzh=665;
unsigned int Ua_d,Ua3,Ua5,Uaxsh=938,Iaxsh=997,Ua1,Ia1,bianyaqi=75;	//对fft计算结果的校验系数;
int		adpoint=0;
long P,Q,S,P1,Q1,S1;
unsigned int Factor; 
int output1[64],output2[64];
/******************和FFT计算,调用有关的参数及常数列表*****************/
#define N	32
extern void fft(void);       
extern void resave();  
extern int nom;			/*when nom=1, FFT implement normalization*/
extern int input[64];   	/*input data */
int indati[32]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int indatr[32];/*={0,6807,10755,10947,8838,6838,6368,7039,
		   499,7039,6368,6838,8838,10947,10755,6807,
		   0,-6807,-10755,-10947,-8838,-6838,-6368,-7039,
		   -7499,-7039,-6368,-6838,-8838,-10947,-10755,-6807
	       };*/
				
		/*={ 17500,15354,10915,4887,1767,1139,1517,1251,
                  0,-1251,-1517,-1139,-1767,-4887,-10915,-15354,
                  -17500, -15354,-10915,-4887,-1767,-1139,-1517,-1251,
                  0,1251,1517,1139,1767,4887,10195,15354};  */

int sintab[N]={ 0x7FFF,0x0000,0x7D89,0xE708,0x7640,0xCF05,0x6A6C,0xB8E4,
		0x5A81,0xA57F,0x471C,0x9594,0x30FB,0x89C0,0x18F8,0x8277,
		0x0000,0x8001,0xE708,0x8277,0xCF05,0x89C0,0xB8E4,0x9594,
		0xA57F,0xA57F,0x9594,0xB8E4,0x89C0,0xCF05,0x8277,0xE708, 
	      };
/*****************************************************************
** 函数名: Xiebo()
** 功能描述:根据fft计算结果计算各相电压3次、5次谐波的模值
** 作 者:严利平
** 日 期:2003年1月12日
****************************************************************/

void Xiebo()
{	unsigned int i;
	unsigned long data;
						
	for(i=0;i<=63;i++)        	 		
		input[i]=0;	
	for(i=0;i<32;i++)
		indatr[i]=ADUa[i]-0x01FF;
	resave();
	fft();
    for(i=0;i<=63;i++)        	 		
		output1[i]=input[i];	
	
	for(i=0;i<=63;i++)        	 		
		input[i]=0;	
	for(i=0;i<32;i++)
		indatr[i]=ADIa[i]-0x01ff;
	resave();
	fft();
	data=input[2]*input[2]+input[3]*input[3];		//计算基波				
	data=qsqrt(data);
	Ia1=(unsigned int)((data*Iaxsh)>>9);  
	
	for(i=0;i<=63;i++)        	 		
		input[i]=0;	
	for(i=0;i<32;i++)
		indatr[i]=ADIa[i];
	resave();
	fft();
	for(i=0;i<=63;i++)        	 		
		output2[i]=input[i]; 
	

	P1=(output1[2])*(output2[2])+(output1[3])*(output2[3]);
	
	Q1=(output1[3])*(output2[2])-(output1[2])*(output2[3]);  
	
	P1=(P1*Iaxsh)>>7;
	P1=(P1*Uaxsh)>>6;
	P1=P1/100;
	
	Q1=(Q1*Iaxsh)>>7;	
	Q1=(Q1*Uaxsh)>>6;
	Q1=Q1/100; 
	
			
	asm(" nop");		
	return;
	
    
}


//  屏蔽中断子程序        
void inline disable() 
	{
   		 asm(" setc INTM");
	}
// 开总中断子程序
void inline enable()
{
		asm(" clrc INTM"); 
}
// 系统初始化子程序
void  initial()
{
   asm(" setc      SXM");	// 符号位扩展有效
   asm(" clrc     OVM");//累加器中结果正常溢出
   asm(" clrc      CNF");	// B0被配置为数据存储空间
   SCSR1=0x83FE;	// CLKIN=10M,CLKOUT=4*CLKIN=40M
   WDCR=0x0E8;	// 不使能看门狗,因为SCSR2中的WDOVERRIDE
			// 即WD保护位复位后的缺省值为1,故可以用
	  		// 软件禁止看门狗
   IMR=0x0001;	//  允许INT1中断
   IFR=0x0FFFF;	//  清除全部中断标志,"写1清0"
   	PBDATDIR=0x0FF00;		// IOPB端口设置为输出方式
	PADATDIR=PADATDIR&0x0FFEF;	// IOPA4=0
	PADATDIR=PADATDIR|0x1010;		// IOPA4 设置为输出方式,且IOPA4=1
	PADATDIR=PADATDIR&0x0FFEF;	// IOPA4=0  
}
// AD初始化子程序
void  ADINIT()
{
   T4CNT=0X0000;	// T4计数器清0
   T4CON=0X170C;	// T4为连续增计数模式,128分频,且选用内部时钟源
   T4PR=0X59;	// 设置T4的周期寄存器 ,0.625ms中断一次
   GPTCONB=0X400;	// T4周期中断标志触发AD转换
   EVBIFRB=0X0FFFF;	// 清除EVB中断标志,写"1"清0
   ADCTRL1=0X10;	// 采样时间窗口预定标位ACQ PS3-ACQ PS0为0,
		// 转换时间预定标位CPS为0,AD为启动/停止模式,排
		// 序器为级连工作方式,且禁止特殊的两种工作模式
   ADCTRL2=0X8405;	// 可以用EVB的一个事件信号触发AD转换,
	// 且用中断模式1
   MAXCONV=0X0F;	// 16通道
   CHSELSEQ1=0X3210;
   CHSELSEQ2=0X7654;
   CHSELSEQ3=0X0BA98;
     CHSELSEQ4=0X0FEDC;	// 转换通道是0-15  
}
// 启动AD转换子程序(通过启动定时器4的方式间接启动)
void  ADSOC()
{
   T4CON=T4CON|0X40;	// 启动定时器4
}
// 若是其它中断则直接返回子程序
void interrupt nothing()
{
   return;
}

/*****************************************************************
** 函数名: Youxiaozhi()
** 功能描述:根据32点采样值计算测量电压、电流有效值
** 作 者:严利平
** 日 期:2003年1月13日
****************************************************************/
void Youxiaozhi()
{	unsigned int	j;
	unsigned long	data,data1,b0,b1,b2,b3,b4,b5,b6,b7;


	b0=0;							// 求Ua  (Uab)的有效值 
	b1=0;
	b2=0;
	b3=0;
	b4=0;
	b5=0;
	b6=0;
	b7=0;
	for(j=0;j<4;j++)
	{	b0=b0+(ADUa[j]-0x01FF)*(ADUa[j]-0x01FF);
		b1=b1+(ADUa[j+4]-0x01FF)*(ADUa[j+4]-0x01FF);
		b2=b2+(ADUa[j+8]-0x01FF)*(ADUa[j+8]-0x01FF);
		b3=b3+(ADUa[j+12]-0x01FF)*(ADUa[j+12]-0x01FF);
		b4=b4+(ADUa[j+16]-0x01FF)*(ADUa[j+16]-0x01FF);
		b5=b5+(ADUa[j+20]-0x01FF)*(ADUa[j+20]-0x01FF);
		b6=b6+(ADUa[j+24]-0x01FF)*(ADUa[j+24]-0x01FF);
		b7=b7+(ADUa[j+28]-0x01FF)*(ADUa[j+28]-0x01FF);
	}
	data=((b0>>3)+(b1>>3)+(b2>>3)+(b3>>3))>>2;
	data1=((b4>>3)+(b5>>3)+(b6>>3)+(b7>>3))>>2;		
	data=qsqrt(data+data1);
	UaAv=(unsigned int)((data*Uaxzh)>>4);
//	UaAv=UaAv*7.33;
	
  
	b0=0;								// 求Ia的有效值 
	b1=0;
	b2=0;
	b3=0;
	for(j=0;j<8;j++)
	{	b0=b0+(ADIa[j]-0x01FF)*(ADIa[j]-0x01FF);       
		b1=b1+(ADIa[j+8]-0x01FF)*(ADIa[j+8]-0x01FF);
		b2=b2+(ADIa[j+16]-0x01FF)*(ADIa[j+16]-0x01FF);
		b3=b3+(ADIa[j+24]-0x01FF)*(ADIa[j+24]-0x01FF);
	}
	data=((b0>>3)+(b1>>3)+(b2>>3)+(b3>>3))>>2;		
	data=qsqrt(data);										
	IaAv=(unsigned int)((data*Iaxzh)>>9);  

	return;
							
} 

/**************************************************************************/
void PowerY()
{	int i,k,k1; 
	long a0,a1,a2,a3,a4,a5,a6,a7,data;

	a0=0;		/* 计算Ua*Ia */					
	a1=0;
	a2=0;
	a3=0;  
	a4=0;
	a5=0;
	a6=0;
	a7=0;
	for(i=0;i<4;i++)
	{
		a0=a0+(ADUa[i]-0x01FF)*(ADIa[i]-0x01FF);
		a1=a1+(ADUa[i+4]-0x01FF)*(ADIa[i+4]-0x01FF);
		a2=a2+(ADUa[i+8]-0x01FF)*(ADIa[i+8]-0x01FF);
		a3=a3+(ADUa[i+12]-0x01FF)*(ADIa[i+12]-0x01FF); 
		a4=a4+(ADUa[i+16]-0x01FF)*(ADIa[i+16]-0x01FF);
		a5=a5+(ADUa[i+20]-0x01FF)*(ADIa[i+20]-0x01FF);
		a6=a6+(ADUa[i+24]-0x01FF)*(ADIa[i+24]-0x01FF);
		a7=a7+(ADUa[i+28]-0x01FF)*(ADIa[i+28]-0x01FF);
	}
	
	data=((a0>>5)+(a1>>5)+(a2>>5)+(a3>>5)+(a4>>5)+(a5>>5)+(a6>>5)+(a7>>5));
	data=(data*Iaxzh)>>7;	
	P=(data*Uaxzh)>>6;
//	P=(P*bianyaqi)>>10;
	P=P/100;

	S=UaAv*IaAv;
	S=S/100;
	Factor=P*100/S; 
	Q=qsqrt(S*S-P*P);					/* 对无符号型长整数开平方 */
	a0=0; 
	k=32;                                                      
	for(i=0;i<k;i++)
	{
		k1=k>>2;
		if((i+k1)<k)
		{	
			
			a0=a0+(ADUa[i]-0x01FF)*(ADIa[i+(k>>2)]-0x01FF); 
			}
		else 
		{k1=(k*3)>>2;
			a0=a0+(ADUa[i]-0x01FF)*(ADIa[i-((k*3)>>2)]-0x01FF);
			}
	}
	
	Q1=(a0*Iaxzh)>>7;	
	Q1=(Q1*Uaxzh)>>10;
	Q1=Q1/100; 

	S1=(qsqrt((P/100)*(P/100)+(Q1/100)*(Q1/100)))*100;


}  
// AD中断服务子程序
void  interrupt  adINT()
{
  
   asm(" clrc      SXM");//抑制符号位扩展
   if(adpoint<32)
   {
	//	ADIa[adpoint]=RESULT0>>6; 
		ADUa[adpoint]=RESULT0>>6; 
   		adpoint++;
   	}
   	else
   	{
   		Youxiaozhi();
		Xiebo();
  		PowerY();
   		adpoint=0;
   	  
   	}
   ADCTRL2=ADCTRL2|0X4200;	// 复位SEQ1,且清除INT FLAG SEQ1标志写"1"清0
   enable();//开总中断
    return;
}  


/************************************************************************/
/************************************************************************/
/*主程序*/
main()
{
   disable();	// 禁止总中断
   initial();	// 系统初始化
   ADINIT();	// AD初始化子程序
   enable(); 	// 开总中断
   ADSOC();	// 启动AD转换
    while(1)
   {
      
  ;                            
   }	//死循环,在实际的工程应用中在此可以利用A/D转换的结果用于一些运算
}

⌨️ 快捷键说明

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