#include<STC12C5A60S2.h>
#include "intrins.h"
#include <string.h>
#include <stdio.h>
/*#include "define.h"
#include "delay.h"
#include "lcd.h"
#include "ad.h"
#include "pid.h"
#include "pwm.h" */
/*……………………………………………… define.h…………………………….*/
#define uint unsigned int
#define uchar unsigned char
#define N 14
sbit pwmout=P3^7;
sbit lcden=P2^6;
sbit lcdrs=P2^4;
sbit lcdrw=P2^5;
//uchar a;
uchar code table[]="The Vol is:.V ";
/*…………………………………………..delay.h……………………………….*/
void delay(uint z) //12M晶振 毫秒级延时
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/*…………………………………………lcd 1602显示……………………………………*/
void write_com(uchar com) //写控制字
{
lcdrs=0;
delay(5);
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_data(uchar date) //写数据
{
lcdrs=1;
delay(5);
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void lcdinit() //lcd初始化
{
lcden=0;
lcdrw=0;
write_com(0x38);
write_com(0x01);
write_com(0x0e);
write_com(0x06);
}
void display(uchar add,uint num)
{
/*uchar i;
write_com(0x80);
for(i=0;i<11;i++) //显示字符
{
write_data(table[i]);
delay(1);
}
write_com(0x80+0x40); //显示电压数据
if(num/10000==0)
{
write_data(table[13]);
}
else
write_data(0x30+num/10000);
write_data(0x30+num%10000/1000);
write_data(table[11]);
write_data(0x30+num%1000/100);
write_data(0x30+num%100/10);
write_data(0x30+num%10);
write_data(table[12]);*/
if(add==1)
{
write_com(0x80);
write_data(0x30+num/10000);
write_data(0x30+num%10000/1000);
write_data(0x30+num%1000/100);
write_data(0x30+num%100/10);
write_data(0x30+num%10);
}
if(add==3)
{
write_com(0x80+0x07);
write_data(0x30+num/10000);
write_data(0x30+num%10000/1000);
write_data(0x30+num%1000/100);
write_data(0x30+num%100/10);
write_data(0x30+num%10);
}
if(add==2)
{
write_com(0x80+0x40);
write_data(0x30+num/10000);
write_data(0x30+num%10000/1000);
write_data(0x30+num%1000/100);
write_data(0x30+num%100/10);
write_data(0x30+num%10);
}
if(add==4)
{
write_com(0x80+0x40+0x06);
write_data(0x30+num/10000);
write_data(0x30+num%10000/1000);
write_data(0x30+num%1000/100);
write_data(0x30+num%100/10);
write_data(0x30+num%10);
}
if(add==5)
{
write_com(0x80+0x40+0x0b);
write_data(0x30+num/10000);
write_data(0x30+num%10000/1000);
write_data(0x30+num%1000/100);
write_data(0x30+num%100/10);
write_data(0x30+num%10);
}
}
/*…………………………………..A/D程序…………………………………….*/
void AD_init() //AD转化初始化
{
P1ASF=0x01;
P1M0=0x03;
P1M1=0x03; //P1.0为开漏模式,用来A/D采集
ADC_CONTR=0xe0;
delay(10);
}
int GetAD(uchar channel)
{
uchar AD_finished=0;
int result;
ADC_RES=0;
ADC_RESL=0;
ADC_CONTR|=channel;
delay(1); //此延时函数很重要
ADC_CONTR|=0x88;//启动AD
_nop_();
_nop_();
_nop_();
_nop_();
while(AD_finished==0)
{
AD_finished=(ADC_CONTR&0x10); //flag=1,AD转换完成。
}
result=ADC_RES*4+ADC_RESL;
ADC_CONTR&=0xe7;
return(result);
}
float AD_av(uchar channel)
{
float Val_av=0;
uchar num;
for(num=100;num>0;num--) //多次采样取平均值
{
Val_av+=GetAD(channel);
}
Val_av/=100;
Val_av=Val_av*4.90/1024.0;
return(Val_av);
}
/*float ad_ filter(uchar channel) //防脉冲干扰滤波
{
uchar count,i,j;
uint value_buf[N]; //缓冲N个采样值的存储变量
uint sum=0;
uint temp;
float f_result;
for(count=0;count<N;count++)
{
value_buf[count]=GetAD(channel);
_nop_();
}
for(j=0;j<N-1;j++)
{
for(i=0;i<N-j;i++)
{
if(value_buf[i]>value_buf[i+1])
{
temp=value_buf[i];
value_buf[i]=value_buf[i+1];
value_buf[i+1]=temp;
}
}
}
for(count=1;count<N-1;count++) //去掉一个最大值和一个最小值
{
sum+=value_buf[count];
}
f_result=sum/(N-2);
f_result=f_result*5/1024; //参考电压为5V
return(f_result);
} */
/*………………………………………………pwm模块……………………….*/
void pwm_init()
{
AUXR=0x80; //T0定时器设置为1T模式 T2工作在12T模式
CMOD=0x05; //定时器0的溢出,可以实现可调频率的PWM输出
CL=0x00;
CH=0x00;
TMOD=0x02; //定时器1工作在方式二
TH0=0xfd;
TL0=0xfd;
TR0=1; //定时器0开始定时
}
void PCA_Interrupt(void) interrupt 7 //PCA定时器中断
{
if(CCF0) CCF0=0;
if(CCF1) CCF1=0; //软件清零
if(CF) CF=0; //软件清零
}
typedef struct PID {
double SetPoint; // 设定目标 Desired Value
double Proportion; // 比例常数 Proportional Const
double Integral; // 积分常数 Integral Const
double Derivative; // 微分常数 Derivative Const
double LastError; // Error[-1]
double PrevError; // Error[-2]
double PrePrevError; // Error[-3]
double SumError; // Sums of Errors
} PID;
struct PID SPID;
/*=======================初始化的PID结构 ===========================*/
void PID_init (PID *pp)
{
memset ( pp,0,sizeof(PID));
}
/*========================PID计算部分===============================*/
/*double PIDCalc( PID *pp, double NextPoint ) //采用增量式PID算法
{
double pError,dError,Error;
Error = pp->SetPoint - NextPoint; // 偏差
pError= pp->LastError - pp->PrevError;
dError = pp->LastError - 2*pp->PrevError + pp->PrePrevError; // 当前微分
pp->PrePrevError=pp->PrevError;
pp->PrevError = pp->LastError;
pp->LastError = Error;
return (pp->Proportion *pError // 比例项
+ pp->Integral * Error // 积分项
+ pp->Derivative * dError // 微分项
);
} */
double PIDCalc( PID *pp, double NextPoint )
{
double 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 // 微分项
);
}
/*-------------------------主函数----------------------------------------------------------*/
void main()
{
float ad1,ad2;
int Rout; // PID响应(输出) PID Response (Output)
float Rin,Vin;
uint a1,a2,Ve,Ve_buck,Ve_boost;
lcdinit();
AD_init();
pwm_init(); // PID控制结构 PID Control Structure
PID_init ( &SPID ); // 初始化结构Initialize Structure
SPID.Proportion = 10; // 设置PID系数
SPID.Integral = 6.5;
SPID.Derivative = 0.8;
SPID.SetPoint = 1.82; // 设置PID设定值 Set PID Setpoint
CCAPM0=0x42;
评论15