收藏 分销(赏)

C单片机的温闭环控制实验程序.doc

上传人:a199****6536 文档编号:2646238 上传时间:2024-06-03 格式:DOC 页数:8 大小:34.50KB 下载积分:6 金币
下载 相关 举报
C单片机的温闭环控制实验程序.doc_第1页
第1页 / 共8页
C单片机的温闭环控制实验程序.doc_第2页
第2页 / 共8页


点击查看更多>>
资源描述
#include <reg51.h> #include <absacc.h> #include <math.h> void pid(void) //PID算法子程序 void init(void) //初始化子程序 void display(void) //延时子程序 void clear() //清零子程序 int mmul(int x,int y) //16位乘法,溢出赋极值 int madd(int x,int y) //16位加法,溢出赋极值 int change32_16(int x,int t) //32——16 char change16_8(int wd) //16——8 #define C8255_A XBYTE[0x7F00] #define C8255_B XBYTE[0x7F01] #define C8255_C XBYTE[0x7F02] #define C8255_CON XBYTE[0x7F03] #define AD0809 XBYTE[0xFEFF] //定义AD0809的地址 sbit P17=P1^7; //PWM的驱动 char TS=0x64; //采样周期 int X=0x80; char SPEC=0x28; //给定:要求达到的温度值 char IBAND=0x60; //积分分离值:PID算法中积分分离值 int KP=12; //比例系数:PID算法中比例项系数 char KI=20; //积分系数 char KD=32; //微分系数 int CK; //控制量:PID算法产生用于控制的量 int TC; //采样周期变量 char FPWM; //PWM脉冲中间标识位 int CK_1; //控制量变量,用于记录上次控制的值 int AAAA; // PWM高电平脉冲时间计算 int VAA; //AAAA变量 int BBB; //PWM低电平脉冲时间计算 int VBB; //BBB变量 int TKMARK; //采样标志值 int ADMARK;//AD转换结束标志位 int ADVALUE; //AD采样后保存 int YK; //反馈:测量温度值 int EK; //温度误差 int EK_1; int AEK; int BEK; unsigned char dis; //BCD码显示 unsigned char led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; unsigned char b[]={0x00,0x00,0x00,0x00}; //位选 /********************温度表**************/ unsignedcharcode a[0x100]={0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x15,0x16,0x17,0x18,0x19, 0x1a,0x1b,0x1c,0x1d,0x1e,0x1e,0x1f,0x20,0x21,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a, 0x2b,0x2c,0x2d,0x2e,0x2f,0x31,0x32,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e, 0x3f,0x40,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x4f,0x50, 0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,0x60,0x61,0x62,0x63,0x64,0x64,0x65,0x65,0x66,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6e,0x6f,0x6f,0x70,0x71,0x72,0x73,0x74, 0x75,0x76,0x77,0x78,0x79, 0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x80,0x81,0x82,0x83,0x84,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9b,0x9c,0x9c,0x9d,0x9d,0x9e,0x9e, 0x9f,0x9f,0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0xb0,0xb1,0xb2,0xb3,0xb4,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbd,0xbe,0xbe,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6, 0xc8,0xca,0xcc,0xce,0xcf,0xd0,0xd1,0xd2,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xe3,0xe6,0xe9, 0xec,0xf0,0xf2,0xf6,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,} /**************延时子程序*********************/ void delay(unsigned int time) { unsigned int i; for(i=0;i<time;i++) } /*************主程序*************************/ void main() { init(); while(1); { while(1) { if(TRMARK==0x01) break; //采样周期到否 } TRMARK==0x00; while(1) { if(ADMARK==0x01) break; //AD转换是否结束 } ADMARK=0x00; YK=a[ADVALUE]; dis=(char)YK; //查温度表 pid(); //PID算法 if(CK<=0x80) //根据CK产生PWM AAAA=0x00; else AAAA=CK-0x80; BBB=0x7f-AAAA; } } /***********初始化函数*********************/ void init(void) { YK=0x00; //变量初始化 EK=0x00; EK_1=0x00; AEK=0x00; BEK=0x00; CK=0x00; CK_1=0x00; BBB=0x00; VBB=0x00; ADVALUE=0x00; TKMARK=0x00; ADMARK=0x00; TC=0x00; //采样周期变量 FPWM=0x01; AAAA=0x7f; VAA=0x7f; C8255_CON=0x81; display(); clear(); TMOD=0x11; //T1 ,T0由外部控制中断控制信号,16位定时器,工作在方式一下 IP=0x02; //设定T0中断优先级最高 IT1=1; //外部中断请求信号方式为脉冲触发方式,外中断1为下降沿有效 EX1=1; //允许INT1中断 TH0=0xd8; TL0=0xef; TH1=0xd8; TL1=0xef; ET0=ET1=1; //允许T0,T1中断 TR0=TR1=1; //启动T0,T1 EA=1; AD0809=1; //启动AD转换 } void myint3(void) interrupt 3 //定时器1 LED显示 { TH1=0xd8; TL1=0xef; ET1=1; display(); clear(); } void myint1(void) interrupt 2 //外中断1 读AD转换结果 { ADVALUE=AD0809; ADMARK=0x01; } void myint2(void) interrupt 1 //定时器0 启动AD转换 { TH0=0xd8; TL0=0xef; ET0=1; //启动定时器0 AD0809=1; //启动AD if(TC<TS) TC++; //采样周期变量 else { TKMARK=0x01; TC=0x00; } if(FPWM==0x01) //产生PWM ,0x01表示加热模块 { if(VA!=0x00) { VAA=VAA-1; P17=0; //输出为低 加热 } else { FPWM=0x02; VBB=BBB/2; } } if(FPWM==0x02) //0x02表示停止加热模块 { if(VBB!=0x00) { VBB=VBB-1; P17=1; //输出为高 停止加热 } else { FPWM=0x01; VAA=AAAA/2; } } return; } /*****************PID子程序***********/ void pid(void) { int K,P,I,D; K=P=I=D=0; EK=SPEC-YK;              //得到偏差 BEK=EK-EK_1-AEK;           //12EK AEK=EK-EK_1; //偏差变化量 /*********UK=Kp*AEK+Ki*EK+Kd*BEK****/ if(abs(EK)>abs(IBAND)) I=0; //判积分分离 else I=(EK*TS)/KI; //计算积分项 P=AEK; D=((KD/TS)*BEK)/10000; //计算微分项 //与书上对照,忽略KP K=madd(I,P); K=madd(D,K); K=mmul(K,KP); K=K/10; CK=K+CK_1; CK=change16_8(CK); CK_1=CK; EK_1=EK; CK=CK+X; } int mmul(int x,int y) { int t,z; long s; s=x*y; z=(int)(s&0x0ffff); t=(int)((s>>16)&0x0ffff); s=change32_16(z,t); return(s); } int change32_16(int z,int t) //t=高字节,z=低字节 { int s; if(t==0) { if((z&0x8000)==0) s=z; else s=0x7fff; } else if((t&0xffff)==0xffff) { if((z&0x8000)==0) s=0x8000; else s=z; } else if((t&0x8000)==0) s=0x7fff; else s=0x8000; return(s); } int mmad(int x,int y) { int t; t=x+y; if(x>=0&&y>=0) //同号相乘,符号位变反说明溢出 { if((t&0x8000)!=0) t=0x7fff; } else if(x<=0&&y<=0) { if((t&0x8000)==0) t=0x8000; } return(t); } char change16_8(int wd) //t=高字节,z=低字节 { char z,t,s; z=(wd>>8)&0x0ff; if(t==0x00) { if((z&0x80)==0) s=z; else s=0x7f; } else if((t&0xff)==0xff) { if((z&0x80)==0) s=0x80; else s=z; } else if((t&0x80)==0) s=0x7f; else s=0x80; return(s); } void display() //数码管显示函数 { unsigned char i,j=0xf7; b[3]=SPEC/10; b[2]=SPEC%10; b[1]=dis/10; b[0]=dis%10; for(i=0;i<4;i++) { C8255_A=j; C8255_B=led[b[i]]; delay(0x55); j>>=1; } } void clear() { C8255_B=0x00; }
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服