首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

C8051F的AD采集交流电程序

C8051F的AD采集交流电程序

/*******************************************************************

C8051F020 AD采集 2006.09.26

*******************************************************************/

/************************预定义************************************/
#i nclude <C8051F020.h>
#i nclude <intrins.h>
#i nclude <stdio.h>
#i nclude <math.h>
/*******************************************************************

定义IO口和变量

*******************************************************************/
sbit LCDBUSY = P3^0; //LCD忙信号位
sbit REQ = P3^1; //LCD请求信号位
sbit RES = P3^2; //LCD复位信号位
sfr16 ADC0 = 0xbe;
unsigned int xdata ADC0_data1[800]; //AD通道一采集数据存放数组
unsigned int xdata ADC0_data2[800]; //AD通道二采集数据存放数组
unsigned int data ADC0_data_n; //AD采集次数
unsigned int data ADC0_data_n1; //通道一采集次数
unsigned int data ADC0_data_n2; //通道二采集次数
bit m;//AD采集完标志
/*******************************************************************

函数声明

*******************************************************************/

void Sjcl(void);//AD采集完100次数据处理函数

void ADC0_ISR(void);//ADC0中断函数声明

void write_data(unsigned char writedata);//写数据到LCD

void send_ascii8(unsigned char x,unsigned char y,unsigned char ascii);//显示8*8ASCII

/********************************************************************

子函数定义

********************************************************************/

void delay_us(int timer)//us沿时
{
timer*=20;//时钟周期调整
for(;timer>0;timer--)
_nop_();
}

void delay_ms(int i)//ms沿时
{
for(;i>0;i--)
delay_us(1000);
}

void lcd_init(void)//lcd初始化
{
RES=0;
delay_ms(20);
RES=1;
REQ=0;
LCDBUSY=0;
}
/********************************************************************

系统初始化函数

********************************************************************/
void UART_Init()
{
SCON0 = 0x50; //使能UART0并允许接收
}


void Timer_Init()

{
CKCON = 0x10;
TCON = 0x40;
TMOD = 0x20;
TH1 = 0xB8; //用定时器3做为AD0的启动转换标志每100us启动一次采集,


TMR3CN = 0x04; //使用系统时钟12分频做为定时器3的时钟源(22.1184M)
TMR3RLL = 0xd1; //T1使用系统时钟并产生9600的波特率用与UART0
TMR3RLH = 0xFF;
TMR3L = 0xd1;
TMR3H = 0xFF;

}

void ADC_Init()
{
ADC0CF = 0x40; //ADC0为定时器3益处采集方式,时钟频率为2.5M,
ADC0CN = 0x04; //增益为1,数据为右对齐方式
AMX0SL=0X00;
}

void Voltage_Reference_Init()
{
REF0CN = 0x03; //ADC0的参考电压来自内部增益
}

void Port_IO_Init() //IO口初始化

{
P0MDOUT = 0x01; //P0.0,P0.1做为UART0的通信引脚,其中TX0为推拉方式
P3MDOUT = 0x06; //P3.0为BUSY读取引脚,设为开漏方式
//P3.1为请求标志位设为推拉方式
//P3.2为复位信号脚设置为推拉方式
P74OUT = 0x03; //P4为液晶数据线设为推拉方式
XBR0 = 0x04;
XBR2 = 0x40;
}

void Oscillator_Init()//使用外部晶振22.1184M
{
int i = 0;
OSCXCN = 0x67;
for (i = 0; i < 3000; i++); // Wait 1ms for initialization
while ((OSCXCN & 0x80) == 0);
OSCICN = 0x08;
}

void Interrupts_Init()
{
EIE2 = 0x02; //允许ADC0中断
}

void Init_Device(void)
{
Timer_Init();
UART_Init();
ADC_Init();
Voltage_Reference_Init(); //初始化主程序
Port_IO_Init();
Oscillator_Init();
Interrupts_Init();
}
//end init//

/****************************************************************************

主函数定义开始

*****************************************************************************/

void main(void)
{
WDTCN=0xde;
WDTCN=0xad; //关看门狗
Init_Device();
lcd_init();
AD0EN=1;
delay_ms(5);
EA=1;
TI0=1;
while(1)
{
if(m==1)
{

m=0;
TMR3CN&=0xFB; //关定时器3
Sjcl(); //处理数据
TMR3CN|=0X04; //开定时器3
}
}
}
/****************************************************************************

ADC0中断处理

****************************************************************************/

void ADC0_ISR(void) interrupt 15
{
ADC0CN&=0xdf;
if(ADC0_data_n%2==0)
{
ADC0_data1[ADC0_data_n1] = ADC0;
ADC0_data_n1++;
AMX0SL = 0x01;
}

else
{
ADC0_data2[ADC0_data_n2]=ADC0;
ADC0_data_n2++;
AMX0SL=0x00;
}

ADC0_data_n++;
if(ADC0_data_n==1600)//两路采集完800点
{
m=1;
}
}

/****************************************************************************

数据采集完处理函数

****************************************************************************/

void Sjcl(void)
{
/*unsigned int j;*/
/*unsigned char xdata lcd_senddata[4];//四位LCD显示数据*/
unsigned int i;
unsigned long data ADC0_dataadd=0;//采集完毕的累加计算值
unsigned long data a=0;
unsigned long data b=0;
float data c;
float data d;
float data P_dataadd=0;
float data U=0;
float data I=0;
float data S=0;
float data P=0;
float data Q=0;
float data COSg=0;
//通道一数据处理
for(i=0;i<=ADC0_data_n1;i++)
{
a=ADC0_data1;
ADC0_dataadd=ADC0_dataadd+a*a;

}

U=ADC0_dataadd/ADC0_data_n1;//取平均值
U=sqrt(U);//取平方根值
U=(U*2.451)/0x0fff;//计算实际电压值

//通道二数据处理
ADC0_dataadd=0;
for(i=0;i<=ADC0_data_n2;i++)
{
a=ADC0_data2;
ADC0_dataadd=ADC0_dataadd+a*a;

}
I=ADC0_dataadd/ADC0_data_n2;//取平均值
I=sqrt(I);//取平方根值
I=(I*2.451)/0x0fff;//计算实际电压2值
S=U*I;
for(i=0;i<=ADC0_data_n1;i++) //计算P值
{
c=((float)ADC0_data1*2.451)/0x0fff;
d=((float)ADC0_data1*2.451)/0x0fff;
P_dataadd=P_dataadd+c*d;
}
P=P_dataadd/ADC0_data_n1;//取平均值
Q=sqrt(S*S-P*P);//计算Q值
COSg=P/S;//计算cosg值
printf("************************************\n");
delay_ms(10);
printf("U=%.3fv I=%.3fv\n",U,I);
delay_ms(10);
printf("S=%.3fw P=%.3fw Q=%.3fw\n",S,P,Q);
delay_ms(10);
printf("COSg=%.3f\n",COSg);
delay_ms(10);
ADC0_data_n=0;
ADC0_data_n1=0;
ADC0_data_n2=0;
}
返回列表