LCD1602和DS18B20显示温度
DS18B20与LCD1602的测温显示程序
ds18B20_data = 1; // 拉高总线,延时 15us-60us 后等待ds18B20 响应
delay_15us(2); // 15us-60us
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;
uchar Minus_Flag=0;
uchar code Temp_Disp_Title[]={"Current Temp : "};
uchar Current_Temp_Display_Buffer[]={"TEMP: "};
LCD_RS = 0;
LCD_RW = Байду номын сангаас;
LCD_EN = 0;
_nop_();
_nop_();
LCD_Data = cmd;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
void Write_LCD_Data(uchar dat)
#define ds18B20_ALARM_SEARCH 0xEC // 报警搜索指令
#define ds18B20_WRITE_SCRATCHPAD 0x4E // 写暂存寄存器指令
#define ds18B20_READ_SCRATCHPAD 0xBE // 读暂存寄存器指令
{
while(LCD_Busy_Check());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
基于DS18B20的lcd1602的温度检测系统
1.1、来源在人类的生活环境中,温度扮演着极其重要的角色。
无论你生活在哪里,从事什么工作,无时无刻不在与温度打着交道。
温度无时无刻不在,同样也时时刻刻都在变化,为了让人们能更直观的看出此时此刻此地的实时温度,我就利用了单片机来完成这一功能。
1.2、意义温度的检测与控制在现代经济与社会中有举足轻重的地位,与我们的生活息息相关,密不可分,越发占有一席之地。
例如在储粮仓库、智能楼宇、空调控制及其他的工农业生产和科学研究中应用广泛。
在温度的检测与控制方面,DS18B20小型温度检测系统及其数字温度传感器有许多突出的优点,其通过单总线与单片机连接,系统结构简单,抗干扰能力强,适合于恶劣环境下进行现场温度检测,因此对于我们来设计并研究基于DS18B20的温度检测系统有主要的现实意义,从一方面讲这不仅对于工农业的发展,更对于国防的巩固与建设起到重要的作用;另一方面,本设计能够在一定程度上提高自己的单片机开发能力。
1.3、目的(1)本实验要实现的是通过DS18B20温度传感器采集温度并在LCD上显示,并学会使用单片机控制DS18B20此类单总线器件,并对数字温度传感器DS18B0进行时序分析。
(2)更进一步了解LCD1602的应用。
(3)掌握单片机与PC的远程通信。
2、课题承担人员及分工说明*********:(1)主要负责电路板的制作、焊接与调试。
(2)电路的仿真。
(3)温度主要程序的编写与调试。
**********:(1)Protel画板,材料的收集。
(2)串口的调试与程序编写。
(3)VB界面的设计和上位机程序的编写。
二、课题总体设计说明1、说明总体开发计划和课题所达到的功能目标和技术指标1.1、总体开发计划1.1.1、基本功能(1)以数字传感器DS1820作为前端采集温度,经过单片机处理后,将外部的温度显示在液晶屏上。
(2)可用通过独立式按键来设定温度的上限值和下限值,当坏境温度超过上限值或低于下限值时蜂鸣器会自动报警,并在液晶屏上提示温度大于上限值或温度小于下限值。
51单片机DS18B20测温1602a显示
/*******************************************************************/
void beep()
{
unsigned char y ;
for (y=0 ;y<100 ;y++)
{
Delay(60) ;
BEEP=!BEEP ; //BEEP取反
void lcd_wdat(uchar dat)
{
while(lcd_busy()) ;
LCD_RS = 1 ;
LCD_RW = 0 ;
LCD_EN = 0 ;
P0 = dat ;
delayNOP() ;
LCD_EN = 1 ;
delayNOP() ;
LCD_EN = 0 ;
}
/* LCD初始化设定*/
}
/*******************************************************************/
/*写显示数据到LCD */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。*/
/*******************************************************************/
Disp_Temperature()
{
display[4]=temp_data[0]&0x0f ;
display[0]=ditab[display[4]]+0x30 ; //查表得小数位的值
display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4) ;
读取DS18B20温度,通过LCD1602显示出来,并输出控制
读取DS18B20温度,通过LCD1602显示出来,并输出控制电路原理图程序1.main.c#include #include"lcd.h"#include"temp.h" void LcdDisplay(int); sbit K1=P2^0;sbit K2=P2^1;sbit K3=P2^2;sbit K4=P2^3; extern int th=20; extern int tl=-10; sbit beep=P1^0;void main(){LcdInit(); LcdWriteCom(0xc7); LcdWriteData('C'); while(1){if(K1==0){Delay1ms(500);if(K1==0);th++;}if(K2==0){Delay1ms(500);if(K2==0);th--;}if(K3==0){Delay1ms(500);if(K3==0);tl++;}if(K4==0){Delay1ms(500);if(K4==0);tl--;}LcdDisplay(Ds18b20ReadTemp());}}void LcdDisplay(int temp){int i,tt,rr,mm;unsigned char datas[] = {0, 0, 0, 0},datas1[] = {0, 0, 0},datas2[] = {0, 0, 0};float tp;if(temp< 0){LcdWriteCom(0xc0);LcdWriteData('-');i=1;temp=temp-1;temp=~temp;tp=temp;temp=tp*0.0625*10+0.5;mm=-temp;}else{LcdWriteCom(0xc0);LcdWriteData('+');tp=temp;temp=tp*0.0625*10+0.5;mm=temp;}datas[0] = temp / 1000; datas[1] = temp % 1000 / 100; datas[2] = temp % 100 / 10; datas[3] = temp% 10;if(th < 0){LcdWriteCom(0x89);LcdWriteData('-');tt=-th;}else{LcdWriteCom(0x89);LcdWriteData('+');tt=th;}datas1[0] = tt / 100;datas1[1] = tt% 100 / 10; datas1[2] = tt % 10; LcdWriteCom(0x87); LcdWriteData('H'); LcdWriteCom(0x88); LcdWriteData(':'); LcdWriteCom(0x8a); LcdWriteData('0'+datas1[0]); LcdWriteCom(0x8b); LcdWriteData('0'+datas1[1]); LcdWriteCom(0x8c); LcdWriteData('0'+datas1[2]);if(tl < 0){LcdWriteCom(0x90);LcdWriteData('-');rr=-tl;}else{LcdWriteCom(0x90);LcdWriteData('+');rr=tl;}datas2[0] = rr / 100;datas2[1] = rr% 100 / 10; datas2[2] = rr % 10; LcdWriteCom(0x8e); LcdWriteData('L'); LcdWriteCom(0x8f); LcdWriteData(':'); LcdWriteCom(0x91); LcdWriteData('0'+datas2[0]); LcdWriteCom(0x92);LcdWriteData('0'+datas2[1]); LcdWriteCom(0x93); LcdWriteData('0'+datas2[2]);if(mm>=(th*10)||mm<=(tl*10)||th<=tl) beep=0;elsebeep=1;LcdWriteCom(0x80); LcdWriteData('T');LcdWriteCom(0x81); LcdWriteData('A');LcdWriteCom(0x82); LcdWriteData('I');LcdWriteData(' ');LcdWriteCom(0x84); LcdWriteData('A');LcdWriteCom(0x85); LcdWriteData('N');LcdWriteCom(0xc1); LcdWriteData('0'+datas[0]); LcdWriteCom(0xc2); LcdWriteData('0'+datas[1]);LcdWriteCom(0xc3);LcdWriteData('0'+datas[2]);LcdWriteCom(0xc4);LcdWriteData('.');LcdWriteCom(0xc5);LcdWriteData('0'+datas[3]);LcdWriteCom(0xc6);LcdWriteData('"');}2.lcd.h#ifndef __LCD_H_/********************************** 当使用的是4位数据传输的时候定义,使用8位取消这个定义**********************************/ #define LCD1602_4PINS /********************************** 包含头文件#include//---重定义关键词---//#ifndef uchar#define uchar unsigned char#endif#ifndef uint#define uint unsigned int#endif/********************************** PIN口定义**********************************/ #define LCD1602_DATAPINS P0sbit LCD1602_E=P2^7;sbit LCD1602_RW=P2^5;sbit LCD1602_RS=P2^6;/********************************** 函数声明/*在51单片机12MHZ时钟下的延时函数*/ void Lcd1602_Delay1ms(uint c); //误差0us /*LCD1602写入8位命令子函数*/void LcdWriteCom(uchar com);/*LCD1602写入8位数据子函数*/void LcdWriteData(uchar dat) ;/*LCD1602初始化子程序*/void LcdInit();#endif3.temp.h#define __TEMP_H_#includesbit DSPORT=P3^7;void Delay1ms(unsigned int );unsigned char Ds18b20Init();void Ds18b20WriteByte(unsigned char com); unsigned char Ds18b20ReadByte();void Ds18b20ChangTemp();void Ds18b20ReadTempCom();int Ds18b20ReadT emp();#endif4.lcd.c#include"lcd.h"void Lcd1602_Delay1ms(uint c) //延时{uchar a,b;for (; c>0; c--){for (b=19;b>0;b--){for(a=1;a>0;a--);}}}#ifndef LCD1602_4PINS //当没有定义这个LCD1602_4PINS时void LcdWriteCom(uchar com) //写入一个字节命令{LCD1602_E = 0;LCD1602_RS = 0;LCD1602_RW = 0;LCD1602_DATAPINS = com;Lcd1602_Delay1ms(1);LCD1602_E = 1;Lcd1602_Delay1ms(5);LCD1602_E = 0;}#elsevoid LcdWriteCom(uchar com){LCD1602_E = 0;LCD1602_RW = 0;LCD1602_DATAPINS = com; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改Lcd1602_Delay1ms(1);LCD1602_E = 1;Lcd1602_Delay1ms(5);LCD1602_E = 0;LCD1602_DATAPINS = com << 4; //发送低四位Lcd1602_Delay1ms(1);LCD1602_E = 1;Lcd1602_Delay1ms(5);LCD1602_E = 0;}#endif#ifndef LCD1602_4PINSvoid LcdWriteData(uchar dat) //写入一个字节数据{LCD1602_E = 0;LCD1602_RS = 1;LCD1602_DATAPINS = dat;Lcd1602_Delay1ms(1);LCD1602_E = 1;Lcd1602_Delay1ms(5);LCD1602_E = 0;}#elsevoid LcdWriteData(uchar dat){LCD1602_E = 0;LCD1602_RS = 1;LCD1602_RW = 0;LCD1602_DATAPINS = dat; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改Lcd1602_Delay1ms(1);LCD1602_E = 1; //写入时序Lcd1602_Delay1ms(5);LCD1602_E = 0;LCD1602_DATAPINS = dat << 4; //写入低四位Lcd1602_Delay1ms(1);LCD1602_E = 1; //写入时序Lcd1602_Delay1ms(5);LCD1602_E = 0;}#endif#ifndef LCD1602_4PINSvoid LcdInit() //LCD初始化子程序{LcdWriteCom(0x38);LcdWriteCom(0x0c);LcdWriteCom(0x06);LcdWriteCom(0x01);LcdWriteCom(0x80);}#elsevoid LcdInit(){LcdWriteCom(0x32); LcdWriteCom(0x28); LcdWriteCom(0x0c); LcdWriteCom(0x06); LcdWriteCom(0x01); LcdWriteCom(0x80);}#endif5.temp.c#include"temp.h"void Delay1ms(unsigned int y) //延时{ unsigned int x;for(y;y>0;y--)for(x=110;x>0;x--);}unsigned char Ds18b20Init() //初始化{ unsigned int i;DSPORT=0;i=70;while(i--);DSPORT=1;i=0;while(DSPORT){i++;if(i>5000)return 0;//失败}return 1;//成功}void Ds18b20WriteByte(unsigned char dat) //写字节{unsigned int i,j;for(j=0;j<8;j++){DSPORT=0; //每写入一位数据之前先把总线拉低1us (数据手册上模糊)i++;DSPORT=dat&0x01;i=6;while(i--);DSPORT=1;dat>>=1;}}unsigned char Ds18b20ReadByte(){unsigned char byte,bi;unsigned int i,j;for(j=8;j>0;j--){DSPORT=0;i++;DSPORT=1;i++;i++;bi=DSPORT;byte=(byte>>1)|(bi<<7);i=4;while(i--);}return byte;}void Ds18b20ChangTemp() //温度转换{Ds18b20Init();Delay1ms(1);Ds18b20WriteByte(0xcc);Ds18b20WriteByte(0x44);}void Ds18b20ReadTempCom() //读取温度命令{ Ds18b20Init();Delay1ms(1);Ds18b20WriteByte(0xcc);Ds18b20WriteByte(0xbe);}int Ds18b20ReadT emp() //读取温度{int temp=0;unsigned char tmh,tml;Ds18b20ChangT emp();Ds18b20ReadTempCom();tml=Ds18b20ReadByte();tmh=Ds18b20ReadByte();temp=tmh;temp<<=8;temp|=tml;。
51单片机ds18b20和lcd1602显示温度
/*本程序为基于51单片机的DS18b20与lcd1602显示温度程序,1602数据线友P0口提供*/程序已通过硬件测试直接使用作者:liuzqiang1016#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit DQ=P2^0;//ds18b20sbit lcd_rw=P2^5;sbit lcd_rs=P2^6;sbit lcd_en=P2^7;unsigned char code str1[]={"temperature: "};unsigned char code str2[16]={" "};uchar data disdata[5];uint value;//温度值uchar flag;//正负标志/*************************lcd1602程序**************************/void delay1ms(unsigned int ms)//延时1毫秒(不够精确的){unsigned int i,j;for(i=0;i<ms;i++)for(j=0;j<100;j++);}void write_com(unsigned char com)//写指令//{ delay1ms(1);lcd_rs=0;lcd_rw=0;lcd_en=0;P0=com;delay1ms(1);lcd_en=1;delay1ms(1);lcd_en=0;}void write_dat(unsigned char dat)//写数据//{ delay1ms(1);;lcd_rs=1;lcd_rw=0;lcd_en=0;P0=dat;delay1ms(1);lcd_en=1;delay1ms(1);lcd_en=0;}void lcd_init()//初始化设置//{write_com(0x38);delay1ms(5);write_com(0x08);delay1ms(5);write_com(0x01);delay1ms(5);write_com(0x06);delay1ms(5);write_com(0x0c);delay1ms(5);}void display(unsigned char *p)//显示//{while(*p!='\0'){write_dat(*p);p++;delay1ms(1);}}init_play()//初始化显示{ lcd_init();write_com(0x80);display(str1);write_com(0xc0);display(str2);}void delay_18B20(unsigned int i)//延时1微秒{while(i--);}void ds1820rst()/*ds1820复位*/{unsigned char x=0;DQ = 1; //DQ复位delay_18B20(4); //延时DQ = 0; //DQ拉低delay_18B20(100); //精确延时大于480usDQ = 1; //拉高delay_18B20(40);}uchar ds1820rd()/*读数据*/{unsigned char i=0;unsigned char dat = 0;for (i=8;i>0;i--){ DQ = 0; //给脉冲信号dat>>=1;DQ = 1; //给脉冲信号if(DQ)dat|=0x80;delay_18B20(10);}return(dat);}void ds1820wr(uchar wdata)/*写数据*/ {unsigned char i=0;for (i=8; i>0; i--){ DQ = 0;DQ = wdata&0x01;delay_18B20(10);DQ = 1;wdata>>=1;}}read_temp()/*读取温度值并转换*/{uchar a,b;ds1820rst();ds1820wr(0xcc);//*跳过读序列号*/ds1820wr(0x44);//*启动温度转换*/ds1820rst();ds1820wr(0xcc);//*跳过读序列号*/ds1820wr(0xbe);//*读取温度*/a=ds1820rd();b=ds1820rd();value=b;value<<=8;value=value|a;if(value<0x0fff)flag=0;else{value=~value+1;flag=1;}value=value*(0.625);//温度值扩大10倍,精确到1位小数return(value);}/*******************************************************************/ void ds1820disp()//温度值显示{ uchar flagdat;disdata[0]=value/1000+0x30;//百位数disdata[1]=value%1000/100+0x30;//十位数disdata[2]=value%100/10+0x30;//个位数disdata[3]=value%10+0x30;//小数位if(flag==0)flagdat=0x20;//正温度不显示符号elseflagdat=0x2d;//负温度显示负号:-if(disdata[0]==0x30){disdata[0]=0x20;//如果百位为0,不显示if(disdata[1]==0x30){disdata[1]=0x20;//如果百位为0,十位为0也不显示}}write_com(0xc0);write_dat(flagdat);//显示符号位write_com(0xc1);write_dat(disdata[0]);//显示百位write_com(0xc2);write_dat(disdata[1]);//显示十位write_com(0xc3);write_dat(disdata[2]);//显示个位write_com(0xc4);write_dat(0x2e);//显示小数点write_com(0xc5);write_dat(disdata[3]);//显示小数位}/********************主程序***********************************/ void main(){ init_play();//初始化显示while(1){read_temp();//读取温度ds1820disp();//显示}}。
DS18b20传感器利用1602显示温度电路图
DS18b20传感器利用1602显示温度电路图(附代码)*重要注:图中没有画出单片机最小系统,另外在实际焊接中1602 的1,2,3,15,16引脚要按下图焊接,其他引脚看上图,另外要加排阻;其次ds18b20焊接时要注意引脚,不要焊反。
下面说明书中给出的是bottom view,分清引脚后18b20直接按上图焊即可。
Ds18b20说明书:代码:#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit ds=P2^2;sbit rs=P3^5;sbit wr=P3^6;sbit lcden=P3^4;uint temp;bit flag;uchar code table1[]="temperature is:"; void delay(uchar x)//延时函数_ms{uchar a,b;for(a=x;a>0;a--)for(b=120;b>0;b--);}/* 18b20 */void delayus(uint t)//延时函数_us{while(t--);}void z_reset()//单总线复位{ds=1;delayus(5);ds=0;delayus(80);ds=1;delayus(14);if(ds==0)flag=1;elseflag=0;delayus(20);}bit z_bit_read()//总线读一位{bit dat;ds=0;_nop_();_nop_();ds=1;_nop_();dat=ds;delayus(10);return dat;}uchar ds_read_byte()//18b20读一字节{uchar i,k,j;for(i=0;i<8;i++){j=z_bit_read();k=(k>>1)|(j<<7);}return k;}void ds_write_byte(uchar dat)//18b20写一字节{uchar i;for(i=0;i<8;i++){ds=0;_nop_();ds=dat&0x01;delayus(6);ds=1;dat=dat>>1;}delayus(6);}uint ds_read_temperature()//从18b20读温度{uchar a,b;z_reset();ds_write_byte(0xcc);ds_write_byte(0xbe);a=ds_read_byte();b=ds_read_byte();temp=b;temp=temp<<8;temp=temp|a;temp=temp*0.0625*10;return temp;}/* 1602 */void write_com(uchar com)//1602写命令{rs=0;wr=0;lcden=0;P0=com;lcden=1;delay(5);lcden=0;}void write_data(uchar dat)//1602写数据{rs=1;wr=0;lcden=0;P0=dat;lcden=1;delay(5);lcden=0;}void init()//1602初始化{write_com(0x38);write_com(0x08);write_com(0x01);write_com(0x06);write_com(0x0f);}main(){uint c,num;uchar i,j,k,z;P0=0;init();for(num=0;num<15;num++) //1602静态显示第一行{write_data(table1[num]);delay(300);}while(1){z_reset();ds_write_byte(0xcc);ds_write_byte(0x44);c=ds_read_temperature(); //读到温度write_com(0x80+0x40); //从第二行写i=c/100;//得十位j=c/10-c/100*10;//得各位k=c%10;//得十分位z='.';write_data(0x30+i);//1602显示数字只能输入ASCII码write_data(0x30+j);write_data(z);write_data(0x30+k);delay(300);}}。
DS18B20温度采集+1602显示
/*************************************************************************************************************** 名称:DS18B20采集温度+1602LCD显示编写:超时间:2012-11-29内容:***************************************************************************************************************/ #include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit DQ=P3^7; //ds18b20与单片机连接口sbit RS=P3^0; //1602写数据/写命令选择端口//RS=1写数据,即要显示的内容//RS=0写命令,即一些LCD设置命令sbit RW=P3^1; //1602读/写选择端,RW=0为写模式sbit EN=P3^2; //给EN一个高脉冲,将数据送入液晶控制器,完成写操作uchar code str1[]={"^_^ Zhang Chao"};uchar code str2[]={" T= "};uchar data disdata[5];//百、十、个、小数位uint tvalue; //温度值uchar tflag; //温度正负标志/*************************lcd1602设置子函数*******************************************************************/ void delay1ms(uint ms) //延时1毫秒子函数,形参为ms(不够精确的){unsigned int i,j;for(i=0;i<ms;i++)for(j=0;j<110;j++);}void wr_com(uchar com)//lcd写控制指令子函数,形参为com{delay1ms(1); //调用延时子函数,并用实参1代替延时子函数中的形参msRS=0; //RS=0进入写命令状态,即一些LCD设置命令RW=0; //RW=0为写模式EN=0; //EN=0时不能完成写操作P2=com; //把要设置的指令码com送给P2口delay1ms(1);EN=1; //给EN一个高脉冲,将数据送入液晶控制器,完成写操作delay1ms(1);EN=0; //EN=0时不能完成写操作}void wr_dat(uchar dat)//lcd写显示数据子函数,形参为dat{delay1ms(1);RS=1; //RS=1进入写数据状态,即要显示的内容RW=0; //RW=0为写模式EN=0; //EN=0时不能完成写操作P2=dat; //把要显示的数据dat送给P2口delay1ms(1);EN=1; //给EN一个高脉冲,将数据送入液晶控制器,完成写操作delay1ms(1);EN=0; //EN=0时不能完成写操作}void lcd_init() //lcd初始化设置子函数,不带参数,0x38是显示模式设置,其余是显示开/关及光标设置,无顺序{delay1ms(15);wr_com(0x38); //调用写控制指令子函数,并用实参"0011 1000"代替形参com//0x38表示设置为16*2显示,每个块为5*7点阵,8位数据接口delay1ms(5);wr_com(0x08); //调用写控制指令子函数,并用实参"0000 1000"代替形参com//0x08表示设置为关显示、不显示光标、光标不闪烁delay1ms(5);wr_com(0x01); //调用写控制指令子函数,并用实参"0000 0001"代替形参com//0x01表示显示数据清屏(数据指针清0,所有显示清0)delay1ms(5);wr_com(0x06);//调用写控制指令子函数,并用实参"0000 0110"代替形参com//0x06表示当读或写一个字符后地址指针加1,且光标加1;当写一个字符时,整屏显示不移动delay1ms(5);wr_com(0x0c);//调用写控制指令子函数,并用实参"0000 1100"代替形参com//0x0c打开显示、不显示光标、光标不闪烁delay1ms(5);}void display(uchar *p)//lcd显示字符串子函数{while(*p!='\0') //测试是否等于'\0',即判断是否结尾{wr_dat(*p); //显示指针所指的字符串p++; //指针加1delay1ms(1);}}init_play()//初始化显示子函数{lcd_init(); //调用lcd初始化设置子函数,对LCD进行初始化wr_com(0x80); //调用写控制指令子函数,并用实参"1000 0000"代替形参com//并将数据指针定位到第一行第一个字符处display(str1);//从第一行第一个字符处显示字符串str1wr_com(0x80+0x40);//调用写控制指令子函数,并用实参"1000 0000"代替形参com//并将数据指针定位到第二行第一个字符处display(str2); //从第二行第一个字符处显示字符串str2}/**************************************************************************************************************//******************************ds18b20程序******************************************************************/ void delay_18b20(uint i)//延时1微秒{while(i--);}void ds18b20rst() //ds18b20初始化子函数//要求"数据线拉高-延时-数据线拉低-延时大于480微妙-数据线拉高-延时等待" {uchar x=0;DQ = 1; //信号线DQ复位delay_18b20(4); //延时DQ = 0; //DQ拉低delay_18b20(100); //精确延时大于480usDQ = 1; //拉高delay_18b20(40);}void ds18b20wr(uchar wdata)/*写数据子函数,无返回值,含参数*/{uchar i=0;for (i=8; i>0; i--)//要写完一个字节,故需要重复8次以下操作{DQ = 0; //数据线拉低DQ = wdata&0x01;//wdata是一个形参,将其与0000 0001进行按位与//按从低到高的顺序发送数据(一次发送一位)delay_18b20(10);DQ = 1; //最后将数据线拉高wdata>>=1; //将wdata右移1位}}uchar ds18b20rd() //读数据子函数,是有返回值dat{uchar i=0;uchar dat = 0;for (i=8;i>0;i--)//要读完一个字节,故需要重复8次以下操作{DQ = 0; //给脉冲信号dat>>=1;DQ = 1; //给脉冲信号if(DQ)dat|=0x80;delay_18b20(10);}return(dat); //返回dat}read_temp() //读取温度值并转换的子函数,有返回值温度值tvalue{uchar a,b;ds18b20rst(); //调用ds18b20初始化子函数ds18b20wr(0xcc);//调用写数据子函数,向ds18b20写命令0xcc//ccH表示跳过ROM读序列号,适用于单机工作,直接向18b20发送温度变换命令ds18b20wr(0x44);//调用写数据子函数,向ds18b20写命令0x44//44H表示启动ds18b20温度转换,结果自行存入9字节的RAM中ds18b20rst(); //调用ds18b20初始化子函数ds18b20wr(0xcc);//同上ds18b20wr(0xbe);//调用写数据子函数,向ds18b20写命令0xbe//beH表示读取RAM中9字节的温度数据a=ds18b20rd(); //调用读数据子函数,并将所得数据给ab=ds18b20rd(); //tvalue=b; //把b的值给tvaluetvalue<<=8; //tvalue左移8位tvalue=tvalue|a;//tvalue与a进行按位或if(tvalue<0x0fff)//tflag=0; //前五位为0时,读取的温度为正,标志位为0,此时只要//将测得数值乘以0.0625即可得到实际温度else //前五位为1时,读取的温度为负,标志位为1,此时需要{ //将测得数值取反后再加1,再乘以0.0625即可得到实际温度tvalue=~tvalue+1;tflag=1; //此时表示负温度}tvalue=tvalue*(0.625);//温度值扩大10倍,精确到1位小数return(tvalue); //返回温度值}/*************************************************************************************************************//************************温度值显示**************************************************************************/ void ds18b20disp()//温度值显示{uchar flagdat;disdata[0]=tvalue/1000+0x30; //百位数disdata[1]=tvalue%1000/100+0x30;//十位数disdata[2]=tvalue%100/10+0x30; //个位数disdata[3]=tvalue%10+0x30; //小数位if(tflag==0)flagdat=0x2b; //正温度显示符号:+elseflagdat=0x2d; //负温度显示负号:-if(disdata[0]==0x30){disdata[0]=0x20; //如果百位为0,不显示if(disdata[1]==0x30){disdata[1]=0x20; //如果百位为0,十位为0也不显示}}wr_com(0x80+0x46); //定位数据指针的位置:第二行第六个字符处wr_dat(flagdat); //显示符号位wr_com(0x80+0x47); //定位数据指针的位置:第二行第七个字符处wr_dat(disdata[0]); //显示百位wr_com(0x80+0x48); //定位数据指针的位置:第二行第八个字符处wr_dat(disdata[1]); //显示十位wr_com(0x80+0x49); //定位数据指针的位置:第二行第九个字符处wr_dat(disdata[2]); //显示个位wr_com(0x80+0x4a); //定位数据指针的位置:第二行第十个字符处wr_dat(0x2e); //显示小数点wr_com(0x80+0x4b); //定位数据指针的位置:第二行第十一个字符处wr_dat(disdata[3]); //显示小数位}/**************************************************************************************************************//********************主程序*********************************************************************************/ void main(){init_play(); //调用lcd初始化显示子函数while(1){read_temp(); //调用ds18b20读取温度ds18b20disp(); //调用温度显示子函数}}/************************************************************************************************************/。
DS18B20与LCD1602结合显示温度汇总
二、DS18B20存储器结构
DS18B20的内部有64位的ROM单元,和9字节的暂存器单元。
1、64位(激)光刻只读存储器
每只DS18B20都有一个唯一存储在ROM中的64位编码(跟人的身份证号类似,一人一个身份证号),这是出厂时被光刻好的。最前面8位是单线系列编码:28h。接着的48位是一个唯一的序列号。最后8位是以上56位的CRC编码。64-位的光刻ROM又包括5个ROM的功能命令:读ROM,匹配ROM,跳跃ROM,查找ROM和报警查找。ROM的作用是使每个DS18B20各不相同,这样就可以实现一根总线上挂接多个DS18B20以实现多点监测。
图3
表2
4)、CRC发生器
CRC字节作为DS18B2064位ROM的一部分存储在存储器中。CRC码由ROM的前56位计算得到,被包含在ROM的重要字节当中的数据发生改变时,CRC的值也随之改变。
CRC能够在总线控制器读取DS18B20时进行数据校验。为校验数据是否被正确读取,总线控制器必须用接受到的数据计算出一个CRC值,和存储在DS18B20的64位ROM中的值(读ROM时)或DS18B20内部计算出的8位CRC值(读存储器时)进行比较。如果计算得到的CRC值和读取出来的CRC值相吻合,数据被无错传输。CRC值的比较以及是否进行下一步操作完全由总线控制器决定。当在DS18B20中存储的或由其计算到CRC值和总线控制器计算的值不相符时,DS18B20内部并没有一个能阻止命令序列进行的电路。
2)、非挥发的温度报警触发器TH和TL
位于第2和第3字节,用于写入温度报警值,实际上就是设定温度的最高和最低界限。
读取DS18B20温度,通过LCD1602显示出来,并输出控制讲解
电路原理图程序1.main.c#include<reg51.h> #include"lcd.h"#include"temp.h" void LcdDisplay(int); sbit K1=P2^0;sbit K2=P2^1;sbit K3=P2^2;sbit K4=P2^3; extern int th=20; extern int tl=-10; sbit beep=P1^0;void main(){LcdInit();LcdWriteCom(0xc7);LcdWriteData('C');while(1){if(K1==0){Delay1ms(500);if(K1==0);th++;}if(K2==0){Delay1ms(500);if(K2==0);th--;}if(K3==0){Delay1ms(500);if(K3==0);tl++;}if(K4==0){Delay1ms(500);if(K4==0);tl--;}LcdDisplay(Ds18b20ReadTemp());}}void LcdDisplay(int temp){int i,tt,rr,mm;unsigned char datas[] = {0, 0, 0, 0},datas1[] = {0, 0, 0},datas2[] = {0, 0, 0};float tp;if(temp< 0){LcdWriteCom(0xc0);LcdWriteData('-');i=1;temp=temp-1;temp=~temp;tp=temp;temp=tp*0.0625*10+0.5;mm=-temp;}else{LcdWriteCom(0xc0);LcdWriteData('+');tp=temp;temp=tp*0.0625*10+0.5;mm=temp;}datas[0] = temp / 1000; datas[1] = temp % 1000 / 100; datas[2] = temp % 100 / 10; datas[3] = temp% 10;if(th < 0){LcdWriteCom(0x89);LcdWriteData('-');tt=-th;}else{LcdWriteCom(0x89);LcdWriteData('+');tt=th;}datas1[0] = tt / 100;datas1[1] = tt% 100 / 10; datas1[2] = tt % 10; LcdWriteCom(0x87); LcdWriteData('H'); LcdWriteCom(0x88); LcdWriteData(':'); LcdWriteCom(0x8a); LcdWriteData('0'+datas1[0]); LcdWriteCom(0x8b); LcdWriteData('0'+datas1[1]); LcdWriteCom(0x8c); LcdWriteData('0'+datas1[2]);if(tl < 0){LcdWriteCom(0x90);LcdWriteData('-');rr=-tl;}else{LcdWriteCom(0x90);LcdWriteData('+');rr=tl;}datas2[0] = rr / 100;datas2[1] = rr% 100 / 10; datas2[2] = rr % 10; LcdWriteCom(0x8e); LcdWriteData('L'); LcdWriteCom(0x8f); LcdWriteData(':'); LcdWriteCom(0x91); LcdWriteData('0'+datas2[0]); LcdWriteCom(0x92);LcdWriteData('0'+datas2[1]); LcdWriteCom(0x93); LcdWriteData('0'+datas2[2]);if(mm>=(th*10)||mm<=(tl*10)||th<=tl) beep=0;elsebeep=1;LcdWriteCom(0x80); LcdWriteData('T');LcdWriteCom(0x81); LcdWriteData('A');LcdWriteCom(0x82); LcdWriteData('I');LcdWriteData(' ');LcdWriteCom(0x84); LcdWriteData('A');LcdWriteCom(0x85); LcdWriteData('N');LcdWriteCom(0xc1); LcdWriteData('0'+datas[0]); LcdWriteCom(0xc2); LcdWriteData('0'+datas[1]);LcdWriteCom(0xc3);LcdWriteData('0'+datas[2]);LcdWriteCom(0xc4);LcdWriteData('.');LcdWriteCom(0xc5);LcdWriteData('0'+datas[3]);LcdWriteCom(0xc6);LcdWriteData('"');}2.lcd.h#ifndef __LCD_H_#define __LCD_H_/********************************** 当使用的是4位数据传输的时候定义,使用8位取消这个定义**********************************/ #define LCD1602_4PINS/********************************** 包含头文件#include<reg51.h>//---重定义关键词---//#ifndef uchar#define uchar unsigned char#endif#ifndef uint#define uint unsigned int#endif/********************************** PIN口定义**********************************/ #define LCD1602_DATAPINS P0sbit LCD1602_E=P2^7;sbit LCD1602_RW=P2^5;sbit LCD1602_RS=P2^6;/********************************** 函数声明/*在51单片机12MHZ时钟下的延时函数*/ void Lcd1602_Delay1ms(uint c); //误差0us /*LCD1602写入8位命令子函数*/void LcdWriteCom(uchar com);/*LCD1602写入8位数据子函数*/void LcdWriteData(uchar dat) ;/*LCD1602初始化子程序*/void LcdInit();#endif3.temp.h#ifndef __TEMP_H_#define __TEMP_H_#include<reg51.h>sbit DSPORT=P3^7;void Delay1ms(unsigned int );unsigned char Ds18b20Init();void Ds18b20WriteByte(unsigned char com); unsigned char Ds18b20ReadByte();void Ds18b20ChangTemp();void Ds18b20ReadTempCom();int Ds18b20ReadTemp();#endif4.lcd.c#include"lcd.h"void Lcd1602_Delay1ms(uint c) //延时{uchar a,b;for (; c>0; c--){for (b=19;b>0;b--){for(a=1;a>0;a--);}}}#ifndef LCD1602_4PINS //当没有定义这个LCD1602_4PINS时void LcdWriteCom(uchar com) //写入一个字节命令{LCD1602_E = 0;LCD1602_RS = 0;LCD1602_RW = 0;LCD1602_DATAPINS = com;Lcd1602_Delay1ms(1);LCD1602_E = 1;Lcd1602_Delay1ms(5);LCD1602_E = 0;}#elsevoid LcdWriteCom(uchar com){LCD1602_E = 0;LCD1602_RW = 0;LCD1602_DATAPINS = com; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改Lcd1602_Delay1ms(1);LCD1602_E = 1;Lcd1602_Delay1ms(5);LCD1602_E = 0;LCD1602_DATAPINS = com << 4; //发送低四位Lcd1602_Delay1ms(1);LCD1602_E = 1;Lcd1602_Delay1ms(5);LCD1602_E = 0;}#endif#ifndef LCD1602_4PINSvoid LcdWriteData(uchar dat) //写入一个字节数据{LCD1602_E = 0;LCD1602_RS = 1;LCD1602_DATAPINS = dat;Lcd1602_Delay1ms(1);LCD1602_E = 1;Lcd1602_Delay1ms(5);LCD1602_E = 0;}#elsevoid LcdWriteData(uchar dat){LCD1602_E = 0;LCD1602_RS = 1;LCD1602_RW = 0;LCD1602_DATAPINS = dat; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改Lcd1602_Delay1ms(1);LCD1602_E = 1; //写入时序Lcd1602_Delay1ms(5);LCD1602_E = 0;LCD1602_DATAPINS = dat << 4; //写入低四位Lcd1602_Delay1ms(1);LCD1602_E = 1; //写入时序Lcd1602_Delay1ms(5);LCD1602_E = 0;}#endif#ifndef LCD1602_4PINSvoid LcdInit() //LCD初始化子程序{LcdWriteCom(0x38);LcdWriteCom(0x0c);LcdWriteCom(0x06);LcdWriteCom(0x01);LcdWriteCom(0x80);}#elsevoid LcdInit(){LcdWriteCom(0x32);LcdWriteCom(0x28);LcdWriteCom(0x0c);LcdWriteCom(0x06);LcdWriteCom(0x01);LcdWriteCom(0x80);}#endif5.temp.c#include"temp.h"void Delay1ms(unsigned int y) //延时{unsigned int x;for(y;y>0;y--)for(x=110;x>0;x--);}unsigned char Ds18b20Init() //初始化{unsigned int i;DSPORT=0;i=70;while(i--);DSPORT=1;i=0;while(DSPORT){i++;if(i>5000)return 0;//失败}return 1;//成功}void Ds18b20WriteByte(unsigned char dat) //写字节{unsigned int i,j;for(j=0;j<8;j++){DSPORT=0; //每写入一位数据之前先把总线拉低1us (数据手册上模糊)i++;DSPORT=dat&0x01;i=6;while(i--);DSPORT=1;dat>>=1;}}unsigned char Ds18b20ReadByte(){unsigned char byte,bi;unsigned int i,j;for(j=8;j>0;j--){DSPORT=0;i++;DSPORT=1;i++;i++;bi=DSPORT;byte=(byte>>1)|(bi<<7);i=4;while(i--);}return byte;}void Ds18b20ChangTemp() //温度转换{Ds18b20Init();Delay1ms(1);Ds18b20WriteByte(0xcc);Ds18b20WriteByte(0x44);}void Ds18b20ReadTempCom() //读取温度命令{Ds18b20Init();Delay1ms(1);Ds18b20WriteByte(0xcc);Ds18b20WriteByte(0xbe);}int Ds18b20ReadTemp() //读取温度{int temp=0;unsigned char tmh,tml;Ds18b20ChangTemp();Ds18b20ReadTempCom();tml=Ds18b20ReadByte();tmh=Ds18b20ReadByte();temp=tmh;temp<<=8;temp|=tml;return temp; }。
DS18B20温度计 c程序 lcd1602显示(word文档良心出品)
2007-12-14 19:05温度值精确到0.1度,lcd1602显示仿真电路图如下c程序如下:#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit DQ=P3^7;//ds18b20与单片机连接口sbit RS=P3^0;sbit RW=P3^1;sbit EN=P3^2;unsigned char code str1[]={"temperature: "};unsigned char code str2[]={" "};uchar data disdata[5];uint tvalue;//温度值uchar tflag;//温度正负标志/*************************lcd1602程序**************************/ void delay1ms(unsigned int ms)//延时1毫秒(不够精确的){unsigned int i,j;for(i=0;i<ms;i++)for(j=0;j<100;j++);}void wr_com(unsigned char com)//写指令//{ delay1ms(1);RS=0;RW=0;EN=0;P2=com;delay1ms(1);EN=1;delay1ms(1);EN=0;}void wr_dat(unsigned char dat)//写数据//{ delay1ms(1);;RS=1;RW=0;EN=0;P2=dat;delay1ms(1);EN=1;delay1ms(1);EN=0;}void lcd_init()//初始化设置//{delay1ms(15);wr_com(0x38);delay1ms(5);wr_com(0x08);delay1ms(5);wr_com(0x01);delay1ms(5);wr_com(0x06);delay1ms(5);wr_com(0x0c);delay1ms(5);}void display(unsigned char *p)//显示//{while(*p!='\0'){wr_dat(*p);p++;delay1ms(1);}}init_play()//初始化显示{ lcd_init();wr_com(0x80);display(str1);wr_com(0xc0);display(str2);}/******************************ds1820程序***************************************/ void delay_18B20(unsigned int i)//延时1微秒{while(i--);}void ds1820rst()/*ds1820复位*/{ unsigned char x=0;DQ = 1; //DQ复位delay_18B20(4); //延时DQ = 0; //DQ拉低delay_18B20(100); //精确延时大于480usDQ = 1; //拉高delay_18B20(40);}uchar ds1820rd()/*读数据*/{ unsigned char i=0;unsigned char dat = 0;for (i=8;i>0;i--){ DQ = 0; //给脉冲信号dat>>=1;DQ = 1; //给脉冲信号if(DQ)dat|=0x80;delay_18B20(10);}return(dat);}void ds1820wr(uchar wdata)/*写数据*/{unsigned char i=0;for (i=8; i>0; i--){ DQ = 0;DQ = wdata&0x01;delay_18B20(10);DQ = 1;wdata>>=1;}}read_temp()/*读取温度值并转换*/{uchar a,b;ds1820rst();ds1820wr(0xcc);//*跳过读序列号*/ds1820wr(0x44);//*启动温度转换*/ds1820rst();ds1820wr(0xcc);//*跳过读序列号*/ds1820wr(0xbe);//*读取温度*/a=ds1820rd();b=ds1820rd();tvalue=b;tvalue<<=8;tvalue=tvalue|a;if(tvalue<0x0fff)tflag=0;else{tvalue=~tvalue+1;tflag=1;}tvalue=tvalue*(0.625);//温度值扩大10倍,精确到1位小数return(tvalue);}/*******************************************************************/ void ds1820disp()//温度值显示{ uchar flagdat;disdata[0]=tvalue/1000+0x30;//百位数disdata[1]=tvalue%1000/100+0x30;//十位数disdata[2]=tvalue%100/10+0x30;//个位数disdata[3]=tvalue%10+0x30;//小数位if(tflag==0)flagdat=0x20;//正温度不显示符号elseflagdat=0x2d;//负温度显示负号:-if(disdata[0]==0x30){disdata[0]=0x20;//如果百位为0,不显示if(disdata[1]==0x30){disdata[1]=0x20;//如果百位为0,十位为0也不显示}}wr_com(0xc0);wr_dat(flagdat);//显示符号位wr_com(0xc1);wr_dat(disdata[0]);//显示百位wr_com(0xc2);wr_dat(disdata[1]);//显示十位wr_com(0xc3);wr_dat(disdata[2]);//显示个位wr_com(0xc4);wr_dat(0x2e);//显示小数点wr_com(0xc5);wr_dat(disdata[3]);//显示小数位}/********************主程序***********************************/void main(){ init_play();//初始化显示while(1){read_temp();//读取温度ds1820disp();//显示}}。
DS18B20与LCD1602结合显示温度汇总(可编辑修改word版)
单总线系统包括一个总线控制器和一个或多个从机。DS18B20 总是充当从机。当只有 一只从机挂在总线上时,系统被称为“单点”系统;如果由多只从机挂在总线上,系统被 称为“多点”。 所有的数据和指令的传递都是从最低有效位开始通过单总线。单总线需要 一个约 5KΩ 的外部上拉电阻;单总线的空闲状态是高电平。无论任何理由需要暂停某一 执行过程时,如果还想恢复执行的话,总线必须停留在空闲状态。在恢复期间,如果单总 线处于非活动(高电平)状态,位与位间的恢复时间可以无限长。如果总线停留在低电平 超过 480us,总线上的所有器件都将被复位。 四、操作流程 1.DS18B20 复位。 2.执行 ROM 指令。就是访问,搜索,匹配每个 DS18B20 独有的 64 位序列号。实验板上只 连有一个 DS18B20,故不需识别,也就是不需读出此序列号,写代码时直接写命令 0xcc 跳过。 3.执行 DS18B20 功能指令(RAM 指令,就是读写暂存器指令)。
一个身份证号),这是出厂时被光刻好的。最前面 8 位是单线系列编码:28h。接着的 48 位
是一个唯一的序列号。最后 8 位是以上 56 位的 CRC 编码。64-位的光刻 ROM 又包括 5 个
ROM 的功能命令:读 ROM,匹配 ROM,跳跃 ROM,查找 ROM 和报警查找。ROM 的作
用是使每个 DS18B20 各不相同,这样就8B20 一、DS18B20 的外形及其与单片机的连接图
(a)
(b)
图1
DS18B20 是 Dallas 公司生产的 1-Wire 接口数字温度传感器,其外形如图 1(a)所示,有
三个引脚,分别为:电源地 1(GND); 数字信号输入/输出端 2(DQ);外接供电电源输入端
单片机应用技术项目5 用LCD1602与DS18B20设计的数字温度计
五、偏置 LCD的SEG/COM的驱动波形为模拟信号,而各档模拟电压相
对于LCD输出的最高电压的比例称为偏置,而一般来讲,是以 最低一档与输出最高电压的比值来表示。 由此可见51系列单片机的普通IO口不能满足LCD的驱动要求, 需要外加LCD驱动专用芯片来驱动液晶显示,而某些单片机集 成有LCD驱动模块比如PIC系列单片机。
5.1.1 LCD1602的内部结构
一、 LCD简介 LCD ( Liquid Crystal Display )液晶显示器,是利用液晶
分子的物理结构和光学特性进行显示的一种技术。液晶分子是 介于固体和液体之间的一种棒状结构的大分子物质;在自然形态, 具有光学各向异性的特点,在电(磁)场作用下,呈各向同性特 点。 LCD 的构造是在两片平行的玻璃基板当中放置液晶盒, 下基板玻璃上设置薄膜晶体管,上基板玻璃上设置滤光片,通 过极板上的信号与电压改变来控制液晶分子的转动方向,从而 达到控制每个像素点偏振光出射与否而达到显示目的。下面以 直视型简单多路TN/STN LCD Panel(液晶显示面板)的基本结
上一页 下一页 返回
二、 LCD1602简介 1602液晶也叫1602字符型液晶,它能够同时显示16列2行,
即32个字符。它是一种专门用来显示字母、数字、符号等的点 阵型液晶模块。它由32个5X7或者5X11等点阵字符位组成, 每个点阵字符位都可以显示一个字符,每位之间有一个点距的 间隔,每行之间也有间隔,起到了字符间距和行间距的作用, 正因为如此所以它不能很好地显示图形。其优点是微功耗、体 积小、显示内容丰富、超薄轻巧、易于控制,常用在袖珍式仪 表和低功耗单片机应用系统中。实物图和PROTEUS中的模型:
上一页 下一页 返回
基于LCD1602液晶的DS18B20温度传感器的温度采集系统设计说明
2012 ~ 2013学年第2学期《单片机原理及应用》课程设计报告题目:基于DS18B20的温度采集系统设计专业:自动化班级:姓名:指导教师:电气工程学院2013年6月6日摘要随着信息技术的飞速发展,嵌入式智能电子技术已渗透到社会生产、工业控制以及人们日常生活的各个方面。
单片机又称为嵌入式微型控制器,在智能仪表、工业控制、智能终端、通信设备、医疗器械、汽车电器、导航系统和家用电器等很多领域都有着广泛的应用,已成为当今电子信息领域应用最广泛的技术之一。
本文主要介绍了一个基于STC89C52RC单片机的测温系统,详细描述了利用液晶显示器件温度传感器DS18B20开发测温系统的原理,重点对传感器与单片机的硬件连接和软件编程进行了详细分析。
主要地介绍了数字温度传感器DS18B20的数据采集过程,进而对各部分硬件电路的工作原理进行了介绍。
温度传感器DS18B20与STC89C52RC结合构成了最简温度检测系统,该系统可以方便的实现温度采集和显示,它使用起来相当方便,具有精度高、量程宽、灵敏度高、体积小、功耗低等优点,适合我们日常生活和工、农业生产中的温度测量,也可以当作温度处理模块嵌入其它系统中,作为其他主系统的辅助扩展。
关键词:单片机STC89C52RC、DS18B20温度传感器、液晶显示器LCD1602 基于DS18B20的温度采集系统设计目录第一章绪论21.1温度检测系统的介绍21.1.1 温度检测系统的组成31.1.2 温度检测的实际意义3第二章温度检测系统方案的选取32.1温度检测系统方案的选取3温度检测模块32.1.2温度显示模块42.2温度检测系统结构的设计4第三章硬件电路的设计53.1STC89C52RC的介绍53.2DS18B20的介绍53.2.1 DS18B20的主要特点53.2.2 DS18B20的结构63.2.3 DS18B20的测温原理63.3 LCD1602的介绍83.4硬件设计9硬件设计目标9硬件功能模块划分9接口和连接方式10硬件仿真电路10第四章软件设计104.11602液晶显示处理部分104.218B20函数处理部分11第五章心得体会13参考文献13附录14第一章绪论1.1 温度检测系统的介绍温度检测在各领域应用的非常广泛,可以说渗透到了社会的每一个领域。
51单片机的18B20、1302和LCM1602液晶显示温度与万年历显控制
摘要本设计以数字集成电路技术为基础,单片机技术为核心。
软件设计采用模块化结构,C语言编程。
系统通过LCD显示数据,可以显示日期(年、月、日、时、分、秒)以及温度。
在内容安排上首先描述系统硬件工作原理,着重介绍了各硬件接口技术和各个接口模块的功能;其次,详细的阐述了程序的各个模块和实现过程。
前言电子时钟是实现对年,月,日,时,分,秒数字显示的计时装置,广泛用于个人家庭,车站,码头,办公室,银行大厅等场所,成为人们日常生活中的必需品。
数字集成电路的发展和石英晶体振荡器的广泛应用,使得数字钟的精度远远超过老式钟表。
钟表的数字化给人们生产生活带来了极大的方便,在此基础上完成的电子时钟精度高,功能易于扩展。
可扩展成为诸如定时自动报警、按时自动打铃、时间程序自动控制、定时广播、自动起闭路灯、定时开关烘箱、通断动力设备、甚至各种定时电气的自动启用等电路。
所有这些,都是以钟表数字化为基础的。
因此,研究数字时钟及扩大其应用有着非常现实的意义。
本设计就是数字时钟简单的扩展应用。
1.1设计目标:利用单片机技术,以及模拟电子技术和数字电子技术的理论知识,设计实现MCS-51单片机对LCM1602液晶输出显示控制的这一基本要求。
1.2设计要求:本设计利用DS1302;DS18B20;LCD1602实现以下功能:(1) 显示日期功能(年、月、日、时、分、秒以及星期)(2) 可通过按键切换年、月、日及时、分、秒的显示状态(3) 可随时调校年、月、日或时、分、秒(4) 可每次增减一进行时间调节(5) 可动态完整显示年份,实现真正的万年历显示(6) 可显示温度2 设计方案2.1 控制器硬件控制电路主要用了AT89C52芯片处理器、LCD显示器等。
根据各自芯片的功能互相连接成电子万年历的控制电路。
软件控制程序主要有主控程序、电子万年历的时间控制程序、时间显示及星期显示和温度采集程序等组成。
主控程序中对整个程序进行控制,进行了初始化程序及计数器、还有键盘功能程序、以及显示程序等工作,时间控制程序是电子万年历中比较重要的部分。
DS18B20测量温度液晶1602显示
DS18B20测量温度液晶1602显示DS18B20温度传感器简介DS18B20是一种数字温度传感器。
它输出的是数字信号,同时具有体积小,硬件资源耗费少,抗干扰能力强,精度高等特点。
DS18B20温度传感器特点1、单线接口:DS18B20仅需一条线可实现与微处理器双向通信。
2、测温范围: DS18B20温度传感器的测温范围可达-55℃~+125℃,在-10℃到+85℃范围内误差为±0.4°。
3、支持多点组网功能:多个DS18B20温度传感器可以并联在一条数据线上,最多可以并联8个,实现多点测温。
4、工作电源: 3.0~5.5V/DC ,DS18B20温度传感器可以采用外部独立电源供电,也可以用数据线寄生电源供电。
5、DS18B20温度传感器在应用过程中不需要任何外围元件。
6、DS18B20测量温度的结果以9~12位数字量方式串行传送。
7、掉电保护功能, DS18B20温度传感器内部含有 EEPROM ,通过配置寄存器可以设定数字转换精度和报警温度。
在DS18B20温度传感器掉电以后仍可保存分辨率及报警温度的设定值。
8、DS18B20温度传感器返回16位二进制数代表此刻探测的温度值,其高五位代表正负。
如果高五位全部为1,则代表返回的温度值为负值。
如果高五位全部为0,则代表返回的温度值为正值。
后面的11位数据代表温度的绝对值,将其转换为十进制数值之后,再乘以0.0625即可获得此时的温度值。
DS18B20温度传感器引脚说明DS18B20温度传感器接口电路液晶1602接口电路DS18B20测量温度程序源代码/*****************DS18B20测量温度,用1602显示温度值******************* 单片机:51单片机* 开发环境:keil* 功能: DS18B20测量温度,并在LCD1602中显示出来**********************************************************************/#include <reg51.h>#define LCD_Data P0#define Busy 0x80#define uchar unsigned char#define uint unsigned intuchar code table0[] = {" SL-51A "};uchar code table1[] = {" TEMP: XX.X "};uchar temperature[5]; //温度值uint temp;sbit LCD_RS = P1^0;sbit LCD_RW = P1^1;sbit LCD_E = P2^5;sbit DS = P2^2;void Delay5Ms(void);void delay(uint count);void WriteDataLCD(unsigned char WDLCD);void WriteCommandLCD(unsigned char WCLCD,BuysC);unsigned char ReadDataLCD(void);unsigned char ReadStatusLCD(void);void LCDInit(void);void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData); void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData); void Info_display(void);void dsreset(void);bit tmpreadbit(void);uchar tmpread(void);void tmpwritebyte(uchar dat);void tmpchange(void);uint tmp();void delay(uint count){uint i;while(count){i=200;while(i>0)i--;count--;}}void dsreset(void) //发复位命令{uint i;DS=0;i=103;while(i>0)i--;DS=1;i=4;while(i>0)i--;}bit tmpreadbit(void) //读取一位{uint i;bit dat;DS=0;i++;DS=1;i++;i++;dat=DS;i=8;while(i>0)i--;return (dat);}uchar tmpread(void) //读取一个字节{uchar i,j,dat;dat=0;for(i=1;i<=8;i++){j=tmpreadbit();dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面 }return(dat);}void tmpwritebyte(uchar dat) //向ds18b20写入一个字节{uint i;uchar j;bit testb;for(j=1;j<=8;j++){testb=dat&0x01;dat=dat>>1;if(testb){DS=0;i++;i++;DS=1;i=8;while(i>0)i--;}else{DS=0;i=8;while(i>0)i--;DS=1;i++;i++;}}}void tmpchange(void) //DS18B20开始转换{dsreset();delay(1);tmpwritebyte(0xcc); //命令的含义可以查18b20的手册 tmpwritebyte(0x44);}uint tmp() //获取温度值{float tt;uchar a,b;dsreset();delay(1);tmpwritebyte(0xcc);tmpwritebyte(0xbe);a=tmpread();b=tmpread();temp=b;temp<<=8;temp=temp|a;tt=temp*0.0625;temp=tt*10+0.5;return temp;}/*************************5ms延时函数***************************/void Delay5Ms(void){unsigned int TempCyc = 3552;while(TempCyc--);}/**************************写数据函数***************************/void WriteDataLCD(unsigned char WDLCD){ReadStatusLCD(); //检测忙LCD_Data = WDLCD;LCD_E = 0; //若晶振速度太高可以在这后加小的延时 LCD_E = 0; //延时LCD_RS = 1;LCD_RW = 0;LCD_E = 1;LCD_E = 0;}/*************************写指令函数****************************/void WriteCommandLCD(unsigned char WCLCD,BuysC) //BuysC为0时忽略忙检测{if (BuysC) ReadStatusLCD(); //根据需要检测忙LCD_Data = WCLCD;LCD_E = 0;LCD_E = 0;LCD_RS = 0;LCD_RW = 0;LCD_E = 1;LCD_E = 0;}/**************************读状态函数***************************/unsigned char ReadStatusLCD(void){LCD_Data = 0xFF;LCD_RS = 0;LCD_RW = 1;LCD_E = 0;LCD_E = 0;LCD_E = 1;while (LCD_Data & Busy); //检测忙信号return(LCD_Data);}/***************************LCD初始化***************************/void LCDInit(void) //LCD初始化{LCD_Data = 0;WriteCommandLCD(0x38,0); //三次显示模式设置,不检测忙信号Delay5Ms();WriteCommandLCD(0x38,0);Delay5Ms();WriteCommandLCD(0x38,0);Delay5Ms();WriteCommandLCD(0x38,1); //显示模式设置, 开始要求每次检测忙信号WriteCommandLCD(0x08,1); //关闭显示WriteCommandLCD(0x01,1); //显示清屏WriteCommandLCD(0x06,1); //显示光标移动设置WriteCommandLCD(0x0C,1); //显示开及光标设置}/**********************按指定位置显示一个字符*********************/void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData){Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;X |= 0x80; //算出指令码WriteCommandLCD(X, 0); //这里不检测忙信号,发送地址码WriteDataLCD(DData);}/***********************按指定位置显示一串字符********************/void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData) {unsigned char ListLength;ListLength = 0;Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1while (DData[ListLength]>=0x20) //若到达字串尾则退出{if (X <= 0xF) //X坐标应小于0xF{DisplayOneChar(X, Y, DData[ListLength]);//显示单个字符ListLength++;X++;}}}/*****************************************************************/ void temp_display(unsigned int temp) //显示程序{unsigned char A1,A2,A2t,A3;A1=temp/100; //百位A2t=temp%100;A2=A2t/10; //十位A3=A2t%10; //个位temperature[1]=A1 + 0x30;temperature[2]=A2 + 0x30;temperature[3]=A3 + 0x30;DisplayOneChar(9,1,temperature[1]);DisplayOneChar(10,1,temperature[2]);DisplayOneChar(12,1,temperature[3]);}/******************************************************************/ void init(){LCDInit();DisplayListChar(0,0,table0);DisplayListChar(0,1,table1);}void main(){int i;init();while(1){tmpchange();for(i=0;i<=10;i++){if(i==10){temp_display(tmp());}}}}。
DS18B20与LCD1602结合显示温度
DS18B20一、DS18B20的外形及其与单片机的连接图(a) (b)图1DS18B20是Dallas公司生产的1-Wire接口数字温度传感器,其外形如图1(a)所示,有三个引脚,分别为:电源地1(GND); 数字信号输入/输出端2(DQ);外接供电电源输入端3(VDD,在寄生电源接线方式时接地)。
它是一种单总线数字温度传感器,所有的数据交换和控制都通过这根数据线来完成。
测试温度范围-55℃-125℃,温度数据位可配置为9、10、11、12位,对应的刻度值分别为0.5℃、0.25℃、0.125℃、0.0625℃,对应的最长转换时间分别为93.75ms、187.5ms、375ms、750ms。
出厂默认配置为12位数据,刻度值为0.0625℃,最长转换时间为750ms。
从以上数据可以看出,DS18B20数据位越低、转换时间越短、反应越快、精度越低。
单总线没有时钟线,只有一根通信线,其读写数据是靠控制起始时间和采样时间来完成,所以时序要求很严格。
图1(a)为DS18B20与单片机的连接电路图,它的数据线通常要求外接一个 4.7KΩ-10KΩ的上拉电阻(该电阻画原理图时靠近单片机画故没有显示出来),故其闲置时状态位高电平。
提示:DS18B20外形酷似三极管,分辨引脚时,面对着扁平的那一面,左负右正,一旦接反就会立刻发热,甚至有可能烧毁。
二、DS18B20存储器结构DS18B20的内部有64位的ROM单元,和9字节的暂存器单元。
1、64位(激)光刻只读存储器每只DS18B20都有一个唯一存储在ROM中的64位编码(跟人的身份证号类似,一人一个身份证号),这是出厂时被光刻好的。
最前面8位是单线系列编码:28h。
接着的48位是一个唯一的序列号。
最后8位是以上56位的CRC编码。
64-位的光刻ROM又包括5个ROM的功能命令:读ROM,匹配ROM,跳跃ROM,查找ROM和报警查找。
ROM的作用是使每个DS18B20各不相同,这样就可以实现一根总线上挂接多个DS18B20以实现多点监测。
51单片机ds18b20和lcd1602显示温度
/*本程序为基于51单片机的DS18b20与lcd1602显示温度程序,1602数据线友P0口提供*/程序已通过硬件测试直接使用作者:liuzqiang1016#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit DQ=P2^0;//ds18b20sbit lcd_rw=P2^5;sbit lcd_rs=P2^6;sbit lcd_en=P2^7;unsigned char code str1[]={"temperature: "};unsigned char code str2[16]={" "};uchar data disdata[5];uint value;//温度值uchar flag;//正负标志/*************************lcd1602程序**************************/void delay1ms(unsigned int ms)//延时1毫秒(不够精确的){unsigned int i,j;for(i=0;i<ms;i++)for(j=0;j<100;j++);}void write_com(unsigned char com)//写指令//{ delay1ms(1);lcd_rs=0;lcd_rw=0;lcd_en=0;P0=com;delay1ms(1);lcd_en=1;delay1ms(1);lcd_en=0;}void write_dat(unsigned char dat)//写数据//{ delay1ms(1);;lcd_rs=1;lcd_rw=0;lcd_en=0;P0=dat;delay1ms(1);lcd_en=1;delay1ms(1);lcd_en=0;}void lcd_init()//初始化设置//{write_com(0x38);delay1ms(5);write_com(0x08);delay1ms(5);write_com(0x01);delay1ms(5);write_com(0x06);delay1ms(5);write_com(0x0c);delay1ms(5);}void display(unsigned char *p)//显示//{while(*p!='\0'){write_dat(*p);p++;delay1ms(1);}}init_play()//初始化显示{ lcd_init();write_com(0x80);display(str1);write_com(0xc0);display(str2);}void delay_18B20(unsigned int i)//延时1微秒{while(i--);}void ds1820rst()/*ds1820复位*/{unsigned char x=0;DQ = 1; //DQ复位delay_18B20(4); //延时DQ = 0; //DQ拉低delay_18B20(100); //精确延时大于480usDQ = 1; //拉高delay_18B20(40);}uchar ds1820rd()/*读数据*/{unsigned char i=0;unsigned char dat = 0;for (i=8;i>0;i--){ DQ = 0; //给脉冲信号dat>>=1;DQ = 1; //给脉冲信号if(DQ)dat|=0x80;delay_18B20(10);}return(dat);}void ds1820wr(uchar wdata)/*写数据*/ {unsigned char i=0;for (i=8; i>0; i--){ DQ = 0;DQ = wdata&0x01;delay_18B20(10);DQ = 1;wdata>>=1;}}read_temp()/*读取温度值并转换*/{uchar a,b;ds1820rst();ds1820wr(0xcc);//*跳过读序列号*/ds1820wr(0x44);//*启动温度转换*/ds1820rst();ds1820wr(0xcc);//*跳过读序列号*/ds1820wr(0xbe);//*读取温度*/a=ds1820rd();b=ds1820rd();value=b;value<<=8;value=value|a;if(value<0x0fff)flag=0;else{value=~value+1;flag=1;}value=value*(0.625);//温度值扩大10倍,精确到1位小数return(value);}/*******************************************************************/ void ds1820disp()//温度值显示{ uchar flagdat;disdata[0]=value/1000+0x30;//百位数disdata[1]=value%1000/100+0x30;//十位数disdata[2]=value%100/10+0x30;//个位数disdata[3]=value%10+0x30;//小数位if(flag==0)flagdat=0x20;//正温度不显示符号elseflagdat=0x2d;//负温度显示负号:-if(disdata[0]==0x30){disdata[0]=0x20;//如果百位为0,不显示if(disdata[1]==0x30){disdata[1]=0x20;//如果百位为0,十位为0也不显示}}write_com(0xc0);write_dat(flagdat);//显示符号位write_com(0xc1);write_dat(disdata[0]);//显示百位write_com(0xc2);write_dat(disdata[1]);//显示十位write_com(0xc3);write_dat(disdata[2]);//显示个位write_com(0xc4);write_dat(0x2e);//显示小数点write_com(0xc5);write_dat(disdata[3]);//显示小数位}/********************主程序***********************************/ void main(){ init_play();//初始化显示while(1){read_temp();//读取温度ds1820disp();//显示}}。
DS18B20温度传感器和1602液晶制作温度和时间同时显示
用DS18B20温度传感器和1602液晶制作温度和时间同时显示【含原理图】2009年11月26日星期四22:43C程序如下:/*功能:温度采集显示和可调时钟显示,时钟用中断法实现s1:选择要调节的时、分、秒位s2:时、分、秒加一s3:时、分、秒减一*/#include<reg52.h>#define uchar unsigned char#define uint unsigned intuchar num,s1num,count;uchar shi,fen,miao;sbit rs=P2^0;sbit e=P2^1;sbit s1=P3^0;sbit s2=P3^1;sbit s3=P3^2; //按键定义sbit DQ =P2^2; //定义通信端口bit flag;uchar code table1[]="Time: 00:00:00";uchar code table2[]="Temperature: 'C";//1602初始化字符void delay(uint z)//延时子函数{uint x,y;for(x=z; x>0; x--)for(y=110;y>0;y--);}#include<1602.h>#include<18b20.h>#include<clock_set.h>void main(){uchar temp;init_1602();while(1){ delay(500); //去除0秒和1秒之间显示间隔跟正常1秒间隔相差过大if(miao==0) //每分钟进行温度采集一次{TR0=0; //进入温度采集后,关闭定时器flag=1; //flag=1,标志进入温度采集模式write_com(0x80+0x40+13);write_dat(0x30+1); //消除不显示数字1temp=ReadTemperature(); //读取DS18B20的温度值write_1602(12,temp); //向1602中写入温度值TR0=1; //温度采集完成后,打开定时器delay(100);//等待miao不等零,跳出循环}flag=0; //flag=0,标志在时钟显示模式下keyscan(); //调用键盘扫描子程序,用以调整时间}}void timer0() interrupt 1//定时器1的中断服务程序,并向1602中写时分秒显示时间{TH0=(65535-50000)/256;TL0=(65535-50000)%256;count++;if (count==18){count=0;miao++;if(miao==60){miao=0;fen++;if(fen==60){fen=0;shi++;if(shi==24){shi=0;}if(flag==0) //flag=0,标志在时钟显示模式下,然后才显示时间write_1602(6,shi);}if(flag==0)write_1602(9,fen);}if(flag==0)write_1602(12,miao);}}"1602.h"void write_com(uchar com)//向1602液晶写命令函数{rs=0;e=0;P0=com;delay(5);e=1;delay(5);e=0;}void write_dat(uchar dat)//向1602液晶写入数据{rs=1;e=0;P0=dat;delay(5);e=1;delay(5);e=0;}void init_1602()//1602液晶的初始化{uchar i;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);TMOD=0x01;TH0=(65535-50000)/256;TL0=(65535-50000)%256;EA=1;ET0=1;TR0=1;write_com(0x80); //第一行字符的初始化for(i=0;i<16;i++){write_dat(table2[i]);delay(5);}write_com(0x80+0x40); //第二行字符的初始化for(i=0;i<14;i++){write_dat(table1[i]);delay(5);}}void write_1602(uchar address,uchar temp_dat)//向指定的地址中写入时、分、秒数据{uchar gewei,shiwei;if(flag==0) //若在时钟显示模式下,向第二行写数据{write_com(0x80+0x40+address);}else{write_com(0x80+address); //若在温度采集显示模式下,向第一行写数据}shiwei=temp_dat/10;gewei=temp_dat%10;write_dat(0x30+shiwei); //根据1602字符库做相应转换write_dat(0x30+gewei);}"18B20.h"void delay_18b20(unsigned int i)//延时子函数{while(i--);}//初始化DS18B20子函数Init_DS18B20(void){unsigned char x=0;DQ = 1; //DQ复位delay_18b20(8); //稍做延时DQ = 0; //单片机将DQ拉低delay_18b20(80); //精确延时大于480usDQ = 1; //拉高总线delay_18b20(14);x=DQ; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay_18b20(20);}//读一个字节ReadOneChar(void){unsigned char i=0;unsigned char dat = 0;for (i=8;i>0;i--){DQ = 0; // 给脉冲信号dat>>=1;DQ = 1; // 给脉冲信号if(DQ)dat|=0x80;delay_18b20(4);}return(dat);}//写一个字节WriteOneChar(unsigned char dat){unsigned char i=0;for (i=8; i>0; i--){DQ = 0;DQ = dat&0x01;delay_18b20(5);DQ = 1;dat>>=1;}delay_18b20(4);}//读取温度值ReadTemperature(void){uchar a,b,t;Init_DS18B20();WriteOneChar(0xCC); // 跳过读序号列号的操作WriteOneChar(0x44); // 启动温度转换delay(850); //等待温度转换结束,不能过短,否则第一次显示不出实际温度,会显示85 Init_DS18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度a=ReadOneChar(); //读取温度值低位b=ReadOneChar(); //读取温度值高位a=a>>4; //低位右移4位,舍弃小数部分t=b<<4; //高位左移4位,舍弃符号位t=t|a;return(t);}"clock_set.h"void keyscan()//键盘扫描程序{if(s1==0)//s1键扫描{delay(5);if(s1==0){TR0=0;s1num++;while(!s1);//等待键的释放switch(s1num)//根据s1的按键次数做相应的处理{case 1:write_com(0x80+0x40+12);write_com(0x0f); break;//按键一次,调整光标的形状及位置case 2:write_com(0x80+0x40+9); break;case 3:write_com(0x80+0x40+6); break;case 4:s1num=0;write_com(0x0c);TR0=1;break;}}}if(s1num)//在s1有被按下的情况下做相应的处理{if(s2==0)//s2按键检测,按下s2键后相应的时、分、秒加1操作{delay(5);if(s2==0){while(!s2);//松手检测switch(s1num){case 1:miao++;if(miao==60) miao=0;write_1602(12,miao);write_com(0x80+0x40+12);break;case 2:fen++;if(fen==60) fen=0;write_1602(9,fen);write_com(0x80+0x40+9);break;case 3:shi++;if(shi==24) shi=0;write_1602(6,shi);write_com(0x80+0x40+6);break;case 4:break;}// delay(500);//把松手检测部分去除后,按下后时间一直增加}}if(s3==0)//s3按键检测,按下s3键后相应的时、分、秒减1操作{delay(5);if(s3==0){while(!s3);//松手检测switch(s1num){case 1:miao--;if(miao==-1) miao=59;write_1602(12,miao);write_com(0x80+0x40+12);break;case 2:fen--;if(fen==-1) fen=59;write_1602(9,fen);write_com(0x80+0x40+9);break;case 3:shi--;if(shi==-1) shi=23;write_1602(6,shi);write_com(0x80+0x40+6);break;case 4:break;}// delay(500);//把松手检测部分去除后,按下后时间一直减小}}}}原理图:。
温度传感器DS18B及LCD1602的使用
温度传感器DS18B及LCD1602的使用温度传感器DS18B20是一种数字温度传感器,可以通过单线数字接口与单片机进行通信。
它采用了Dallas的1-Wire总线协议,具有高精度、低功耗、长传输距离等特点。
而LCD1602是一种常用的字符型液晶显示屏,可以显示16×2个字符。
使用DS18B20温度传感器需要先进行硬件连接。
它需要三个引脚,即VCC、GND和DQ。
VCC连接到3.3V或5V电源,GND连接到地线,DQ连接到单片机的一个GPIO口。
在连接时要注意使用上拉电阻将DQ引脚连接到VCC,以确保通信的可靠性。
在软件方面,需要使用1-Wire总线的协议进行通信。
可以使用基于C语言或者Arduino的库来实现。
在Arduino中,可以使用OneWire库来方便地读取DS18B20的数据。
首先需要创建一个OneWire对象,并指定DQ引脚,然后在setup(函数中初始化该对象。
接下来在loop(函数中可以使用`reset_search(`函数来连接的设备,并通过`search(`函数来获取设备的地址。
而后使用`reset(`函数重置总线,`select(`函数选择设备进行通信,`write(`函数发送指令,`read(`函数读取数据。
其中,读取温度数据需要先发送读取温度的指令,使用`read_bytes(`函数读取9个字节的数据,低字节在前,高字节在后,然后将读取到的数据处理转换为摄氏温度。
接下来是LCD1602的使用。
LCD1602需要连接到单片机的多个引脚,包括VCC、GND、SCL、SDA等。
在Arduino中,可以使用LiquidCrystal库来方便地控制LCD1602、首先需要创建一个LiquidCrystal对象,并指定连接的引脚,然后在setup(函数中初始化该对象。
接下来可以使用一系列函数来向LCD1602写入数据,如`begin(`函数用于初始化LCD1602,`print(`函数用于显示字符,`setCursor(`函数用于设置光标位置等。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
您研究一下以下这个程序,然后就可以加上时间功能.多做一点就能多学一点.开机时对DS18B20进行检测,如果DS18B20检测不正常,LCD1602显示:DS18B20 ERRORPLEASE CHECK蜂鸣器报警。
DS18B20检测正常,LCD1602显示:DS18B20 OKTEMP: 100.8℃如果温度值高位为0,将不显示出来。
你可以通过拔插DS18B20查看DS18B20的检测功能。
/* ME300B单片机开发系统演示程序- DS18B20温度显示*//* LCD1602显示*//* 作者:gguoqing *//*Copyright(C)伟纳电子 All Rights Reserved *//*******************************************************************/#include < reg51.h >#include < intrins.h >#define uchar unsigned char#define uint unsigned intsbit DQ = P3^3 ; //定义DS18B20端口DQsbit BEEP=P3^7 ; //蜂鸣器驱动线bit presence ;sbit LCD_RS = P2^0 ;sbit LCD_RW = P2^1 ;sbit LCD_EN = P2^2 ;uchar code cdis1[ ] = {" DS18B20 OK "} ;uchar code cdis2[ ] = {" TEMP: . C "} ;uchar code cdis3[ ] = {" DS18B20 ERR0R "} ;uchar code cdis4[ ] = {" PLEASE CHECK "} ;unsigned char data temp_data[2] = {0x00,0x00} ;unsigned char data display[5] = {0x00,0x00,0x00,0x00,0x00} ;unsigned char code ditab[16] = {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09} ;void beep() ;unsigned char code mytab[8] = {0x0C,0x12,0x12,0x0C,0x00,0x00,0x00,0x00} ; #define delayNOP() ; {_nop_() ;_nop_() ;_nop_() ;_nop_() ;} ;/*******************************************************************/void delay1(int ms){unsigned char y ;while(ms--){for(y = 0 ; y<250 ; y++){_nop_() ;_nop_() ;_nop_() ;_nop_() ;}}}/******************************************************************//*检查LCD忙状态*//*lcd_busy为1时,忙,等待。
lcd-busy为0时,闲,可写指令与数据。
*//******************************************************************/bit lcd_busy(){bit result ;LCD_RS = 0 ;LCD_RW = 1 ;LCD_EN = 1 ;delayNOP() ;result = (bit)(P0&0x80) ;LCD_EN = 0 ;return(result) ;}/*写指令数据到LCD */ /*RS=L,RW=L,E=高脉冲,D0-D7=指令码。
*//*******************************************************************/void lcd_wcmd(uchar cmd){while(lcd_busy()) ;LCD_RS = 0 ;LCD_RW = 0 ;LCD_EN = 0 ;_nop_() ;_nop_() ;P0 = cmd ;delayNOP() ;LCD_EN = 1 ;delayNOP() ;LCD_EN = 0 ;}/*******************************************************************//*写显示数据到LCD *//*RS=H,RW=L,E=高脉冲,D0-D7=数据。
*//*******************************************************************/void lcd_wdat(uchar dat){while(lcd_busy()) ;LCD_RS = 1 ;LCD_RW = 0 ;LCD_EN = 0 ;P0 = dat ;delayNOP() ;LCD_EN = 1 ;delayNOP() ;LCD_EN = 0 ;}/* LCD初始化设定*/ /*******************************************************************/void lcd_init(){delay1(15) ;lcd_wcmd(0x01) ; //清除LCD的显示内容lcd_wcmd(0x38) ; //16*2显示,5*7点阵,8位数据delay1(5) ;lcd_wcmd(0x38) ;delay1(5) ;lcd_wcmd(0x38) ;delay1(5) ;lcd_wcmd(0x0c) ; //显示开,关光标delay1(5) ;lcd_wcmd(0x06) ; //移动光标delay1(5) ;lcd_wcmd(0x01) ; //清除LCD的显示内容delay1(5) ;}/* 设定显示位置*//*******************************************************************/void lcd_pos(uchar pos){lcd_wcmd(pos | 0x80) ; //数据指针=80+地址变量}/*自定义字符写入CGRAM */ /*******************************************************************/void writetab(){unsigned char i ;lcd_wcmd(0x40) ; //写CGRAMfor (i = 0 ; i< 8 ; i++)lcd_wdat(mytab[ i ]) ;}/*us级延时函数*//*******************************************************************/void Delay(unsigned int num){while( --num ) ;}/*初始化ds1820 *//*******************************************************************/Init_DS18B20(void){DQ = 1 ; //DQ复位Delay(8) ; //稍做延时DQ = 0 ; //单片机将DQ拉低Delay(90) ; //精确延时大于480usDQ = 1 ; //拉高总线Delay(8) ;presence = DQ ; //如果=0则初始化成功=1则初始化失败Delay(100) ;DQ = 1 ;return(presence) ; //返回信号,0=presence,1= no presence }/* 读一个字节*//*******************************************************************/ ReadOneChar(void){unsigned char i = 0 ;unsigned char dat = 0 ;for (i = 8 ; i > 0 ; i--){DQ = 0 ; // 给脉冲信号dat >>= 1 ;DQ = 1 ; // 给脉冲信号if(DQ)dat |= 0x80 ;Delay(4) ;}return (dat) ;}/* 写一个字节*//*******************************************************************/ WriteOneChar(unsigned char dat){unsigned char i = 0 ;for (i = 8 ; i > 0 ; i--){DQ = 0 ;DQ = dat&0x01 ;Delay(5) ;DQ = 1 ;dat>>=1 ;}}/* 读取温度*//*******************************************************************/Read_Temperature(void){Init_DS18B20() ;WriteOneChar(0xCC) ; // 跳过读序号列号的操作WriteOneChar(0x44) ; // 启动温度转换Init_DS18B20() ;WriteOneChar(0xCC) ; //跳过读序号列号的操作WriteOneChar(0xBE) ; //读取温度寄存器temp_data[0] = ReadOneChar() ; //温度低8位temp_data[1] = ReadOneChar() ; //温度高8位}/* 数据转换与温度显示*/ /*******************************************************************/Disp_Temperature(){display[4]=temp_data[0]&0x0f ;display[0]=ditab[display[4]]+0x30 ; //查表得小数位的值display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4) ;display[3]=display[4]/100+0x30 ;display[1]=display[4]%100 ;display[2]=display[1]/10+0x30 ;display[1]=display[1]%10+0x30 ;if(display[3]==0x30) //高位为0,不显示{display[3]=0x20 ;if(display[2]==0x30) //次高位为0,不显示display[2]=0x20 ;}lcd_pos(0x48) ;lcd_wdat(display[3]) ; //百位数显示lcd_pos(0x49) ;lcd_wdat(display[2]) ; //十位数显示lcd_pos(0x4a) ;lcd_wdat(display[1]) ; //个位数显示lcd_pos(0x4c) ;lcd_wdat(display[0]) ; //小数位数显示}/*******************************************************************//* 蜂鸣器响一声*//*******************************************************************/void beep(){unsigned char y ;for (y=0 ;y<100 ;y++){Delay(60) ;BEEP=!BEEP ; //BEEP取反}BEEP=1 ; //关闭蜂鸣器Delay(40000) ;}/* DS18B20 OK 显示菜单*/ /*******************************************************************/void Ok_Menu (){uchar m ;lcd_init() ; //初始化LCDlcd_pos(0) ; //设置显示位置为第一行的第1个字符m = 0 ;while(cdis1[m] != '\0'){ //显示字符lcd_wdat(cdis1[m]) ;m++ ;}lcd_pos(0x40) ; //设置显示位置为第二行第1个字符m = 0 ;while(cdis2[m] != '\0'){lcd_wdat(cdis2[m]) ; //显示字符m++ ;}writetab() ; //自定义字符写入CGRAMdelay1(5) ;lcd_pos(0x4d) ;lcd_wdat(0x00) ; //显示自定义字符}/* DS18B20 ERROR 显示菜单*//*******************************************************************/void Error_Menu (){uchar m ;lcd_init() ; //初始化LCDlcd_pos(0) ; //设置显示位置为第一行的第1个字符m = 0 ;while(cdis3[m] != '\0'){ //显示字符lcd_wdat(cdis3[m]) ;m++ ;}lcd_pos(0x40) ; //设置显示位置为第二行第1个字符m = 0 ;while(cdis4[m] != '\0'){lcd_wdat(cdis4[m]) ; //显示字符m++ ;}}/* 主函数*//************************************/ void main(){Ok_Menu () ;do{Read_Temperature() ;Disp_Temperature() ;}while(!presence) ;Error_Menu () ;do{Init_DS18B20() ;beep() ;}while(presence) ;}。