📄 ad.c
字号:
#include "register.h"
int i=0X00,AD0,AD1,ADIa[32];
//int Sint[32]={0,200,391,568,723,851,945,1003,1023,1003,945,851,723,568,391,200,0,-200,-391,-568,-723,-851,-945,-1003,-1023,-1003,-945,-851,-723,-568,-391,-200};
//int Cost[32]={1023,1003,945,851,723,568,391,200,0,-200,-391,-568,-723,-851,-945,-1003,-1023,-1003,-945,-851,-723,-568,-391,-2000,200,391,568,723,851,945,1003};
int Sint[16]={0,392,724,946,1024,946,724,392,0,-392,-724,-946,-1024,-946,-724,-391}; //富式算法SIN表,扩大了4095倍
int Cost[16]={1024,946,724,392,0,-392,-724,-946,-1024,-946,-724,-391,0,392,724,946 };
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 ADUa[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 Ua1xzh=150,Ia1xzh=5;
unsigned int Ua1,Ia1;
int ADPoint=0;
int ADUa1[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int ADIa1[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
signed long Ua1R=0,Ua1I=0,Ia1R=0,Ia1I=0,R1,R2,I1,I2;
long P,Q,S;
unsigned Factor;
/*****************************************************************
** 函数名: BHJS()
** 功能描述:保护基波参数计算子程序
** 出 口:
** 作 者:严利平
** 日 期:2003年1月22日
****************************************************************/
void BHJS()
{ unsigned int k;
unsigned int t1;
unsigned long d;
signed long data,data1;
// signed long R,I;
signed long a1,a2,a3,a4,a5;
signed long IabR,IabI,IbcR,IbcI;
//20030214 k=ADPoint/2;
k=ADPoint>>1;
// k=ADPoint; //1个周期采16点
data=AD0-ADUa1[k]; // X(k)-X(k-16)
ADUa1[k]=AD0; //保存新的X(k)
data1=data*Sint[k];
Ua1R+=data1; //保存通道实部
data1=data*Cost[k];
Ua1I+=data1; // 保存通道虚部
R1=Ua1R>>13;
I1=Ua1I>>13;
d=R1*R1+I1*I1;
d=qsqrt(d);
d=(d*Ua1xzh)>>9;
Ua1=(unsigned int)d; //求Ua1的保护基波分量
data=AD1-ADIa1[k]; // X(k)-X(k-16)
ADIa1[k]=AD1; //保存新的X(k)
data1=data*Sint[k];
Ia1R+=data1; //保存通道实部
data1=data*Cost[k];
Ia1I+=data1; // 保存通道虚部
R2=Ia1R>>13;
I2=Ia1I>>13;
d=R2*R2+I2*I2;
d=qsqrt(d);
d=(d*Ia1xzh)>>9;
Ia1=(unsigned int)d; //求Ua1的保护基波分量
return;
}
/*****************************/
void power()
{
P=(Ua1R>>13)*(Ia1R>>13)+(Ua1I>>13)*(Ia1I>>13);
P=(((((P*Ia1xzh)>>9)*Ua1xzh*100))>>9);
Q=(Ua1I>>13)*(Ia1R>>13)-(Ia1I>>13)*(Ua1R>>13);
Q=(((((Q*Ia1xzh)>>9)*Ua1xzh*100))>>9);
S=(qsqrt((P/100)*(P/100)+(Q/100)*(Q/100)))*100;
Factor=P*100/S;
}
// 屏蔽中断子程序
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;
}
// AD中断服务子程序
void interrupt adINT()
{
asm(" clrc SXM");//抑制符号位扩展
if(ADPoint<32)
{
// ADIa[ADPoint]=RESULT0>>6;
// ADUa[ADPoint]=RESULT0>>6;
// AD0=RESULT0>>6;
AD0=ADUa[ADPoint];
AD1=ADIa[ADPoint];
if((ADPoint%2)==0)BHJS();
ADPoint++;
}
else
{
power();
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 + -