程序部分.docx
- 文档编号:29692509
- 上传时间:2023-07-26
- 格式:DOCX
- 页数:20
- 大小:18.64KB
程序部分.docx
《程序部分.docx》由会员分享,可在线阅读,更多相关《程序部分.docx(20页珍藏版)》请在冰豆网上搜索。
程序部分
7.8设计程序
1、主程序:
#include
#include
/*蒸煮过程给定量*/
#defineP10.2;//低压保压值(MPa)
P20.8;//高压保压值(MPa)
T1600;//空转时间(s)
T2600;//升低压时间(s)
T3600;
T4600;
T5600;//高压保压时间(s)
//
#defineT5;//采样周期
#defineKP1;//比例系数
#defineKI0;//积分系数
#defineKD0;//微分系数
#definePP10.2;//低压保压值
#definePP20.6;
#defineTT1
/floatLB(unsignedcharc[7]);//数字滤波
unsignedcharPID(unsignedchar*P,float*E);voidAD(unsignedchar*CO,unsignedchari);//A/D转换
voidDA(unsignedcharP,unsignedchari);//D/A转换
voiddisplay1(unsignedcharA,unsignedcharC);//LCD显示1
voiddisplay2(void);//LCD初始化显示
voiddisplay3(float*c);//压力值显示
unsignedintt,t1,t2,t3,t4,t5;
floatR;//给定值
floatdP1,dP2;//给定值增量
bitflag1,flag2;//采样标志位,蒸煮结束标志位
unsignedintIC;//定时中断计数器
voidmain(void)
{unsignedcharCO[5][7];//采样值存储数组
floatC[5];//滤波后的采样值
floatE[5][3];//偏差
unsignedcharP[5][2];//PID输出值
unsignedchari;
E=0;
R=t=IC=0;
t1=TT1;
t2=t1+TT2;
t3=t2+TT3;
t4=t3+TT4;
t5=t4+TT5;
ZD=flag1=flag2=0;
dP1=PP1/TT2;
dP2=PP2/TT4;
for(i=0;i<5;i++)
for(j=0;j<2;j++)
P[i][j]=0;
TH2=RCAP2H=OX3C;//装50ms定时初值
TL2=RCAP2L=OXB0;
ET2=1;//开中断
EA=1;
TR2=1;//启动定时器
display2();
while
(1)
{if(flag1==1)
{for(i=0;i<5;i++)
AD(CO[i],i);//A/D转换
for(i=0;i<5;i++)
C[i]=LB(CO[i]);//滤波
for(i=0;i<5;i++)
E[i][0]=R-C[i];//求偏差
for(i=0;i<5;i++)
P[i][0]=PID(P[i],E[i]);//PID运算
if(ZD==0)
{
for(i=0;i<5;i++)//判断是否为自动控制方式
DA(P[i][0],i);//D/A转换
}
display3();//刷新显示
flag=0;//采样标志清零
}
if(p3^1==0)//判断“手动/自动”按钮是否按下
{delay(20);//延时消抖
if(p3^1==0)
ZD=~ZD;//控制方式切换
}
while(flag2)//判断整个控制过程是否结束
display2();
}
}
voiddelay(intk)
{unsignedinti,j;
for(i=0;i for(j=0;j<220;j++) ; } 2、各部分子程序 /*数字滤波子函数*/ /*把采样来的7个数据去掉最大值和最小值,求出剩下的5个数的算术平均值,然后输出*/ floatLB(unsignedcharc[7]) {unsignedcharMax,Min,i; floatSum; Sum=0; Max=Min=c[0]; for(i=0;i<7;i++) {Sum+=c[i]; if(c[i]>Max) Max=c[i]; if(c[i] Min=c[i]; } Sum=(Sum-Max-Min)/5; returnSum; } /*PID运算子函数*/ /*位置型PID输出表达式: P(K)=P(K-1)+KP[E(K)-E(K-1)]+KIE(K)+KD[E(K)-2E(K-1)+E(K-2)]*/ unsignedcharPID(unsignedchar*P,float*E) {floatF; F=P[1]+KP(E[0]-E[1])+KI*E[0]+KD(E[0]-2E[1]+E[2]); E[2]=E[1]; E[1]=E[0]; if(F<=0) P[1]=0; else P[1]=(unsignedchar)F; returnP[1]; } /*A/D转换子函数*/ voidAD(unsignedchar*CO,unsignedchari) /*转换结果存于CO所指单元i为转换通道号*/ {unsignedcharj; for(j=0;j<7;j++) {XBYTE[A_D+i]=255;//启动A/D转换 delay (1); while(P3^5==0)//判断是否转换结束 ; CO[j]=XBYTE[A_D+i];//读转换结果 } } /*D/A转换子函数*/ voidDA(unsignedcharP,unsignedchari) { switch(i) {case0: XBYTE[D_A1]=P;break; case1: XBYTE[D_A2]=P;break; case2: XBYTE[D_A3]=P;break; case3: XBYTE[D_A4]=P;break; case4: XBYTE[D_A5]=P;break; default: break; } } /*LCD显示子函数*/ voiddisplay1(unsignedcharA,unsignedcharC) {unsignedcharj; do//检测忙信号 {E=1; j=XBYTE[LCD1]; E=0; }while(j<127) E=1; XBYTE[LCD0]=A;//设置显示地址 E=0; do {E=1; j=XBYTE[LCD1]; E=0; }while(j>127) E=1; XBYTE[LCD2]=C;//输出字符码 } voiddisplay2(void) { E=1; XBYTE[LCD0]=OX38;//设置显示模式 delay(5); XBYTE[LCD0]=OX01;//清屏 delay(5); XBYTE[LCD0]=OX0C;//显示ON,光标OFF,闪烁OFF delay(5); XBYTE[LCD0]=OX06;//光标移动设置 display1(OX82,'Z'); display1(OX83,'h'); display1(OX84,'e'); display1(OX85,'n'); display1(OX86,'g'); display1(OX88,'Q'); display1(OX89,'i'); display1(OX8A,'u'); display1(OX8C,'Y'); display1(OX8D,'a'); display1(OX8F,'L'); display1(OX90,'i'); display1(OXC1,'1'); display1(OXC2,'#'); display1(OXC3,': '); display1(OXC4,'0'); display1(OXC5,'.'); display1(OXC6,'0'); display1(OXC7,'0'); display1(OXCB,'2'); display1(OXCC,'#'); display1(OXCD,': '); display1(OXCE,'0'); display1(OXCF,'.'); display1(OXD0,'0'); display1(OXD1,'0'); display1(OX95,'3'); display1(OX96,'#'); display1(OX97,': '); display1(OX98,'0'); display1(OX99,'.'); display1(OX9A,'0'); display1(OX9B,'0'); display1(OX9F,'4'); display1(OXA0,'#'); display1(OXA1,': '); display1(OXA2,'0'); display1(OXA3,'.'); display1(OXA4,'0'); display1(OXA5,'0'); display1(OXD5,'5'); display1(OXD6,'#'); display1(OXD7,': '); display1(OXD8,'0'); display1(OXD9,'.'); display1(OXDA,'0'); display1(OXDB,'0'); display1(OXDF,'u'); display1(OXE0,'n'); display1(OXE1,'i'); display1(OXE2,'t'); display1(OXE3,': '); display1(OXE4,'M'); display1(OXE5,'P'); display1(OXE6,'a'); E=0; } voiddisplay3(float*C) {unsignedchari,L,a[5][3]; for(i=0;i<5;i++) {L=c[i]*0.5; a[i][2]=L%10+48; a[i][1]=(L/10)%10+48; a[i][0]=(L/100)%10+48; } display1(OXC4,a[0][0]; display1(OXC6,a[0][1]; display1(OXC7,a[0][2]; display1(OXCE,a[1][0]; display1(OXD0,a[1][1]; display1(OXD1,a[1][2]; display1(OX98,a[2][0]; display1(OX9A,a[2][1]; display1(OX9B,a[2][2]; display1(OXA2,a[3][0]; display1(OXA4,a[3][1]; display1(OXA5,a[3][2]; display1(OXD8,a[4][0]; display1(OXDA,a[4][1]; display1(OXDB,a[4][2]; E=0; } /*50ms定时中断函数*/ voidTimer2(void)interrupt5using1 { if(++IC==20)//1s定时是否到 {++t; if(t R=0;//空转时间 elseif(t R+=dP1;//升低压时间 elseif(t ;//低压保持时间 elseif(t R+=dP2;//升高压时间 elseif(t>=t5) flag2=1;//蒸煮过程结束 } if(IC==(T/0.05))//采样周期为5s {flag1=1;//采样标志位置1 IC=0; } 8.6部分程序 1: 数字控制器程序 staticfloatdataE_1;//设置E(K-1) staticfloatdataE_2;//设置E(K-2) staticfloatdataU_1;//设置U(K-1) staticfloatdataU_2;//设置U(K-2) floatDignal_Contoller(floatRk,floatCk)//Rk为给定值,Ck为测量值 { floatdataU_0;//设置U(K) floatdataE_0;//设置E(k) E_0=Rk-Ck;//计算偏差E(k) U_0=4*E_1-3.92*E_2+1.92*U_1+0.92*U_2;//最少拍无波纹控制算式 E_2=E_1; E_1=E_0;//E(k)赋值给E(K-1),E(k-1)赋值给E(K-2) U_2=U_1; U_1=U_0;//U(k)赋值给U(K-1),U(k-1)赋值给U(K-2) return(U_0); } 2: 中值滤波程序 #defineN12 charfilter() { charcount,i,j; charvalue_buf[N]; intsum=0; for(count=0;count { value_buf[count]=get_ad(); delay(); } for(j=0;j { for(i=0;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 sum+=value[count]; return(char)(sum/(N-2)); } 3: AD采样程序 /******************************************** 函数名称: Init_ADC* 功能: 初始化ADC* 参数: channel——ADC12输入通道选择* ref——ADC12参考电压选择* 返回值: 无* 注: channel的取值范围为0~7,对应P6.0~P6.7通道; ref的取值为0~3(或者Ref1_5Ref2_5Ref_AVccRef_Veref,在ADC_Func.h中定义的), 分别对应参考电压为1.5V2.5v电源电压AVcc外部参考电源Veref。 ********************************************/ voidInit_ADC(charchannel,charref) { ADC12CTL0&=~(ADC12SC+ENC); switch(channel)//改变结果寄存器的输入通道 { case0: ADC12MCTL0|=INCH_0;//选择ADC通道 P6SEL|=0x01;//使能ADC通道 break; case1: ADC12MCTL0|=INCH_1; P6SEL|=0x02;//使能ADC通道 break; case2: ADC12MCTL0|=INCH_2; P6SEL|=0x04;//使能ADC通道 break; case3: ADC12MCTL0|=INCH_3; P6SEL|=0x08;//使能ADC通道 break; case4: ADC12MCTL0|=INCH_4; P6SEL|=0x10;//使能ADC通道 break; case5: ADC12MCTL0|=INCH_5; P6SEL|=0x20;//使能ADC通道 break; case6: ADC12MCTL0|=INCH_6; P6SEL|=0x40;//使能ADC通道 break; case7: ADC12MCTL0|=INCH_7; P6SEL|=0x80;//使能ADC通道 break; default: break; } if(ref==Ref2_5) { ADC12CTL0|=ADC12ON+SHT0_8+REFON+REF2_5V+MSC;//打开ADC,设置采样时间2.5v参考电压多次转换 ADC12MCTL0|=SREF_1;//选择2.5v参考电压 } elseif(ref==Ref1_5) { ADC12CTL0|=ADC12ON+SHT0_8+REFON+MSC;//打开ADC,设置采样时间开1.5v参考电压多次转换 ADC12MCTL0|=SREF_1;//选择1.5v参考电压 } elseif(ref==Ref_AVcc) { ADC12CTL0|=ADC12ON+SHT0_8+MSC;//打开ADC,设置采样时间关参考多次转换 ADC12MCTL0|=SREF_0;//选择AVcc参考源 } elseif(ref==Ref_Veref)//外部参考电压 { ADC12CTL0|=ADC12ON+SHT0_8+MSC; ADC12MCTL0|=SREF_3; } ADC12IE=0x01;//使能ADC中断 ADC12CTL1|=SHP+CONSEQ_1; ADC12MCTL0=INCH0; ADC12MCTL1=INCH1+EOS; ADC12CTL0|=ADC12SC+ENC;//START } /******************************************* 函数名称: ADC12ISR* 功能: 中断服务子程序* 参数: 无* 返回值: 无* ********************************************/ #pragmavector=ADC12_VECTOR __interruptvoidADC12ISR(void) { staticuintADC_dat=0; staticuintADC_dat1=0; ADC_dat=ADC12MEM0; ADC_dat1=ADC12MEM1; ADC12CTL0|=ADC12SC+ENC; } 4: DA输出程序 /******************************************** 函数名称: Init_DAC12* 功能: 初始化DAC12* 参数: channel——DAC12输入通道选择* ref——DAC12参考电压选择* 返回值: 无* 注: channel的取值范围为0和1,对应P6.6和P6.7通道; ref的取值为0~2(或者DAC_Ref1_5DAC_Ref2_5DAC_Ref_Veref,在DAC12_Func.h中定义的), 分别对应参考电压为1.5v2.5v和外部参考电源Veref。 ********************************************/ voidInit_DAC12(ucharref,ucharchannel) { if(channel==0)//通道0 { DAC12_0CTL&=~DAC12ENC; if(ref==DAC_Ref1_5) { ADC12CTL0|=REFON;//打开1.5v参考电压 DAC12_0CTL|=DAC12SREF_0;//选择Vref+ } elseif(ref==DAC_Ref2_5) { ADC12CTL0|=REFON+REF2_5V;//开2.5V DAC12_0CTL|=DAC12SREF_1;//选择Vref+ } elseif(ref==DAC_Ref_Veref) { DAC12_0CTL|=DAC12SREF_2;//选择Veref+ } DAC12_0CTL|=DAC12IR+DAC12AMP_7;//十二位DAC12_0通道 DAC12_0CTL|=DAC12ENC; } elseif(channel==1)//通道1选择 { DAC12_1CTL&=~DAC12ENC; if(ref==DAC_Ref1_5) { ADC12CTL0|=REFON;//打开1.5v参考电压 DAC12_1CTL|=DAC12SREF_0;//选择Vref+ } elseif(ref==DAC_Ref2_5) { ADC12CTL0|=REFON+REF2_5V;//开2.5V DAC12_1CTL|=DAC12SREF_0;//选择Vref+ } elseif(ref==DAC_Ref_Veref) { DAC12_1CTL|=DAC12SREF_2;//选择Veref+ } DAC12_1CTL|=DAC12IR+DAC12AMP_7;//十二位DAC12_0通道 DAC12_1CTL|=DAC12ENC; } } /******************************************** 函数名称: Write_DAC* 功能: 更新DAC12输出* 参数: DAC值DAC_Val,通道号channel* 返回值: 无* ********************************************/ voidWrite_DAC(uint
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 程序 部分
![提示](https://static.bdocx.com/images/bang_tan.gif)