今天给各位分享pid软件设计的知识,其中也会对pid应用实例进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
用单片机设计pid水温传感器用什么软件仿真
你已经很轻松了 不需要做板 随便抄抄都可以过了 我还要 做板呢 自己弄吧
SW里管道设计PID文件从哪里来
pid专用软件。
随着SolidWorks布管功能在三维管道设计中的广泛应用,开发了运行于AutoCAD图形环境的专用pid,可以下载pid软件使用。
SolidWorks公司成立于1993年,由PTC公司的技术副总裁与CV公司的副总裁发起,总部位于马萨诸塞州的康克尔郡(Concord,Massachusetts)内,当初的目标是希望在每一个工程师的桌面上提供一套具有生产力的实体模型设计系统。从1995年推出之一套SolidWorks三维机械设计软件至2010年已经拥有位于全球的办事处,并经由300家经销商在全球140个国家进行销售与分销该产品。1997年,Solidworks被法国达索(Dassault Systemes)公司收购,作为达索中端主流市场的主打品牌。
通用数字PID调节器设计
PID调节器主控部分包括以下几个部分:单片机部分、A/D转换部分、D/A转换部分、稳压部分、数字输入输出部分以及串口通信部分。
D1:内部设定点信号灯
S1:内部设定点和外部设定点转换开关
D2:手动信号灯
S2:手动自动转换开关
D3:实际值X显示信号灯
D4:设定值W显示信号灯
S3:参数修改以及实际值和设定值显示转换开关
D5:超过限定值信号灯
D6:低于限定值信号灯
S4:设定值增加按钮
S5:设定值减少按钮
S6:修改手动变量按钮
S7:修改手动变量按钮
附录[1] 主程序—MAIN.C
#include"adconver.h"
#include"delay.h"
#include"dis7281.h"
#include"STC12C5410AD.H"
#include"main.H"
#include"subkey0.h"
#include"subkey1.h"
#include"subkey2.h"
#include"subkey3.h"
#include"subkey4.h"
#include"subkey5.h"
#include"subkey6.h"
bit insertsetframe=1;//内部设定标志位
bit handframe=1;//手动设定标志位
bit improvedisframe=0;//实际值标志位
bit shineframe=0;//判断是不是之一次开机停止4LED的闪烁
bit canshuframe=0x00;//参数标志位
unsigned char circleframe=0x00;//参数循环变量
unsigned char channelframe=0x00;//通道标志位
unsigned char ledframe=0xfc;//LED灯管状态
unsigned char times=0x00;//记数位
unsigned char readkey;
unsigned int setvalue=0x00;//设定值
unsigned char outputvalue=0x00;//输出值
unsigned int limup=0x270f;//实际值上限
unsigned int limdown=0x00;//实际值下限
unsigned int a1=0x270f;//上限报警值
unsigned int a2=0x00;//下限报警值
unsigned int cp=0x00;//P参数
unsigned int ci=0x00;//I参数
unsigned int cd=0x00;//D参数
unsigned char led[6];//LED值公共
main()
{
unsigned int tmr;
unsigned char keynumber;
for (tmr=0;tmr0xffff;tmr++);
write7281(0x12,0x80);
write7281(0x10,0xf0);
write7281(0x00,0xc8);
write7281(0x14,0x1b);
write7281(0x14,0x2e);
write7281(0x15,0x30);
write7281(0x15,0x40);
write7281(0x15,0x50);
write7281(0x06,0xfc);
while(1)
{
while(!key)
{
keynumber=read7281(0x13);
switch(keynumber)
{
case 0x00:
subkey0();break;
case 0x01:
subkey1();break;
case 0x02:
subkey2();break;
case 0x03:
subkey3();break;
case 0x04:
subkey4();break;
case 0x05:
subkey5();break;
case 0x06:
subkey6();break;
default:
break;
}
}
}
}
附录[2] S1模块的程序—SUBKEY0.C
#include"delay.h"
#include"dis7281.h"
#include"STC12C5410AD.H"
#include"main.H"
#include"subkey0.h"
void subkey0()
{
if(insertsetframe==1)
{
insertsetframe=0;
ledframe|=0x01;
write7281(0x06,ledframe);
}
else
{
insertsetframe=1;
ledframe=0xfe;
write7281(0x06,ledframe);
}
}//更改内部设定和外部设定的状态,并将相应的状态位进行更改,并更改状态灯
附录[3] S2模块的程序—SUBKEY1.C
#include"delay.h"
#include"dis7281.h"
#include"STC12C5410AD.H"
#include"main.H"
#include"subkey1.h"
void subkey1()
{
if(handframe==1)
{
handframe=0;
ledframe|=0x02;
write7281(0x06,ledframe);
}
else
{
handframe=1;
ledframe=0xfd;
write7281(0x06,ledframe);
}
} //更改手动自动状态,改变相应的状态位,更改相应的状态灯
附录[4] S3模块的程序—SUBKEY2.C
#include"delay.h"
#include"dis7281.h"
#include"STC12C5410AD.H"
#include"main.H"
#include"subkey2.h"
#include"adconver.h"
#include"subkey0.h"
#include"subkey1.h"
#include"hdconver.h"
#include"subkey3.h"
#include"subkey4.h"
#include"pid.h"
#include"daconver.h"
void subkey2()
{
if(shineframe==0)
{
write7281(0x10,0xff);
shineframe=1;
}
else
{
skey2();
}
}
void skey2(void)
{ // canshuframe=1;
write7281(0x18,0x17);
switch(circleframe)
{
case 0x00: ledframe|=0x0c;
write7281(0x06,ledframe);
circleframe+=1;
hdconver(limup);//4LED显示上限值
dis4led();
write7281(0x14,0x41);
write7281(0x14,0x5C); //写入2LEDHI
break;
case 0x01: circleframe+=1;
hdconver(limdown);//4LED显示下限值
dis4led();
write7281(0x14,0x40);
write7281(0x14,0x5d); //写入2LEDLO
break;
case 0x02: circleframe+=1;
hdconver(a1);//4LED显示上限报警
dis4led();
write7281(0x14,0x41);
write7281(0x15,0x5a); //写入2LEDA1
break;
case 0x03: circleframe+=1;
hdconver(a2);//4LED显示下限报警
dis4led();
write7281(0x14,0x42);
write7281(0x15,0x5a); //写入2LEDA2
break;
case 0x04: circleframe+=1;
hdconver(cp);//4LED显示P参数
dis4led();
write7281(0x14,0x4e);
write7281(0x14,0x5f); //写入2LEDP
break;
case 0x05: circleframe+=1;
hdconver(ci);//4LED显示I参数
dis4led();
write7281(0x14,0x41);
write7281(0x14,0x5f); //写入2LEDI
break;
case 0x06: circleframe+=1;
hdconver(cd);//4LED显示D参数
dis4led();
write7281(0x15,0x4d);
write7281(0x14,0x5f); //写入2LEDI
break;
case 0x07: improvedisframe=0;
ledframe=(ledframe|0x08)0xfb;
circleframe+=1;
adconver();
write7281(0x14,0x40);
write7281(0x14,channelframe);
write7281(0x06,ledframe);
break;
case 0x08: improvedisframe=1;
ledframe=(ledframe|0x04)0xf7;
circleframe=0;
pidcf();
daconver();
hdconver(setvalue);
dis4led();
write7281(0x06,ledframe);
break;
default:
break;
}
}//按相应的S3改变不同的参数
附录[5] S4模块的程序—SUBKEY3.C
#include"delay.h"
#include"dis7281.h"
#include"STC12C5410AD.H"
#include"main.H"
#include"subkey3.h"
#include"subkey2.h"
#include"hdconver.h"
void subkey3()
{
switch(circleframe)
{
case 0x01:limup=add1(limup);
break;
case 0x02:limdown=add1(limdown);
break;
case 0x03:a1=add1(a1);
break;
case 0x04:a2=add1(a2);
break;
case 0x05:cp=add1(cp);
break;
case 0x06:ci=add1(ci);
break;
case 0x07:cd=add1(cd);
break;
case 0x00:setvalue=add1(setvalue);
break;
default:
break;
}
}
unsigned int add1(unsigned int value)
{
ledframe|=0x20;//关掉下限报警
write7281(0x06,ledframe);
if(value==9999)
{
ledframe=0xef;//打开上限报警灯
write7281(0x06,ledframe);
write7281(0x06,ledframe);
}
else
{
value+=1;
}
hdconver(value);
dis4led();
return(value);
}
附录[6] S5模块的程序—SUBKEY4.C
#include"delay.h"
#include"dis7281.h"
#include"STC12C5410AD.H"
#include"main.H"
#include"subkey4.h"
#include"subkey2.h"
#include"hdconver.h"
void subkey4()
{
switch(circleframe)
{
case 0x01:limup=sub1(limup);
break;
case 0x02:limdown=sub1(limdown);
break;
case 0x03:a1=sub1(a1);
break;
case 0x04:a2=sub1(a2);
break;
case 0x05:cp=sub1(cp);
break;
case 0x06:ci=sub1(ci);
break;
case 0x07:cd=sub1(cd);
break;
case 0x00:setvalue=sub1(setvalue);
break;
default:
break;
}
}
unsigned int sub1(unsigned int value)
{
ledframe|=0x10;//关掉上限报?
write7281(0x06,ledframe);
if(value==0)
{
ledframe=0xdf;//打开上限报警灯
write7281(0x06,ledframe);
}
else
{
value-=1;
}
hdconver(value);
dis4led();
return(value);
}
附录[7] S6模块的程序—SUBKEY5.C
#include"delay.h"
#include"dis7281.h"
#include"STC12C5410AD.H"
#include"main.H"
#include"subkey5.h"
#include"hdconver.h"
void subkey5()
{
if(improvedisframe==0)
{
channelframe=0x00;
write7281(0x15,0x40);
write7281(0x15,0x50);//若现在状态为实际值,则改变通道状态并显示现在状态为00
}
else
{
if(handframe==1)
{
ledframe|=0x10;//关掉上限报警灯
write7281(0x06,ledframe);
if(outputvalue==0x00)
{
ledframe=0xdf;//打开下限报警灯
write7281(0x06,ledframe);
}
else
{
outputvalue-=1;
hdconver2(outputvalue);
}
dis2led();
}
}
}
附录[7] S7模块的程序—SUBKEY6.C
#include"delay.h"
#include"dis7281.h"
#include"STC12C5410AD.H"
#include"main.H"
#include"subkey6.h"
#include"hdconver.h"
void subkey6()
{
if(improvedisframe==0)
{
channelframe=0x01;
write7281(0x15,0x41);
write7281(0x15,0x50);//若现状态为实际值,则2LED显示为01
}
else
{
if(handframe==1)
{
ledframe|=0x20;//关掉下限报警灯
write7281(0x06,ledframe);
if(outputvalue==99)
{
ledframe=0xef;//打开上限报警档?
write7281(0x06,ledframe);
}
else
{
outputvalue+=1;
hdconver2(outputvalue);
}
}
dis2led();
}
}
附录[8] A/D转换模块的程序—ADCONVER.C
#include"STC12C5410AD.H"
#include"adconver.H"
#include"delay.h"
#include"main.h"
#include"dis7281.h"
#include"hdconver.h"
void adconver()
{ unsigned char adchanne=0xe0;//设置P1的0.1位为AD输入通道
ADC_CONTR=(0x80|ADC_CONTR)+channelframe;//开启AD模拟电源
delay(1000);
P1M0=0x03;
P1M1=0x03;//设置通道为开漏模式
ADC_CONTR=adchanne+channelframe;//设置AD转换通道
delay(22);
ADC_DATA=0x00;
ADC_LOW2=0x00;//清除数据口
ADC_CONTR|=0x08;//开启AD端口
while(!(ADC_CONTR0x10)){};//等待AD转换完成
ADC_CONTR=0xe7;//停止AD转换
P1M0=0xfd;
P1M1=0xfd;//设置P1口为普通IO模式
addis();
}
void addis()
{
unsigned int addata;
double liangch;
liangch=(limup-limdown)/100;
addata=ADC_DATA+(ADC_LOW20x03)*1024;
liangch=liangch/1023*addata;
addata=(unsigned int)liangch;
if(addataa1)
{
ledframe=0xef;//打开上限报警灯
write7281(0x06,ledframe);
}
if(addataa2)
{
ledframe=0xdf;//打开上限报警灯
write7281(0x06,ledframe);
}
hdconver(addata);
dis4led();
}
附录[8] D/A转换模块的程序—DACONVER.C
#include"delay.h"
#include"STC12C5410AD.H"
#include"main.H"
#include"daconver.h"
*** it TLV5618_SCLK=P1^7;
*** it TLV5618_DIN=P1^5;
*** it TLV5618_CS=P1^4;
void mDelay(unsigned int a)
{unsigned int f;
for(f=0;fa;f++);
}
void TLV5618 (unsigned int da)
{
unsigned int i;
unsigned int dat;
dat= da|0xc000;
TLV5618_CS=0;
TLV5618_SCLK=0;
for(i=0;i16;i++)
{
TLV5618_DIN=(bit)(dat0x8000);
dat=dat1;
TLV5618_SCLK=1;
mDelay(50);
TLV5618_SCLK=0;
mDelay(50);
}
TLV5618_CS=1;
}
void daconver(void)
{ float i=100;
unsigned int da;
i=outputvalue/100*4096;
da=(unsigned int)i;
TLV5618 (da);
}
附录[9]显示及键盘模块的程序—DIS7281.C
#include"delay.H"
#include"STC12C5410AD.H"
#include"dis7281.H"
#include"main.h"
void write7281(unsigned char regadd,unsigned char writedata)
{
sendbyte(regadd);
sendbyte(writedata);
}
void sendbyte(unsigned char sendbyte)
{
unsigned char bitcounter;
clk=0;
clk=1;
do{
clk=0;
clk=1;
}while(dat);
clk=0;
clk=1;
while(!dat);
for(bitcounter=0;bitcounter8;bitcounter++)
{
if ((sendbyte0x80)==0)
{ dat=0;}
else
{dat=1;}
sendbyte=sendbyte*2;
clk=0;
clk=1;
delay(1);
}
dat=1;
delay(2);
}
unsigned char receivebyte(void)
{
unsigned char bit_counter;
unsigned char in_byte;
clk=0;
clk=1; //只发送一个单元的脉冲
while(dat);//等待BC7281响应DAT底电平
clk=0;
clk=1; //受到响应,再发一脉冲等待接受数据
for (bit_counter=0;bit_counter8;bit_counter++ ) //接受8个BIT
{
delay(1);
in_byte=in_byte*2 ;//in_byte左移一位
if(dat) //如果DAT为1
{
in_byte=in_byte|0x01; //bit^0=1
}
clk=0;
clk=1;
}
delay(2);
clk=0;
clk=1;
return(in_byte);
}
unsigned char read7281(unsigned char reg_add)
{
sendbyte (0x80+reg_add); //发送读指令(BIT 7=1)
return (receivebyte()); //接受数据字节并返回
}
void dis4led()
{
unsigned char i;
unsigned char id=0x00;
for(i=0;i4;i++)
{
write7281(0x14,id+led[i]);
id+=0x10;
}
}
void dis2led()
{
unsigned char i;
unsigned char id=0x40;
for(i=4;i6;i++)
{
write7281(0x14,id+led[i]);
id+=0x10;
}
}
附录[10]PID算法模块的程序—PID.C
#include"adconver.h"
#include"STC12C5410AD.H"
#include"math.h"
#include"pid.h"
#include"hdconver.h"
#include"dis7281.h"
xdata struct _pid
{
int pv;
int sp;
float integral;
float pgain;
float igain;
float dgain;
int deadband;
int last_error;
};
xdata struct _pid warm,*pid;
xdata int process_point,set_point,dead_band;
xdata float p_gain,i_gain,d_gain,integral_val,new_integ;
void pid_init(struct _pid *warm,int process_point,int set_point)
{
struct _pid *pid;
pid=warm;
pid-pv=process_point;
pid-sp=set_point;
}
void pid_tune(struct _pid *pid,float p_gain,float i_gain,float d_gain,int dead_band)
{
pid-pgain=p_gain;
pid-igain=i_gain;
pid-dgain=d_gain;
pid-deadband=dead_band;
pid-integral=integral_val;
pid-last_error=0;
}
void pid_setinteg(struct _pid *pid,float new_integ)
{
pid-integral=new_integ;
pid-last_error=0;
}
void pid_bumpless(struct _pid *pid)
{
pid-last_error=(pid-sp)-(pid-pv);
}
float pid_calc(struct _pid *pid)
{
int err;
float pterm,dterm,result,ferror;
err=(pid-sp)-(pid-pv);
if(abs(err)pid-deadband)
{
ferror=(float)err;
pterm=pid-pgain*ferror;
if(pterm100||pterm-100)
{
pid-integral=0.0;
}
else
{
pid-integral+=pid-igain*ferror;
if(pid-integral100.0)
{
pid-integral=100.0;
}
else
{
if(pid-integral0.0)
{
pid-integral=0.0;
}
}
}
dterm=((float)(err-pid-last_error))*pid-dgain;
result=pterm+pid-integral+dterm;
}
else
{
result=pid-integral;
}
pid-last_error=err;
return(result);
}
void pidcf(void)
{
int count=0;
float val=100;
float p_gain=cp/val;
float i_gain=ci/val;
float d_gain=cd/val;
// unsigned int dadata;
pid=warm;
dead_band=2;
integral_val=(float)(0.01);
while(count=20)
{
process_point=(unsigned int)addata/val;
set_point=(unsigned int)setvalue/val;
pid_init(warm,process_point,set_point);
pid_tune(warm,p_gain,i_gain,d_gain,dead_band);
pid_setinteg(warm,0.0);
pid_bumpless(warm);
count++;
}
outputvalue=(unsigned char)pid_calc(warm);
hdconver2(outputvalue);
dis4led();
}
pid软件设计的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于pid应用实例、pid软件设计的信息别忘了在本站进行查找喔。