基于51单片机的温度测试系统+有VB上位机.docx
《基于51单片机的温度测试系统+有VB上位机.docx》由会员分享,可在线阅读,更多相关《基于51单片机的温度测试系统+有VB上位机.docx(31页珍藏版)》请在冰豆网上搜索。
![基于51单片机的温度测试系统+有VB上位机.docx](https://file1.bdocx.com/fileroot1/2022-12/16/81fa341e-4474-4beb-8866-84f4b9e8fe93/81fa341e-4474-4beb-8866-84f4b9e8fe931.gif)
基于51单片机的温度测试系统+有VB上位机
简介:
这是我学完51单片机的第一个作品,单片机型号为89c52,时钟芯片用的是DS1302,温度传感器用的是DS18B20,USB供电,掉电后时钟芯片继续工作,且已经设置好的温度上下限和闹钟数据不会丢失。
上位机是用VB语言写的,只是一个模型,从上位机上可以观察当前温度值以及温度上下限,以后会更加完善其功能。
下面是下位机程序和上位机程序,程序比较长,而且下位机程序的键盘部分写得有点麻烦。
/***************************************************************************************
作者:
江苏科技大学电子信息科学与技术二班吴亚迪
注:
此程序可以实现万年历
闹钟
温度测定
温度超过上下限发出警报
断电后时钟不停,且已设好的温度上下限和闹钟数据不会丢失
****************************************************************************************/
#include
#defineucharunsignedchar
#defineuintunsignedint
ucharcodetable[]="20 / / DAY-";
ucharcodetable1[]=" :
:
";
ucharcodetable2[]="0123456789";
ucharcodetable3[]=" alarmclock ";
sbitds_clk=P3^6;
sbitds_io=P3^7;
sbitds_rst=P1^4;
sbitlcdrs=P1^0;
sbitlcdrw=P1^1;
sbitlcden=P1^2;
sbitscl=P3^2;
sbitsda=P3^3;
sbitACC_7=ACC^7;
sbitP34=P3^4;
bitalarm=0;//闹钟标志位
bitstop_alarm=0;//停止闹钟标志位
uchari,j;
ucharth,tl; //温度上下限
uintth1,th2,tl1,tl2;
ucharmin,hour,sec; //闹钟时分秒
uintmin1,min2,hour1,hour2,sec1,sec2;
voiddelay(uinti)
{
uintj;
for(;i>0;i--)
for(j=0;j<110;j++);
}
/***********************************************************************************************
DS1302部分
**************************************************************************************************/
chars,s1,s2; //时钟秒
charm,m1,m2; //分
charh,h1,h2; //时
charday; //星期
chardate,date1,date2;//日期
charmon,mon1,mon2; //月
charyear,year1,year2;//年
voidwrite_ds(ucharadd,uchardate)//向ds1302指定地址写数据
{
uchari,temp;
ds_rst=0;
ds_clk=0;
ds_rst=1;
for(i=8;i>0;i--)
{
ds_clk=0;
temp=add;
ds_io=temp&0x01;
add>>=1;
ds_clk=1;
}
for(i=8;i>0;i--)
{
ds_clk=0;
temp=date;
ds_io=temp&0x01;
date>>=1;
ds_clk=1;
}
ds_rst=0;
}
ucharread_ds(ucharadd) //ds1302指定地址读数据
{
unsignedchari,temp,date1;
ds_rst=0;
ds_clk=0;
ds_rst=1;
for(i=8;i>0;i--)
{
ds_clk=0;
temp=add;
ds_io=temp&0x01;
add>>=1;
ds_clk=1;
}
for(i=8;i>0;i--)//这里要注意
{
ACC_7=ds_io;
ds_clk=1;
ACC>>=1;
ds_clk=0;
}
ds_rst=0;
date1=ACC;
returndate1;
}
voidinit_ds() //初始化ds1302
{
write_ds(0x8e,0x00);//关闭写保护
write_ds(0x80,0x22);//初始化秒
write_ds(0x82,0x59);//分
write_ds(0x84,0x23);//时
write_ds(0x86,0x21);//日
write_ds(0x88,0x05);//月
write_ds(0x8a,0x06);//星期
write_ds(0x8c,0x11);//年
write_ds(0x8e,0x80);//开写保护
}
voidread_all() //读s,m,h,date,mon,year,day
{
s=read_ds(0x81);
s1=s/16;
s2=s%16;
m=read_ds(0x83);
m1=m/16;
m2=m%16;
h=read_ds(0x85);
h1=h/16;
h2=h%16;
date=read_ds(0x87);
date1=date/16;
date2=date%16;
mon=read_ds(0x89);
mon1=mon/16;
mon2=mon%16;
day=read_ds(0x8b);
year=read_ds(0x8d);
year1=year/16;
year2=year%16;
}
/***********************************************************************************************
1602部分
**************************************************************************************************/
voidwrite_com(ucharcom) //写命令
{
lcdrs=0;
lcden=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
voidwrite_date(uchardate)//写数据
{
lcdrs=1;
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
voidinit_1602()//初始化1602
{
lcdrw=0;
write_com(0x01);
write_com(0x38);
write_com(0x0f);
write_com(0x06);
for(i=0;i<16;i++)
{
write_date(table[i]);
delay(10);
}
write_com(0x80+0x40);
for(i=0;i<16;i++)
{
write_date(table1[i]);
delay(10);
}
write_com(0x80+0x40+0x0e);
write_date(0xdf);
delay(10);
write_date('c');
}
/***********************************************************************************************
EEPROM部分
**************************************************************************************************/
voiddelay1()
{;;}
voidinit()//初始化总线
{
sda=1;
delay1();
scl=1;
delay1();
}
voidstart()//开始函数
{
sda=1;
delay1();
scl=1;
delay1();
sda=0;
delay1();
}
voidstop()//停止函数
{
sda=0;
delay1();
scl=1;
delay1();
sda=1;
delay1();
}
voidrespons()//应答
{
uchari;
sda=1;
delay1();
scl=1;
while(sda==1&&i<250)i++;
scl=0;
delay1();
}
voidwrite_byterom(uchardate)//向eeprom中写一字节数据
{
uchari;
for(i=0;i<8;i++)
{
date=date<<1;
scl=0;
delay1();
sda=CY;
delay1();
scl=1;
delay1();
}
scl=0;
delay1();
}
ucharread_byterom()//从eeprom中读一字节数据
{
uchari,temp;
scl=0;
delay1();
for(i=0;i<8;i++)
{
scl=1;
delay1();
temp<<=1;
temp|=sda;
scl=0;
delay1();
}
returntemp;
}
voidwrite_add(ucharadd,uchardate)//指定地址写数据
{
start();
write_byterom(0xa0);
respons();
write_byterom(add);
respons();
write_byterom(date);
respons();
stop();
}
ucharread_add(ucharadd)//指定地址读数据
{
uchartemp;
start();
write_byterom(0xa0);
respons();
write_byterom(add);
respons();
start();
write_byterom(0xa1);
respons();
temp=read_byterom();
stop();
returntemp;
}
/***********************************************************************************************
ds18b20部分
**************************************************************************************************/
sbitDQ=P3^5;
voiddelay2(uchari)
{
while(i--);
}
voidinit_ds18b20()//初始化ds18b20
{
uchari;
DQ=1;
delay2(8);
DQ=0;
delay2(80);
DQ=1;
while(DQ==1&&i<255)i++;
delay2(35);
delay2(20);
}
voidwrite_byte(uchardat)//向ds18b20中写一字节
{
uchari;
for(i=0;i<8;i++)
{
DQ=1;
delay2
(1);
DQ=0;
delay2
(1);
DQ=dat&0x01;
delay2(5);
DQ=1;
dat>>=1;
delay2(4);
}
}
ucharread_byte()//从ds18b20中读一字节
{
uchari,dat=0;
for(i=0;i<8;i++)
{
DQ=1;
delay2
(1);
DQ=0;
dat>>=1;
DQ=1;
if(DQ)dat=dat|0X80;
delay2(4);
}
returndat;
}
ucharread_temp()//读温度函数
{
uchara,b,c;
init_ds18b20();
write_byte(0xcc);
write_byte(0x44);
init_ds18b20();
write_byte(0xcc);
write_byte(0xbe);
a=read_byte();
b=read_byte();
c=(b<<4)|(a>>4);
returnc;
}
ucharread_th()//读上限函数
{
uchara,b,c;
init_ds18b20();
write_byte(0xcc);
write_byte(0x44);
init_ds18b20();
write_byte(0xcc);
write_byte(0xbe);
a=read_byte();
b=read_byte();
c=read_byte();
returnc;
}
ucharread_tl()//读下限函数
{
uchara,b,c;
init_ds18b20();
write_byte(0xcc);
write_byte(0x44);
init_ds18b20();
write_byte(0xcc);
write_byte(0xbe);
a=read_byte();
b=read_byte();
a=read_byte();
c=read_byte();
returnc;
}
/***********************************************************************************************
键盘部分(P2^0~P2^3)
**************************************************************************************************/
voidkeyscan()
{
uchartemp,num1,num2;
temp=P2;
temp&=0x0f;
if(temp!
=0x0f) //消抖
{
delay(5);
if(temp!
=0x0f)
{
temp=P2;
temp&=0x0f;
if(temp==0x0e)
{
num1=1;
write_ds(0x8e,0x00);
write_ds(0x80,s|0x80);//禁止写保护
while(temp==0x0e)//松手检测
{
temp=P2;
temp&=0x0f;
}
while
(1)
{
temp=P2;
temp&=0x0f;
if(temp==0x0e)
{
delay(5);
temp=P2;
temp&=0x0f;
if(temp==0x0e)
{
num1++;
}
}
while(temp==0x0e)//松手检测
{
temp=P2;
temp&=0x0f;
}
if(num1==1)
{
write_com(0x80+0x40+0x08);
write_com(0x0f);//光标闪烁
temp=P2;
temp&=0x0f;
if(temp==0x0d)
{
delay(5);
if(temp==0x0d)
{
while(temp==0x0d)//松手检测
{
temp=P2;
temp&=0x0f;
}
s=read_ds(0x81);
s1=s/16;
s2=s%16;
s2+=1;
if(s2==10)
{
s2=0;
s1+=1;
}
if(s1==6)s1=0;
write_com(0x80+0x40+0x07);
write_date(table2[s1]);
write_date(table2[s2]);
write_ds(0x80,s1*16+s2);//向ds1302中写入秒
}
}
elseif(temp==0x0b)
{
delay(5);
if(temp==0x0b)
{
while(temp==0x0b)//松手检测
{
temp=P2;
temp&=0x0f;
}
s=read_ds(0x81);//读ds1302秒
s1=s/16;
s2=s%16;
s2-=1;
if(s2==-1)
{
s2=9;
s1-=1;
}
if(s1==-1)s1=5;
write_com(0x80+0x40+0x07);
write_date(table2[s1]);
write_date(table2[s2]);
write_ds(0x80,s1*16+s2);
}
}
}
if(num1==2)
{
write_com(0x80+0x40+0x05);
write_com(0x0f);
temp=P2;
temp&=0x0f;
if(temp==0x0d)
{
delay(5);
if(temp==0x0d)
{
while(temp==0x0d)//松手检测
{
temp=P2;
temp&=0x0f;
}
m=read_ds(0x83);//从ds1302中读分
m1=m/16;
m2=m%16;
m2+=1;
if(m2==10)
{
m2=0;
m1+=