标题:
基于51单片机的温度控制源码与仿真
[打印本页]
作者:
DUJM
时间:
2018-4-28 20:56
标题:
基于51单片机的温度控制源码与仿真
以AT89C51单片机为核心的控制器,以DS18B20为温度传感器的温度控制器。
首先,通过对元器件的选择,设计控制器的硬件电路;然后,设计相关应用程序;最后,通过仿真,对整个系统进行调试、分析。最终实现温度采集、显示、控制等功能。。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
0.png
(17.4 KB, 下载次数: 98)
下载附件
2018-4-28 23:39 上传
0.jpg
(30.76 KB, 下载次数: 80)
下载附件
2018-4-28 23:39 上传
单片机源程序如下:
#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, 下载次数: 154)
2018-4-28 20:54 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
xxa
时间:
2018-5-2 16:11
请问有PID闭环负反馈控制吗?
作者:
jifengjianwu
时间:
2018-10-26 19:39
这个真挺好,有源程序,仿真也成功了,慢慢学习了。谢谢
作者:
石唯
时间:
2018-10-31 22:24
这个有对应的PCB图吗
作者:
xx14615
时间:
2018-11-16 00:18
挺好的,感谢
作者:
夏一
时间:
2020-5-22 21:32
再加个NO/OFF就更完美了
作者:
年少有你111
时间:
2020-6-23 19:54
这个程序是什么意思
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1