51单片机DS18B20测温LCD1602显示

介绍

通过DS18B20采集温度在LCD1602上显示
第一行显示温度第二行显示精度

Proteus运行仿真图

在这里插入图片描述

源程序

主函数

#include<reg51.h>
#include "mine.h"
uchar code WenDu[]={"Tempture:"};
uchar code JingDu[]={"Accuracy:0.0625"};
uchar code Sz[]={"0123456789"};
int Tempture; 
void main()
{ LCD_Init();
	ds18b20Init();
	ds18b20Start();
	delayxms(1000);
	while(1)
	{
	TemptureDisplay();
	}
}
void TemptureDisplay()
{
	uint i,Bai,Ge,Shi;
	Tempture=ds18b20ReadTemperture()*10;
	/*温度是正还是负*/
	if(Tempture<0)
	 {
	   Tempture=-Tempture;
		 DisplayChar(1,9,'-');
	 }
	 else DisplayChar(1,9,'+');
	 /*取出温度每一位*/
	 Bai=Tempture/100;
	 Ge=Tempture%10;
	 Shi=(Tempture%100)/10;
	 /*显示Tempture:*/
	 for(i=0;i<9;i++)
	 DisplayChar(1,i,WenDu[i]);
	 /*显示Accuracy:*/
	 for(i=0;i<15;i++)
	 DisplayChar(2,i,JingDu[i]);
	 /*显示.°C*/
	 DisplayChar(1,12,'.');
	 DisplayChar(1,14,0xdf);
	 DisplayChar(1,15,'C');
	 /*显示温度整数部分*/
	 DisplayChar(1,10,Sz[Bai]);
	 DisplayChar(1,11,Sz[Shi]);
	 /*显示小数部分*/
	 DisplayChar(1,13,Sz[Ge]);
}

自定义头文件

#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;
/*************************LCD1602模块声明**************************
****************查忙*写数据*写命令*初始化*显示一个字符*************
*******************************************************************/
void Busy();
void W_Data(uchar dat);
void W_Cmd(uchar cmd);
void LCD_Init();
void DisplayChar(uchar y , uchar  x , uchar dat );
sbit rs=P2^0;          
sbit rw=P2^1;  
sbit e=P2^2;
/***********共用模块声明*********
定时器T0初始化*延时10us*延时xms*/
void delay10us(uint us);
void delayxms(uint x);
#endif

LCD1602函数

#include<reg51.h>
#include "mine.h"
/*检查是否忙*/
void Busy()		
{do
  {
		e=0;
		rs=0;
		rw=1;
		P0=0Xff;
		e=1;
  } while (P0^7==1); 
}
/*lcd1602写指令函数*/
void W_Cmd(uchar cmd)
	{
    
    P0=cmd;//要写入的命令
    rs=0; //低电平写指令         
    rw=0; //选择写
		e=0;
	  delayxms(2);
    e=1; 
    delayxms(2);	
    e=0;
}
/*lcd1602写数据函数*/
void W_Data(uchar dat )
{ 
    P0=dat;//要写入的数据
    rs=1;  //高电平写数据         
    rw=0;  //选择写 
    e=0;	
    delayxms(2);  
	  e=1;                
    delayxms(2);  
	  e=0;
}

/*初始化*/
void LCD_Init()
{
  W_Cmd(0x38);//16列两行,8位数据口(指令6)
	W_Cmd(0x0c);//开显示 关光标 不闪烁(指令4)
	W_Cmd(0x06);//写一个数据后,显示位置右移一位(指令3)
	W_Cmd(0x01);//清屏(指令1)
}
/*在指定的位置显示一个字符*/
void DisplayChar(uchar y , uchar  x , uchar dat )
{    
   uchar address;
    if (y==1)                  //等于1使用第一行显示
         address=0x80+x;       //第一行起始地址80H,加x为最终显示字符地址
    else
   address=0xc0+x;             //第二行起始地址c0H,加x为最终显示字符地址
   W_Cmd(address);  //写入地址 
   W_Data(dat);         //写入数据
}

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++);
}
显示负数的时候小数位会有偏差但不知道原因
  • 24
    点赞
  • 157
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
好的,我可以为您提供一些关于51单片机DS18B20测温以及LCD显示的基本知识和代码实现。 1. DS18B20测温原理 DS18B20是一款数字温度传感器,采用单总线接口进行通信,具有精度高、精度可调、线长可达100米等特点,常用于温度测量和控制领域。 DS18B20测温的原理是通过传感器内部的温度传感器将温度转换成数字信号,然后通过单总线接口将数字信号发送到单片机单片机再将数字信号转化为实际温度值进行处理。 2. 51单片机DS18B20测温的连接 DS18B20采用单总线接口进行通信,与51单片机的连接如下: - DS18B20的VCC引脚连接到51单片机的5V电源 - DS18B20的GND引脚连接到51单片机的GND - DS18B20的DQ引脚连接到51单片机的任意I/O口 需要注意的是,DS18B20的DQ引脚需要使用上拉电阻将其拉高。 3. 51单片机和LCD显示的连接 51单片机和LCD显示的连接如下: - LCD的VSS引脚连接到51单片机的GND - LCD的VDD引脚连接到51单片机的5V电源 - LCD的VEE引脚连接到51单片机的可调电位器 - LCD的RS引脚连接到51单片机的任意I/O口 - LCD的RW引脚连接到51单片机的任意I/O口 - LCD的E引脚连接到51单片机的任意I/O口 - LCD的D0-D7引脚连接到51单片机的任意I/O口 需要注意的是,LCD的VEE引脚需要通过可调电位器进行调节,以控制LCD显示的亮度。 4. 代码实现 下面是51单片机通过DS18B20测温并通过LCD显示温度值的代码实现: ``` #include <reg52.h> #include <intrins.h> #define LCD_DPORT P0 sbit LCD_RS = P1^0; sbit LCD_RW = P1^1; sbit LCD_E = P1^2; sbit DQ = P3^7; void delay(unsigned int i) //延时函数 { while(i--); } void lcd_init() //LCD初始化函数 { delay(1000); lcd_cmd(0x38); lcd_cmd(0x0c); lcd_cmd(0x06); lcd_cmd(0x01); } void lcd_cmd(unsigned char cmd) //LCD指令函数 { LCD_RS = 0; LCD_RW = 0; LCD_DPORT = cmd; delay(5); LCD_E = 1; _nop_(); _nop_(); LCD_E = 0; delay(5); } void lcd_data(unsigned char dat) //LCD数据函数 { LCD_RS = 1; LCD_RW = 0; LCD_DPORT = dat; delay(5); LCD_E = 1; _nop_(); _nop_(); LCD_E = 0; delay(5); } void lcd_string(unsigned char *str) //LCD字符串函数 { while(*str != '\0') { lcd_data(*str); str++; } } void lcd_float(float f) //LCD浮点数函数 { unsigned char str[16]; sprintf(str, "%f", f); lcd_string(str); } unsigned char ds18b20_read() //DS18B20读取函数 { unsigned char i; unsigned char dat = 0; for(i = 0; i < 8; i++) { DQ = 0; _nop_(); _nop_(); dat >>= 1; DQ = 1; _nop_(); _nop_(); if(DQ == 1) { dat |= 0x80; } _nop_(); _nop_(); } return dat; } void ds18b20_write(unsigned char dat) //DS18B20写入函数 { unsigned char i; for(i = 0; i < 8; i++) { DQ = 0; _nop_(); _nop_(); if(dat & 0x01) { DQ = 1; } dat >>= 1; _nop_(); _nop_(); DQ = 1; _nop_(); _nop_(); } } void ds18b20_convert() //DS18B20转换函数 { ds18b20_write(0xcc); ds18b20_write(0x44); } void main() //主函数 { unsigned char temp_l, temp_h; int temp; float ftemp; lcd_init(); while(1) { ds18b20_convert(); delay(1000); ds18b20_write(0xcc); ds18b20_write(0xbe); temp_l = ds18b20_read(); temp_h = ds18b20_read(); temp = temp_h; temp <<= 8; temp |= temp_l; ftemp = (float)temp / 16.0; lcd_cmd(0x01); lcd_string("Temp: "); lcd_float(ftemp); lcd_string(" C"); delay(1000); } } ``` 上述代码实现了通过DS18B20测温并通过LCD显示温度值。其中ds18b20_convert()函数用于触发DS18B20转换温度值,ds18b20_write()函数用于向DS18B20写入命令或数据,ds18b20_read()函数用于从DS18B20读取温度值。同时,lcd_float()函数可以将浮点数转化为字符串并在LCD上显示

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值