logo资料库

水温控制系统.docx

第1页 / 共15页
第2页 / 共15页
第3页 / 共15页
第4页 / 共15页
第5页 / 共15页
第6页 / 共15页
第7页 / 共15页
第8页 / 共15页
资料共15页,剩余部分请下载后查看
#include #include #include #include #define uchar unsigned char #define uint unsigned int /********************LCD、键盘的引脚和变量定义***************************/ sbit lcden=P2^7;//LCD 使能引脚 sbit lcdrs=P2^5;//LCD 的 RS 脚 sbit lcdrw=P2^6;//LCD 的 RW 脚 sbit ledred=P1^6; sbit ledgreen=P1^7; sbit key0=P2^0;//加一 sbit key1=P2^1;//减一 sbit key2=P2^2;//加十 sbit key3=P2^3;//减十 //存放设定温度显示值 uchar set[4]={0}; uchar code str1[]="now temp: uchar code str2[]="set temp: uchar code table[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; uchar n,num; C"; C"; /********************PID 结构体、参数定义***************************/ struct PID { unsigned int SetPoint; // 设定目标 unsigned int Proportion; // 比例常数 unsigned int Integral; // 积分常数 unsigned int Derivative; // 微分常数 unsigned int LastError; // 本次偏差 unsigned int PrevError; // 上次偏差 unsigned int SumError; // 偏差和 }; struct PID spid; // PID
uint rin; // 反馈输入,rin 为传感器传回来的真实温度值,作为实参传给 PID 计算函数,rin = tvalue/10; uint rout; // 响应输出,存放 PID 计算结果,用于下一步 high_time 设置使用,rout = PIDCalc ( &spid,rin ); high_time=(unsigned char)(rout/800); int set_temper=30;//初始设定温度变量定义 /********************PWM 输出引脚定义、占空比参数定义***************************/ sbit output=P1^0;//PWM 输出口 uchar high_time,low_time,count=0;//占空比调节参数 /********************DS18B20 引脚定义和参数定义***************************/ sbit DQ=P3^2;//ds18b20 与单片机连接口 int temper,temp; // 温 度 变 量 定 义 temper 为 真 实 温 度 , 用 于 温 度 比 较 函 数 时 使 用 if(set_temper>temper);temp 为扩大十倍的温度,temp 为 uint get_temper()的返回值 //float f_temp;//转换后的温度 uint tvalue;// 用 于 计 算 DS18B20 先 后 传 回 来 的 低 八 位 和 高 八 位 的 温 度 值 的 和 , tvalue=b;tvalue<<=8;tvalue=tvalue|a; 最 后 温 度 值 扩 大 10 倍 , 精 确 到 1 位 小 数 tvalue=tvalue*(0.625); uchar tflag;//温度正负标志 /*************************LCD 程序****************************/ void delay(i)//延时函数 { uint j;
for(i;i>0;i--) for(j=110;j>0;j--); } void wr_com(uchar ml)//写命令 { lcdrs=0;//RS=0 写指令,RS=1 写数据 P0=ml; delay(5); lcden=1;//使能信号,1 时读信息,1>0(下降沿)执行指令 delay(5); lcden=0;//使能信号,1 时读信息,1>0(下降沿)执行指令 } void wr_data(uchar shuju)//写数据 { lcdrs=1;//RS=0 写指令,RS=1 写数据 //lcden=1; P0=shuju; delay(5); lcden=1;//使能信号,1 时读信息,1>0(下降沿)执行指令 delay(5); lcden=0;//使能信号,1 时读信息,1>0(下降沿)执行指令 } void LCD_init() { //按照时序操作的初始化 lcdrw=0;//0 时向 LCD 写指令或数据,1 时从 LCD 读取信息 wr_com(0x38);//显示模式设置,设置为 16*2 显示,5*7 点阵,八位数据口 wr_com(0x0c);//开显示,但不开光标,光标不闪 wr_com(0x06);//显示光标移动设置 wr_com(0x01);// 清屏 wr_com(0x80); for(num=0;num<16;num++) // 数据指针初始化 { } wr_data(str1[num]);//now temp 显示"now temp: C" wr_com(0x80+0x40); //地址初始化 for(num=0;num<16;num++) { } } wr_data(str2[num]);//set temp 显示"set temp: C"
/*************************DS1820 程序****************************/ void delay_18B20(unsigned int i)//延时 1 微秒 { while(i--); } void ds1820rst(void)/*ds1820 复位*/ { //DQ 复位 unsigned char x=0; DQ = 1; delay_18B20(4); //延时 DQ = 0; TR0=0; delay_18B20(100); //精确延时大于 TR0=1; DQ = 1; delay_18B20(40); //DQ 拉低 //拉高 } uchar ds1820rd(void)/*读数据*/ { uchar i=0; uchar dat = 0; TR0=0; for (i=8;i>0;i--) { DQ = 0; //给脉冲信号 dat>>=1; //先传的是低位值,所以需要右移 DQ = 1; //给脉冲信号 if(DQ)//如果 DQ 返回来的是 1,则让 dat 加数字 1,也就是 dat=dat|0x80 dat|=0x80; delay_18B20(10); } return(dat); }
void ds1820wr(uchar wdata)/*写数据*/ { unsigned char i=0; TR0=0; for (i=8; i>0; i--) { DQ = 0; DQ = wdata&0x01; delay_18B20(10); DQ = 1; wdata>>=1; } } uint get_temper()//获取温度 { uchar a,b; ds1820rst(); ds1820wr(0xcc);//*跳过读序列号*/ ds1820wr(0x44);//*启动温度转换*/ ds1820rst(); ds1820wr(0xcc);//*跳过读序列号*/ ds1820wr(0xbe);//*读取温度*/ a=ds1820rd(); b=ds1820rd(); //低八位 //高八位 tvalue=b; tvalue<<=8; tvalue=tvalue|a; TR0=1; if(tvalue<0x0fff) else {tvalue=~tvalue+1;tflag=1;}//温度为负数,取补码 tvalue=tvalue*(0.625);//温度值扩大 10 倍,精确到 1 位小数 temp=tvalue;//温度值扩大 10 倍,精确到 1 位小数 return temp; tflag=0;//温度为正数 } void dis_temp(int t)//显示温度 { uchar d0,d1,d2,d3; //t=26; if(tflag==0) {
LCD 显示需要让得出的数的高位加上 0011 即 0x30 d0=t/1000+0x30;//百位 d1=t%1000/100+0x30;//十位 d2=t%100/10+0x30;//个位 d3=t%10+0x30;//小数一位 if(d0==0x30)//若温度没有超过一百度,则不显示百位 { wr_com(0x80+9); wr_data(d1); //显示十位 wr_com(0x80+10); wr_data(d2); //显示个位 wr_com(0x80+11); wr_data(0x2e); //显示小数点 wr_com(0x80+12); wr_data(d3); //显示第一位小数 } else { //显示百位 //显示十位 wr_com(0x80+9); wr_data(d0); wr_com(0x80+10); wr_data(d1); wr_com(0x80+11); wr_data(d2); wr_com(0x80+12); wr_data(' '); //显示个位 } } //正温度显示 else { wr_com(0x80+9); wr_data('-'); wr_com(0x80+10); wr_data(d1); wr_com(0x80+11); wr_data(d2); wr_com(0x80+12); wr_data(' '); //wr_com(0x80+12); //wr_data(d3); }//负温度显示 wr_com(0x80+14); wr_data(0xdf); //显示摄氏温度的那个小圆圈。 temper=t/10; //get_temper()得到的 temp 传给参数 t,而其值为真实温度值的十倍 用
于温度比较时使用 if(set_temper>temper) } /*************************键盘程序****************************/ void keyscan()//键盘扫描 { if(key0==0) { delay(1); //消抖 if(key0==0) { while(!key0); //若按键没松开则不执行下面的程序 delay(1);//消抖 while(!key0); set_temper++;//设置温度加一 spid.SetPoint =set_temper; } set[0]=set_temper/10; //获得设置温度显示值 set[1]=set_temper%10; set[2]=spid.SetPoint/10; set[3]=spid.SetPoint%10; wr_com(0x80+0x40+9); wr_data(table[set[0]]); delay(1); wr_com(0x80+0x40+10); wr_data(table[set[1]]); delay(1);
//wr_com(0x80+0x40+11); //wr_data(0x2e); //wr_com(0x80+0x40+14); //wr_data(0xdf); delay(1); wr_com(0x80+0x40+12); wr_data(table[set[2]]); delay(1); wr_com(0x80+0x40+13); wr_data(table[set[3]]); delay(1); //显示设置温度 //显示设置温度 } if(key1==0) { delay(3);//延时去抖 if(key1==0) { while(!key1); delay(3); while(!key1); set_temper--;//温度减 if(set_temper==0) {set_temper=0;} spid.SetPoint =set_temper; } set[0]=set_temper/10; //获得设置温度显示值 set[1]=set_temper%10; set[2]=spid.SetPoint/10; set[3]=spid.SetPoint%10; //显示设置温度值 wr_com(0x80+0x40+9); wr_data(table[set[0]]); delay(1); wr_com(0x80+0x40+10); wr_data(table[set[1]]); delay(1); //wr_com(0x80+0x40+11); //wr_data(0x2e);
分享到:
收藏