#include<reg52.h> /*加载头文件*/
#include<intrins.h> /*加载头文件*/
#include<math.h> /*加载头文件*/
#include<string.h> /*加载头文件*/
#include<stdio.h> /*加载头文件*/
#define uchar unsigned char/*定义无符号字符型*/
#define uint unsigned int/*定义无符号整型*/
#define MyAddr 0x01/*定义地址为1*/
#define Start 0x40 /*定义字头,一个ASCI I */
#define End 0x0d /*定义字尾CR,一个ASCI I */
#define Read 0x00/*上位机读*/
#define Write 0x01/*上位机写*/
bit recok=0;/*消息帧接收结束*/
bit startrec=0;/*开始接收消息帧*/
sbit PWM=P1^2;
sbit key_in=P1^4;
sbit key_up=P1^5;
sbit key_down=P1^6;
sbit key_out=P1^7;
sbit DS = P2^1 ;
sbit dula=P2^6;
sbit wela=P2^7;
sbit lcden=P3^4;
sbit lcdrs=P3^5;
uchar dat[10]={1,2,3,4,5,6,7,8}; /*定义组态王中寄存器空间*/
uchar xdata recbuf[20];/*接收数据数组,外部数组*/
uchar xdata sendbuf[10]={0x40,0x30,0x31,0x30,0x31,0,0,0,0,0x0d};/*发送组态王读取数据*/
uchar xdata Answer [8]={0x40,0x30,0x30,0,0,0,0,0x0d};/*下位机应答信息帧数组*/
uchar count=0;/*接收字头字尾间数据个数*/
uchar flag=0;/*单片机接收到字头标志*/
uchar send_temp;
uchar flag1,timer_1,flag_time,uu;
uchar high_time,keyflag=0,count1=0;//占空比调节参数
uchar a,tm1,bai,shi,ge;
uchar xdata table1[]="present:";
uchar xdata table2[]="set_temp:";
uint rin; // PID Feedback (Input)
uint s,temp,tm,m; // variable of temperature
int i;
long int rout; // PID Response (Output)
long int set_temper;
float ff,set=20,set1=20;
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
};
struct PID spid; // PID Control Structure
////////////*****************************************DS18B20温度采集函数*******************************************/////////////////////////////
void delayms(uint xms)
{
uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
void write_com(uchar com)
{
lcdrs=0;
P0=com;
delayms(5);
lcden=1;
delayms(5);
lcden=0;
}
void write_date(uchar date)
{
lcdrs=1;
P0=date;
delayms(5);
lcden=1;
delayms(5);
lcden=0;
}
void delay(uint count) //delay
{
uint i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}
void dsreset(void) //send reset and initialization command
{
uint i;
DS=0;
i=103;
while(i>0)i--;
DS=1;
i=4;
while(i>0)i--;
}
bit tmpreadbit(void) //read a bit
{
uint i;
bit dat;
DS=0;i++; //i++ for delay
DS=1;i++;i++;
dat=DS;
i=8;while(i>0)i--;
return (dat);
}
uchar tmpread(void) //read a byte date
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
}
return(dat);
}
void tmpwritebyte(uchar dat) //write a byte to ds18b20
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //write 1
{
DS=0;
i++;i++;
DS=1;
i=8;while(i>0)i--;
}
else
{
DS=0; //write 0
i=8;while(i>0)i--;
DS=1;
i++;i++;
}
}
}
void tmpchange(void) //DS18B20 begin change
{
dsreset();
delay(1);
tmpwritebyte(0xcc); // address all drivers on bus
tmpwritebyte(0x44); // initiates a single temperature conversion
}
uint tmp() //get the temperature
{
float tt;
uchar a,b;
dsreset();
delay(1);
tmpwritebyte(0xcc);
tmpwritebyte(0xbe);
a=tmpread();
b=tmpread();
temp=b;
temp<<=8; //two byte compose a int variable
temp=temp|a;
tt=temp*0.0625;
temp=tt*10+0.5;
return temp;
}
////////////****************************************PID及定时器初始化函数*******************************************/////////////////////////////
void PIDInit (struct PID *pp)
{
memset ( pp,0,sizeof(struct PID));
}
void serial_init()
{
SCON=0x50;/*模式1,八位,接收使能*/
TMOD=0x21;/*定时器1,模式2*/
TH0=(65535-10000)/256;
TL0=(65535-10000)%256;
TH1=0xfd;/*波特率为9600,11.0592MHz*/
TL1=0xfd;
TR1=1;/*启动定时器*/
ET0=1;
TR0=1;
EA=1;/*中断使能*/
ES=1;/*串口中断使能*/
SM2=1;/*接收到停i1_位后接收中断才置1*/
dula=0;
wela=0;
lcden=0;
write_com(0x38);
write_com(0x0e);
write_com(0x06);
write_com(0x01);
high_time=0;
}
////////////****************************************组态王通信函数*******************************************/////////////////////////////////////
void uartsends(uchar buff[],uchar len)
{
uchar i;
for(i=0;i<len;i++)
{
SBUF=buff[i];
while(!TI);
TI=0;
}
}
uchar read_write_flag()
{
uchar temp;/*定义临时中间变量*/
if(recbuf[4]>0x40)
temp=(recbuf[4]-0x37)&0x0f;
else
temp=(recbuf[4]-0x30)&0x0f;
return temp;
}
uchar Dat_trans(uchar hight_v,uchar low_v)
{
uchar value,hight,low;//定义临时变量
if (hight_v>0x40)
hight=hight_v-0x37;
else
hight=hight_v-0x30;
if (low_v>0x40)
low=low_v-0x37;
else
low=low_v-0x30;
value=(hight&0x0f)<<4;
value+=(low&0x0f);
return value;
}
void write_inform(uchar dat)
{
uchar xordat,i,ctmp1,ctmp2;//定义临时变量
Answer[3]=dat;
Answer[4]=dat;
xordat=0;
for(i=1;i<5;i++)
xordat^=Answer[i];
send_temp=xordat;
ctmp1=(send_temp>>4)&0x0f;
if(ctmp1>9)
Answer[5]=ctmp1%9+0x40;
else
Answer[5]=ctmp1+0x30;
ctmp2=send_temp&0x0f;
if(ctmp2>9)
Answer[6]=ctmp2%9+0x40;
else
Answer[6]=ctmp2+0x30;
uartsends(Answer,8);
}
void Read_byte()
{
uchar ctmp1,ctmp2,xordat,i;//定义临时变量
send_temp=dat[Dat_trans(recbuf[7],recbuf[8])];
ctmp1=(send_temp>>4);
if(ctmp1>9)
sendbuf[5]=0x40+ctmp1%9;
else
sendbuf[5]=ctmp1+0x30;
ctmp2=send_temp&0x0f;
if(ctmp2>9)
sendbuf[6]=0x40+ctmp2%9;
else
sendbuf[6]=ctmp2+0x30;
xordat=0;//计算发送数据异或码
for(i=1;i<7;i++)
xordat^=sendbuf[i];
send_temp=xordat;
ctmp1=(send_temp>>4)&0x0f;
if(ctmp1>9)
sendbuf[7]=ctmp1%9+0x40;
else
sendbuf[7]=ctmp1+0x30;
ctmp2=send_temp&0x0f;
if(ctmp2>9)
sendbuf[8]=ctmp2%9+0x40;
else
sendbuf[8]=ctmp2+0x30;
uartsends(sendbuf,10);
}
bit check_CRC()
{
uchar xordat,i,ctmp1,ctmp2,temp;
if(((read_write_flag())&0x01)==Read)
temp=11;
else if(((read_write_flag())&0x01)==Write)
temp=13;
xordat=recbuf[1];
for(i=2;i<temp;i++)
xordat^=recbuf[i];//异或计算
ctmp1=xordat&0xf0;//取高4位
ctmp1>>=4;
ctmp1+=0x30;
ctmp2=xordat&0x0f;//取低四位
ctmp2+=0x30;
if((ctmp1==recbuf[temp])&&(ctmp2==recbuf[temp+1]))
return 1;//CRC校验正确则返回1
else return 0; //CRC校3错误则返回0
}
void Write_byte()
{
uchar temp;
temp=Dat_trans(recbuf[11],recbuf[12]);
dat[Dat_trans(recbuf[7],recbuf[8])]=temp;
write_inform('#');//上位机写数据正常应答
}
////////////****************************************PID算法函数*******************************************//////////////////////////////////
uint PIDCalc( struct PID *pp, uint NextPoint )
{
uint 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 compare_temper()
{
uchar i;
//spid.Proportion = dat[4]; // Set PID Coefficients
//spid.Integral = dat[5];
//spid.Derivative =dat[6];
spid.SetPoint = 20; // Set PID Setpoint
if(set<ff)
评论1