?? ad.c
字號:
// 該程序用于進(jìn)行A/D轉(zhuǎn)換的演示,A/D轉(zhuǎn)換的結(jié)果存于數(shù)足ADRESULT[16]中,
// 寄存器cesi用于測試每個A/D轉(zhuǎn)換的結(jié)果
#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計算結(jié)果的校驗系數(shù);
int adpoint=0;
long P,Q,S,P1,Q1,S1;
unsigned int Factor;
int output1[64],output2[64];
/******************和FFT計算,調(diào)用有關(guān)的參數(shù)及常數(shù)列表*****************/
#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,
};
/*****************************************************************
** 函數(shù)名: Xiebo()
** 功能描述:根據(jù)fft計算結(jié)果計算各相電壓3次、5次諧波的模值
** 作 者:嚴(yán)利平
** 日 期: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");
}
// 系統(tǒng)初始化子程序
void initial()
{
asm(" setc SXM"); // 符號位擴展有效
asm(" clrc OVM");//累加器中結(jié)果正常溢出
asm(" clrc CNF"); // B0被配置為數(shù)據(jù)存儲空間
SCSR1=0x83FE; // CLKIN=10M,CLKOUT=4*CLKIN=40M
WDCR=0x0E8; // 不使能看門狗,因為SCSR2中的WDOVERRIDE
// 即WD保護(hù)位復(fù)位后的缺省值為1,故可以用
// 軟件禁止看門狗
IMR=0x0001; // 允許INT1中斷
IFR=0x0FFFF; // 清除全部中斷標(biāo)志,"寫1清0"
PBDATDIR=0x0FF00; // IOPB端口設(shè)置為輸出方式
PADATDIR=PADATDIR&0x0FFEF; // IOPA4=0
PADATDIR=PADATDIR|0x1010; // IOPA4 設(shè)置為輸出方式,且IOPA4=1
PADATDIR=PADATDIR&0x0FFEF; // IOPA4=0
}
// AD初始化子程序
void ADINIT()
{
T4CNT=0X0000; // T4計數(shù)器清0
T4CON=0X170C; // T4為連續(xù)增計數(shù)模式,128分頻,且選用內(nèi)部時鐘源
T4PR=0X59; // 設(shè)置T4的周期寄存器 ,0.625ms中斷一次
GPTCONB=0X400; // T4周期中斷標(biāo)志觸發(fā)AD轉(zhuǎn)換
EVBIFRB=0X0FFFF; // 清除EVB中斷標(biāo)志,寫"1"清0
ADCTRL1=0X10; // 采樣時間窗口預(yù)定標(biāo)位ACQ PS3-ACQ PS0為0,
// 轉(zhuǎn)換時間預(yù)定標(biāo)位CPS為0,AD為啟動/停止模式,排
// 序器為級連工作方式,且禁止特殊的兩種工作模式
ADCTRL2=0X8405; // 可以用EVB的一個事件信號觸發(fā)AD轉(zhuǎn)換,
// 且用中斷模式1
MAXCONV=0X0F; // 16通道
CHSELSEQ1=0X3210;
CHSELSEQ2=0X7654;
CHSELSEQ3=0X0BA98;
CHSELSEQ4=0X0FEDC; // 轉(zhuǎn)換通道是0-15
}
// 啟動AD轉(zhuǎn)換子程序(通過啟動定時器4的方式間接啟動)
void ADSOC()
{
T4CON=T4CON|0X40; // 啟動定時器4
}
// 若是其它中斷則直接返回子程序
void interrupt nothing()
{
return;
}
/*****************************************************************
** 函數(shù)名: Youxiaozhi()
** 功能描述:根據(jù)32點采樣值計算測量電壓、電流有效值
** 作 者:嚴(yán)利平
** 日 期: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); /* 對無符號型長整數(shù)開平方 */
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中斷服務(wù)子程序
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; // 復(fù)位SEQ1,且清除INT FLAG SEQ1標(biāo)志寫"1"清0
enable();//開總中斷
return;
}
/************************************************************************/
/************************************************************************/
/*主程序*/
main()
{
disable(); // 禁止總中斷
initial(); // 系統(tǒng)初始化
ADINIT(); // AD初始化子程序
enable(); // 開總中斷
ADSOC(); // 啟動AD轉(zhuǎn)換
while(1)
{
;
} //死循環(huán),在實際的工程應(yīng)用中在此可以利用A/D轉(zhuǎn)換的結(jié)果用于一些運算
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -