#include"c8051f020.h"
#include"intrins.h"
#include"my.h"
#include<string.h>
#include<stdio.h>
#define SYSCLK 22118400
#define SAMPLERATE 5000
xdata unsigned char text1[32]={"数控恒流源"};
xdata unsigned char text2[32]={"设定电流: 20mA"};
xdata unsigned char text3[32]={"实测电流: mA"};
xdata unsigned char text4[32]={"设定电流: 20mA"};
xdata unsigned char text5[32]={"设定的电流值过大"};
xdata unsigned char text6[32]={"请重新输入!"};
struct PID {
float SetPoint; // 设定目标Desired value
float Proportion; // 比例常数Proportional Const
float Integral; // 积分常数Integral Const
float Derivative; // 微分常数Derivative Const
float LastError; // Error[-1]
float PrevError; // Error[-2]
float SumError; // Sums of Errors
}sPID;
//struct PID sPID; /***PID控制结构体***/
float rOut; /***PID ***/
float rIn; /***PID ***/
unsigned long sum=0;
float vc0,vc1;
float DA_data;
xdata unsigned sample[200];
unsigned char flag=0;
//unsigned int Dliu;
unsigned char qw,bw,sw,gw;
void SysclkInit(void)
{
unsigned int i;
OSCXCN=0x67;
for(i=0;i<256;i++);
while(!(OSCXCN&0x80));
OSCICN=0x88;
}
void PortInit(void)
{
XBR2=0x40;
P0MDOUT=0xff;
P1MDOUT=0xff;
P2MDOUT=0xff;
P3MDOUT=0xff;
P74OUT=0xff;
}
void Delay(void)
{
unsigned char i;
for(i=0;i<100;i++);
}
void ADC0Init(void)
{
ADC0CN=0x04; //ADC0禁止;正常工作模式;定时器3溢出ADC0转换开始;ADC0转换数据右对齐
REF0CN=0x07; //使能温度传感器,片内VREF,和VREF输出缓冲器
AMX0SL=0x00; //选择AIN0作为ADC多路转换输出
ADC0CF=(SYSCLK/2500000)<<3; //ADC转换时钟2.5MHZ
ADC0CF&=~0x07; //PGA增益=1
EIE2&=~0x02; //禁止ADC0中断
AD0EN=1; //使能ADC0
}
void DAC1Init(void)
{
REF0CN=0x03;
DAC1CN=0x80;
}
void Timer3Init(int counts)
{
TMR3CN=0x02; //停止定时器3;清除TF3;使用系统时钟作为时基
TMR3RL=-counts; //初始化重装值
TMR3=0xffff; //立即开始重装
EIE2&=~0x01; //禁止定时器3中断
TMR3CN|=0x04; //启动定时器3
}
/*************PID计算部分**************/
unsigned long PIDCalc(struct PID*pp,double NextPoint)/*** ***/
{
float dError,Error ;
Error=pp->SetPoint-NextPoint ; /***偏差***/
pp->SumError+=Error ; /***积分***/
dError =pp->LastError -pp-> PrevError ; /***当前微分***/
pp->PrevError=pp-> LastError; /*** ***/
pp-> LastError=Error; /*** ***/
return( pp->Proportion *Error /***比例项***/
+pp->Integral * pp->SumError /***积分项***/
+pp->Derivative* dError ); /***微分项***/
}
/************初始化PID参数***************/
void PIDInit(struct PID*pp) /*** ***/
{
memset( pp,0,sizeof(struct PID)); /*** ***/
}
void Change(unsigned int i)
{
qw=i%10000/1000;
bw=i%1000/100;
sw=i%100/10;
gw=i%10;
}
void Fuzhi()
{
if(qw==0)
text2[10]=' ';
else
{
text2[10]=qw+0x30;
}
if (qw==0&&bw==0)
text2[11]=' ';
else
{
text2[11]=bw+0x30;
}
if (qw==0&&bw==0&&sw==0)
text2[12]=' ';
else
{
text2[12]=sw+0x30;
}
if (qw==0&&bw==0&&sw==0&&gw==0)
strcpy(text2,text4);
else
{
text2[13]=gw+0x30;
}
}
void DAC_calnum()
{
DA_data=((vc0-4.83)/2436.17)*4095;
}
void DAC_setnum()
{
DAC1L=(unsigned int ) DA_data;
DAC1H=((unsigned int)DA_data)>>8;
}
void ADC_getnum()
{
unsigned char j;
EA=1;
EIE2|=0x02;
while(!flag);
flag=0;
for(j=0;j<200;j++)
sum=sum+sample[j];
sum=sum/200;
if(Dliu<249)
vc1=(((float)sum)/4095)*2430+4.8-5.5;
else if(Dliu<749)
vc1=(((float)sum)/4095)*2430+4.8-6.8;
else if(Dliu<1050)
vc1=(((float)sum)/4095)*2430+4.8-7.9;
else if(Dliu<1450)
vc1=(((float)sum)/4095)*2433+4.8-10.6;
else if(Dliu<1650)
vc1=(((float)sum)/4095)*2433+4.8-11.8;
else
vc1=(((float)sum)/4095)*2435+4.8-15.7;
}
void ADC0_ISR(void) interrupt 15 using 3
{
static unsigned char i=0;
AD0INT=0; //清除ADC0转换结束标志
sample[i]=ADC0; //读和存储ADC0值
i++;
if(i==200)
{
flag=1;
i=0;
EA=0;
EIE2&=~0x02;
}
}
void main(void)
{
float Idealv;
WDTCN=0xde;
WDTCN=0xad;
SysclkInit();
PortInit();
Timer3Init(SYSCLK/SAMPLERATE);
ADC0Init();
DAC1Init();
PIDInit(&sPID); /***结构初始化***/
sPID. Proportion=0.0; /***PID参数设置***/
sPID.Integral=1.0; /*** ***/
sPID.Derivative=0.0; /*** ***/
sPID.SetPoint=0.0; /*** ***/
vc0=20*1.18974;
Idealv=vc0;
DAC_calnum();
DAC_setnum();
Delay();
ADC_getnum();
LcdInit();
LcdClear();
LcdShow(1,1,text1);
LcdShow(2,0,text2);
LcdShow(3,0,text3);
while(1)
{
keydown();
if(Fkey)
{
Fkey=0;
Change(Dliu);
Fuzhi();
if(Dliu>=2490)
{
LcdClear();
LcdShow(1,1,text1);
LcdShow(2,0,text2);
LcdShow(3,0,text5);
LcdShow(4,0,text6);
Dliu=0;
vc0=20*1.18974;
Idealv=vc0;
DAC_setnum();
Delay();
ADC_getnum();
}
else
{
if(!Dliu)
vc0=20*1.18974;
else
vc0=(float)Dliu*1.18974;
Idealv=vc0;
DAC_setnum();
Delay();
ADC_getnum();
LcdClear();
LcdShow(1,1,text1);
LcdShow(2,0,text2);
LcdShow(3,0,text3);
DAC_calnum();
DAC_setnum();
Delay();
ADC_getnum();
}
if(Clr==1)
{
Clr=0;
Dliu=0;
}
}
ADC_getnum();
/* if(vc1-Idealv>0.8)
{
DA_data=DA_data-1.0;
DAC_setnum();
Delay();
ADC_getnum();
}
if(Idealv-vc1>0.8)
{
DA_data=DA_data+1.0;
DAC_setnum();
Delay();
ADC_getnum();
}
*/
}
}
评论1