以AT89C51单片机为核心的控制器,以DS18B20为温度传感器的温度控制器。
首先,通过对元器件的选择,设计控制器的硬件电路;然后,设计相关应用程序;最后,通过仿真,对整个系统进行调试、分析。最终实现温度采集、显示、控制等功能。。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include<reg51.h>
- #include<stdio.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit ds=P3^2; //温度传感器信号线
- sbit RS=P1^0;
- sbit RW=P1^1;
- sbit E=P1^2;
- sbit beep=P1^5;
- sbit man=P1^6;
- sbit woman=P1^7;
- uint temp;
- uint count=0;
- uchar f_temp;
- unsigned int A,W,C;
- data unsigned char SET[15]={"settemp: "};
- data unsigned char REAL[15]={"realtemp: "};
- char code tab[3][4]={ {'1','2','3','4'},
- {'5','6','7','8'},
- {'9','0',' ',' '}}; //0到F的16个键植
-
- void delay(uint z) //延时函数
- { uint x,y;
- for (x=z;x>0;x--)
- for (y=110;y>0;y--);
- }
-
-
- //以下是DS18B20的相关程序
- void dsreset(void) //DS18B20复位初始化函数
- { uint i;
- ds=0;
- i=103;
- while(i>0)i--;
- ds=1;
- i=4;
- while(i>0)i--;
- }
-
- bit tempreadbit(void) //读一位数据函数
- { uint i;
- bit dat;
- ds=0;
- i++; //i++起延时作用
- ds=1;
- i++;
- i++;
- dat=ds;
- i=8;
- while(i>0)i--;
- return(dat);
- }
-
- uchar tempread(void) //读1个字节数据函数
- { uchar i,j,dat;
- dat=0;
- for(i=1;i<=8;i++)
- { j=tempreadbit();
- dat=(j<<7)|(dat>>1);
- }
- return(dat);
- }
-
- void tempwritebyte(uchar dat) //向DS18B20写一个字节数据函数
- { uint i;
- uchar j;
- bit testb;
- for (j=1;j<=8;j++)
- { testb=dat&0x01;
- dat=dat>>1;
- if (testb) //写1
- { ds=0;
- i++;
- i++;
- ds=1;
- i=8;
- while(i>0)i--;
- }
- else
- { ds=0; //写0
- i=8;
- while(i>0)i--;
- ds=1;
- i++;
- i++;
- }
- }
- }
-
- void tempchange(void) //DS18B20开始获取温度并进行转换
- { dsreset(); //复位
- delay(1); //延时
- tempwritebyte(0xcc); //写跳过读ROM指令
- tempwritebyte(0x44); //写温度转换指令
- }
-
- uint get_temp() //读寄存器中的温度
- {
- uchar m,n;
- dsreset(); //复位
- delay(5);
- tempwritebyte(0xcc);
- tempwritebyte(0xbe);
- m=tempread(); //读低8位
- n=tempread(); //读高8位
- temp=n;
- temp<<=8;
- temp=temp|m;
- f_temp=temp*0.0625;
- temp=f_temp*10+0.5;
- f_temp=f_temp+0.05;
- return temp; //temp是整型
- }
- //以下是键盘程序
- char kbscan() //键盘扫描
- {
- unsigned char hang,lie,key;
- P2=0x0f;
- if(P2!=0x0f)
- delay(1);
- if(P2!=0x0f)
- {
- switch(P2&0x0f)
- {
- case 0x0e:lie=0;break;
- case 0x0d:lie=1;break;
- case 0x0b:lie=2;break;
- case 0x07:lie=3;break;
- }
- P2=0xf0;
- P2=0xf0;
- switch(P2&0xf0)
- {
-
- case 0xd0:hang=1;break;
- case 0xb0:hang=2;break;
- case 0xe0:hang=0;break;
- }
- P2=0x0f;
- while(P2!=0x0f);
- key=tab[hang][lie];
- }
- else
- key=0;
- return (key);
- }
- //以下是lm016l的显示程序
- void cls(unsigned char da) //LCD清屏
- {
- delay(1); //用延时代替检测忙信号
- RS=0;
- RW=0;
-
- P0=da;
- E=1;
- E=0;
- }
-
- void write_com(unsigned char c) //写入控制命令的子程序
- {
- int i;
- for(i=80;i>0;i--); //用延时代替忙检测
- RS=0; //选择写命令模式
- RW=0; //选择写模式
- E=0;
- P0=c; //要写的数据
- E=1; //给使能端一个高脉冲
- E=0;
- }
-
- void write_data(unsigned char d) //写入数据的子程序
- {
- int i;
- for(i=80;i>0;i--);
- RS=1; //选择读命令模式
- RW=0; //选择写模式
- E=0;
- P0=d;
- E=1;
- E=0;
- }
-
- void realtemp(te)
- { uchar k;
- k=te/10;
- REAL[9]=k/10+48;
- REAL[10]=k%10+48;
- return;
- }
-
- void sett()
- {
- if(count==1)
- {
- SET[13]=kbscan();
- }
- else if(count==2)
- { SET[9]=kbscan();
- }
- else if(count==3)
- { SET[10]=kbscan();
- }
- else if(count==4)
- { SET[12]=kbscan();
- }
- SET[11]='-';
- return;
- }
- //主程序
- void main()
- {
- int i;
- char a,b;
-
- write_com(0X01); //显示清零数据指针清零
- write_com(0X38); //设置16*2显示5*7点阵8位数据接口
- write_com(0X0C); //设置开显示不显示光标
- write_com(0X06); //写一个字符后地址指针自动加1
- cls(1); //初始化
-
- while(1)
- { tempchange(); //温度转换函数
-
- write_com(0x80); //显示第一排
- if(P2!=0x0f)
- {
- if(count==4)
- { count=1;}
-
- else count=count+1;
- sett();
- }
- for(i=0;i<15;i++)
- {
- a=SET[i];
- write_data(a);
- }
-
- write_com(0xC0); //显示第二排
- realtemp(get_temp());
- for(i=0;i<15;i++)
- { b=REAL[i];
- write_data(b);
- }
- if(A>C||C>W)
- {
- beep=1;
-
- }
- A=SET[9]*10+SET[10];
- W=SET[12]*10+SET[13];
- C=REAL[9]*10+REAL[10];
- if(A<C&&C<W) {beep=0;man=1;woman=1;}
- if(C<W){man=0;}
- else if(C>W){man=1;}
- if(C>A){woman=0;}
- else if(C<A){woman=1;}
- }
- }
复制代码
所有资料51hei提供下载:
原理图及代码.rar
(26.88 KB, 下载次数: 153)
|