100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 51单片机DS18B20测温LCD1602显示

51单片机DS18B20测温LCD1602显示

时间:2021-06-23 09:20:38

相关推荐

51单片机DS18B20测温LCD1602显示

文章目录

介绍Proteus运行仿真图源程序主函数自定义头文件LCD1602函数DS18B20共用函数

介绍

通过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为最终显示字符地址elseaddress=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;//检测到ds18b20while((!DQ)&&time_temp<20){time_temp++;delay10us(1);}if(time_temp>=20)return 1;//如果超时则强制返回1return 0;//检测到响应}/*********温度读取(一位)**********/uchar ds18b20ReadBit(){uchar dat=0;DQ=0;_nop_();_nop_();DQ=1;_nop_();_nop_(); //该段时间不能过长,必须在15us内读取数据if(DQ)dat=1;//读1else dat=0;//读0delay10us(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();//检查DS18B20ds18b20WriteByte(0xcc);//SKIP ROMds18b20WriteByte(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 ROMds18b20WriteByte(0xbe);//读存储器datL=ds18b20ReadByte();//低字节datH=ds18b20ReadByte();//高字节value=(datH<<8)+datL;//合并为16位数据if((value&0xf800)==0xf800)//0xf800(1111 1000 0000 0000)判断符号位,负温度(前五位正负后五位温度){value=(~value)+1; //数据取反再加1temp=value*(-0.0625);//乘以精度}else //正温度{temp=value*0.0625;}return temp;}

共用函数

#include<reg51.h>#include "mine.h"void T0_init(){TMOD=0x01;//设置定时器0TH0=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++);}

显示负数的时候小数位会有偏差但不知道原因

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。