51单片机DS18B20测温LCD12864显示

介绍

DS18B20采集温度每隔一分钟在LCD12864上显示
第一行显示温度第二行显示范围第三行显示1一分钟

Proteus仿真运行图

在这里插入图片描述

源程序

主函数

#include<reg51.h>
#include <intrins.h>
#include "mine.h"
uchar count,num,n=1;
int tempValue,Tempture; 
void main()
{ 
	T0_init();
	ds18b20Init();
	ds18b20Start();
	delayxms(1000);//保证最开始显示当前的温度
	Tempture=ds18b20ReadTemperture()*10;
	InitLCD();	
	while(1)
	{
	TemptureDisplay();
	/*****显示60秒计时*****/
	DisplayZf(1,6,48,num/10);
	DisplayZf(1,6,56,num%10);	
	}
}
void T0_t() interrupt 1
{
	ds18b20Start();
	TH0=0x3c;//重装初值
	TL0=0xb0;
	count++;
	if (count==20)//到了20次即1s时间
	{
		count=0;//清零开始
		  num++;
		if(num==5)
		{
		num=0;
    n=1;			
		}
	}
}
void TemptureDisplay()
{
	
	uint i,Bai,Ge,Shi;
	uint FanWei[]={10,12,5,5,16,1,2,5,14,15};
	if(n)
	{	n=0;
	Tempture=ds18b20ReadTemperture()*10;
	 if(Tempture<0)
	 {
	   Tempture=-Tempture;
		 DisplayZf(1,2,40,12);
	 }
	 else 
	 {
		 DisplayZf(1,2,40,11);
	}}
	 Bai=Tempture/100;
	 Ge=Tempture%10;
	 Shi=(Tempture%100)/10;
	/******温度:*.*°*C*********/
	 for(i=0;i<2;i++)  
		 DisplayHz(1,2,i*16,i);
   DisplayZf(1,2,32,10);
	 DisplayZf(1,2,48,Bai);
	 DisplayZf(1,2,56,Shi);
	 DisplayZf(2,2,0,13);
	 DisplayZf(2,2,8,Ge);
	 DisplayZf(2,2,16,14);
	 DisplayZf(2,2,24,15);
	/*显示范围*/
	for(i=2;i<4;i++)  
		DisplayHz(1,4,(i-2)*16,i);//范围:
	for(i=0;i<4;i++)
	  DisplayZf(1,4,(i*8+32),FanWei[i]);//-55
	for(i=4;i<10;i++)
	  DisplayZf(2,4,(i*8-32),FanWei[i]);//~125°C
}

自定义头文件


#ifndef _MINE_H          
#define _MINE_H
#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
/**************************************ds18b20模块声明*******************************
复位*检查是否存在*读一位*读一个字节*写一个字节*开始读温度*初始*读温度并转换*显示温度*
************************************************************************************/
void ds18b20Rest();
uchar ds18b20Check();
uchar ds18b20ReadBit();
uchar ds18b20ReadByte();
void ds18b20WriteByte(uchar dat);
void ds18b20Start();
uchar ds18b20Init();
float ds18b20ReadTemperture();
void TemptureDisplay();
sbit DQ=P3^3;
/*************************LCD12864模块声明**************************
查忙*写数据*写命令*设定页数(共四行八页0~7)*起始行*列数(64列0~63)****
开关*清屏*初始化*显示汉字(16*16(宽*高))*显示字符(8*16(宽*高))*
*******************************************************************/
void busy();
void W_Data(uchar dat);
void W_Cmd(uchar cmd);	
void S_Page(uchar page);
void S_StartHang(uchar hang);
void S_Lie(uchar lie);
void S_OnOff(uchar onoff);
void S_Screen(uchar screen);
void ClS(uchar screen);
void InitLCD();
void DisplayHz(uchar s,uchar page,uchar lie,uchar number);
void DisplayZf(uchar s,uchar page,uchar lie,uchar number);
sbit rs=P2^0;
sbit rw=P2^1;
sbit e=P2^2;
sbit cs1=P2^3;
sbit cs2=P2^4;
/***********共用模块声明*********
定时器T0初始化*延时10us*延时xms*/
void T0_init();
void delay10us(uint us);
void delayxms(uint x);
#endif

LCD12864函数(不带字库)

#include<reg51.h>
#include "mine.h"
uchar code Hzk[]=
{
	/***********************************温*****************************************/
	0x10,0x60,0x02,0x8C,0x00,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,
	0x04,0x04,0x7E,0x01,0x40,0x7E,0x42,0x42,0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00,
	/***********************************度*****************************************/
	0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00,
	0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00,
	/***********************************范*****************************************/
	0x04,0x44,0x84,0x14,0x64,0x0F,0x04,0xE4,0x24,0x2F,0x24,0x24,0xE4,0x04,0x04,0x00,
  0x00,0x08,0x09,0x78,0x04,0x03,0x00,0x3F,0x40,0x40,0x42,0x44,0x43,0x40,0x78,0x00,
	/***********************************围*****************************************/
	0x00,0xFE,0x02,0x12,0x52,0x52,0x52,0xFE,0x52,0x52,0x52,0x12,0x02,0xFE,0x00,0x00,
	0x00,0xFF,0x40,0x41,0x41,0x41,0x41,0x7F,0x41,0x49,0x51,0x4F,0x40,0xFF,0x00,0x00,
  /*****************************宋体小四(64*64)********************************/
};
uchar code Zfk[]=
{
	/**************************************0~9************************************/
	0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,
	0x00,0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,
	0x00,0x70,0x08,0x08,0x08,0x08,0xF0,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,
	0x00,0x30,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x18,0x20,0x21,0x21,0x22,0x1C,0x00,
	0x00,0x00,0x80,0x40,0x30,0xF8,0x00,0x00,0x00,0x06,0x05,0x24,0x24,0x3F,0x24,0x24,
	0x00,0xF8,0x88,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x20,0x20,0x20,0x11,0x0E,0x00,
	0x00,0xE0,0x10,0x88,0x88,0x90,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x20,0x1F,0x00,
	0x00,0x18,0x08,0x08,0x88,0x68,0x18,0x00,0x00,0x00,0x00,0x3E,0x01,0x00,0x00,0x00,
	0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,
	0x00,0xF0,0x08,0x08,0x08,0x10,0xE0,0x00,0x00,0x01,0x12,0x22,0x22,0x11,0x0F,0x00,
	/**********************************:,+,-,.,°,C,~*********************************/
	0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x0F,0x01,0x01,0x01,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x0C,0x12,0x12,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x02,0x02,0x04,0x02,0x00,
};
/*检查是否忙*/
void busy()		
{uchar dat;
 rs=0;rw=1; 
 do{
	 P0=0x00;
   e=1;	
	 dat=P0;
   e=0;
   dat=0x80 & dat; 
   }while(!(dat==0x00));
}
/*写数据到LCD中*/
void W_Data(uchar dat)
{
  busy();
	rs=1;rw=0;
	P0=dat;
	e=1;e=0;
}
/*写命令到LCD中*/
void W_Cmd(uchar cmd)
{
  busy();
	rs=0;rw=0;
	P0=cmd;
	e=1;e=0;
}
/*设置页(8行为一页,共64行即8页(0~7页)*/
void S_Page(uchar page)
{
  page=0xb8|page;//只有0~7页
	W_Cmd(page);
}
/*起始行*/
void S_StartHang(uchar hang)
{
  hang=0xc0|hang;
	W_Cmd(hang);
}
/*设定列*/
void S_Lie(uchar lie)
{
  lie=lie&0x3f;//lie&(0011 1111),列大于63自动从零列
	lie=0x40|lie;
	W_Cmd(lie);
}
/*开(关)显示*/
void S_OnOff(uchar onoff)
{
  onoff=0x3e|onoff;//(0011 1110)|onoff,0关1开
	W_Cmd(onoff);
}
/*屏幕选择*/
void S_Screen(uchar screen)
{ 
	switch(screen)
	{
	case 0:cs1=0;cs2=0;break;//全屏
	case 1:cs1=0;cs2=1;break;//左屏
	case 2:cs1=1;cs2=0;break;//右屏
	}
}
/*清屏*/
void ClS(uchar screen)
{
  uchar i,j;
	S_Screen(screen);//选择清除那个屏
	for(i=0;i<8;i++)
	{
	S_Page(i);
	S_Lie(0);
	for(j=0;j<64;j++)
	W_Data(0x00);
	}
}
/*初始化*/
void InitLCD()
{
  busy();
	S_Screen(0);S_OnOff(0);
	S_Screen(0);S_OnOff(1);
	S_Screen(0);ClS(0);
	S_StartHang(0);
}
/*显示*/
void DisplayHz(uchar s,uchar page,uchar lie,uchar number)
{int i;	
 S_Screen(s);
 lie=lie&0x3f;
 S_Page(page);S_Lie(lie);
 for(i=0;i<16;i++)  
	W_Data(Hzk[i+32*number]);//显示汉字上半部分
 S_Page(page+1);S_Lie(lie);	  
 for(i=0;i<16;i++)	  
	W_Data(Hzk[i+32*number+16]);//显示汉字下半部分
} 
void DisplayZf(uchar s,uchar page,uchar lie,uchar number)
{
	int i;
	S_Screen(s);
	lie=lie&0x3f;
	S_Page(page);S_Lie(lie);
	for(i=0;i<8;i++)  
		W_Data(Zfk[i+16*number]);
	S_Page(page+1);S_Lie(lie);	  
	for(i=8;i<16;i++)	  
		W_Data(Zfk[i+16*number]);
}

DS18B20函数

#include<intrins.h>
#include "mine.h"
/***************复位**********/
void ds18b20Reset()
{
 DQ=0;
 delay10us(75);//拉低DQ,750us(480~960)
 DQ=1;
 delay10us(2);//DQ=1,20US(15~60)
}
/*******检测18b20是否存在**********/
uchar ds18b20Check()
{
	uchar time_temp=0;
	while(DQ&&time_temp<20)	//等待DQ为低电平,如果一直高电平且超过200us退出,
	{
		time_temp++;
		delay10us(1);	
	}
	if(time_temp>=20)return 1;//ds18b20没有响应
	else time_temp=0;//检测到ds18b20
	while((!DQ)&&time_temp<20)
	{
	time_temp++;
	delay10us(1);
	}
	if(time_temp>=20)return 1;	//如果超时则强制返回1
	return 0;//检测到响应
}
/*********温度读取(一位)**********/
uchar ds18b20ReadBit()
{
	uchar dat=0;
	DQ=0;
	_nop_();_nop_();
	DQ=1;	
	_nop_();_nop_(); //该段时间不能过长,必须在15us内读取数据
	if(DQ)dat=1;	//读1
	else dat=0;//读0
	delay10us(6);
	return dat;
} 
/*******温度读取(一个字节)**********/
uchar ds18b20ReadByte()
{
	uchar i=0;
	uchar dat=0;
	uchar temp=0;
	for(i=0;i<8;i++)//循环8次,每次读取一位,且先读低位再读高位
	{
		temp=ds18b20ReadBit();
		dat=(temp<<7)|(dat>>1);//temp左移7位或上dat右移1位
	}
	return dat;	
}
/*******温度写入(一个字节)**********/
void ds18b20WriteByte(uchar dat)
{
	uchar i=0;
	uchar temp=0;
	for(i=0;i<8;i++)//循环8次,每次写一位,且先写低位再写高位
	{
		temp=dat&0x01;//取出低位,选择低位准备写入
		dat>>=1;//将次高位移到低位右移
		if(temp)
		{
			DQ=0;
			_nop_();_nop_();//延时2us(>1us)
			DQ=1;//释放总线
			delay10us(6);//至少60us
		}
		else
		{
		DQ=0;//写0与写1延时相反
		delay10us(6);
		DQ=1;
		_nop_();_nop_();	
		}	
	}	
}
void ds18b20Start()
{
  ds18b20Reset();//复位
	ds18b20Check();//检查DS18B20
	ds18b20WriteByte(0xcc);//SKIP ROM
  ds18b20WriteByte(0x44);//转换命令	
}
uchar ds18b20Init()
{
	ds18b20Reset();
	return ds18b20Check();	
}
/***********温度读取*********/
float ds18b20ReadTemperture()
{
	float temp;
	uchar datH=0;
	uchar datL=0;
	uint value=0;
	ds18b20Start();//开始转换
	ds18b20Reset();//复位
	ds18b20Check();
	ds18b20WriteByte(0xcc);//SKIP ROM
  ds18b20WriteByte(0xbe);//读存储器
	datL=ds18b20ReadByte();//低字节
	datH=ds18b20ReadByte();//高字节
	value=(datH<<8)+datL;//合并为16位数据
	if((value&0xf800)==0xf800)//0xf800(1111 1000 0000 0000)判断符号位,负温度(前五位正负后五位温度)
	{
	value=(~value)+1; //数据取反再加1
	temp=value*(-0.0625);//乘以精度	
	}
	else //正温度
	{
	temp=value*0.0625;	
	}
	return temp;
}

共用函数

#include<reg51.h>
#include "mine.h"
void T0_init()
{
	TMOD=0x01;//设置定时器0
	TH0=0x3c;//装初值
	TL0=0xb0;
	EA=1;//开总中断
	ET0=1;//开定时器0中断
	TR0=1;//启动定时器0
}
void delay10us(uint us)
{
	while(us--);	
}
void delayxms(uint x)
{
	uint i,j;
	for(i=0;i<x;i++)
	for(j=0;j<110;j++);
}

字模提取

在这里插入图片描述

取字模软件
链接:https://pan.baidu.com/s/15w685otALwl1cU_H0WCJKQ
提取码:1111

  • 11
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值