用51单片机和18b20做一个温度计,求一个完整程序,要求用12864显示。

如题所述

这个是用数码显示的 你自己改改显示就ok了 12864 有带字库的那种,只要输入ASCII码就行了 程序有点乱,你注意换行就行

1.DS18B20基本知识
DS18B20数字温度计是DALLAS公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。
1、DS18B20产品的特点
(1)、只要求一个端口即可实现通信。
(2)、在DS18B20中的每个器件上都有独一无二的序列号。
(3)、实际应用中不需要外部任何元器件即可实现测温。
(4)、测量温度范围在-55。C到+125。C之间。
(5)、数字温度计的分辨率用户可以从9位到12位选择。
(6)、内部有温度上、下限告警设置。
2、DS18B20的引脚介绍
TO-92封装的DS18B20的引脚排列见图1,其引脚功能描述见表1。
(底视图)图1

表1 DS18B20详细引脚功能描述
序号 名称 引脚功能描述
1 GND 地信号
2 DQ 数据输入/输出引脚。开漏单总线接口引脚。当被用着在寄生电源下,也可以向器件提供电源。
3 VDD 可选择的VDD引脚。当工作于寄生电源时,此引脚必须接地。
3. DS18B20的使用方法
由于DS18B20采用的是1-Wire总线协议方式,即在一根数据线实现数据的双向传输,而对AT89S51单片机来说,硬件上并不支持单总线协议,因此,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。
由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。该协议定义了几种信号的时序:初始化时序、读时序、写时序。所有时序都是将主机作为主设备,单总线器件作为从设备。而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。数据和命令的传输都是低位在先。
DS18B20的复位时序

DS18B20的读时序
对于DS18B20的读时序分为读0时序和读1时序两个过程。
对于DS18B20的读时隙是从主机把单总线拉低之后,在15秒之内就得释放单总线,以让DS18B20把数据传输到单总线上。DS18B20在完成一个读时序过程,至少需要60us才能完成。

DS18B20的写时序
对于DS18B20的写时序仍然分为写0时序和写1时序两个过程。
对于DS18B20写0时序和写1时序的要求不同,当要写0时序时,单总线要被拉低至少60us,保证DS18B20能够在15us到45us之间能够正确地采样IO总线上的“0”电平,当要写1时序时,单总线被拉低之后,在15us之内就得释放单总线。

4. 实验任务
用一片DS18B20构成测温系统,测量的温度精度达到0.1度,测量的温度的范围在-20度到+100度之间,用8位数码管显示出来。
5. 电路原理图

6. 系统板上硬件连线
(1). 把“单片机系统”区域中的P0.0-P0.7用8芯排线连接到“动态数码显示”区域中的ABCDEFGH端子上。
(2). 把“单片机系统”区域中的P2.0-P2.7用8芯排线连接到“动态数码显示”区域中的S1S2S3S4S5S6S7S8端子上。
(3). 把DS18B20芯片插入“四路单总线”区域中的任一个插座中,注意电源与地信号不要接反。
(4). 把“四路单总线”区域中的对应的DQ端子连接到“单片机系统”区域中的P3.7/RD端子上。
C语言源程序#include <AT89X52.H>#include <INTRINS.h> unsigned char code displaybit[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};unsigned char code displaycode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40};unsigned char code dotcode[32]={0,3,6,9,12,16,19,22,25,28,31,34,38,41,44,48,50,53,56,59,63,66,69,72,75,78,81,84,88,91,94,97};unsigned char displaycount;unsigned char displaybuf[8]={16,16,16,16,16,16,16,16};unsigned char timecount;unsigned char readdata[8]; sbit DQ=P3^7;bit sflag; bit resetpulse(void){unsigned char i; DQ=0;for(i=255;i>0;i--);DQ=1;for(i=60;i>0;i--);return(DQ);for(i=200;i>0;i--);} void writecommandtods18b20(unsigned char command){unsigned char i;unsigned char j; for(i=0;i<8;i++){if((command & 0x01)==0){DQ=0;for(j=35;j>0;j--);DQ=1;}else{DQ=0;for(j=2;j>0;j--);DQ=1;for(j=33;j>0;j--);}command=_cror_(command,1);}} unsigned char readdatafromds18b20(void){unsigned char i;unsigned char j;unsigned char temp; temp=0;for(i=0;i<8;i++){temp=_cror_(temp,1);DQ=0;_nop_();_nop_();DQ=1;for(j=10;j>0;j--);if(DQ==1){temp=temp | 0x80;}else{temp=temp | 0x00;}for(j=200;j>0;j--);}return(temp);} void main(void){TMOD=0x01;TH0=(65536-4000)/256;TL0=(65536-4000)%256;ET0=1;EA=1; while(resetpulse());writecommandtods18b20(0xcc);writecommandtods18b20(0x44);TR0=1;while(1){;}} void t0(void) interrupt 1 using 0{unsigned char x;unsigned int result; TH0=(65536-4000)/256;TL0=(65536-4000)%256;if(displaycount==2){P0=displaycode[displaybuf[displaycount]] | 0x80;}else{P0=displaycode[displaybuf[displaycount]];}P2=displaybit[displaycount];displaycount++;if(displaycount==8){displaycount=0;} timecount++;if(timecount==150){timecount=0;while(resetpulse());writecommandtods18b20(0xcc);writecommandtods18b20(0xbe);readdata[0]=readdatafromds18b20();readdata[1]=readdatafromds18b20();for(x=0;x<8;x++){displaybuf[x]=16;}sflag=0;if((readdata[1] & 0xf8)!=0x00){sflag=1;readdata[1]=~readdata[1];readdata[0]=~readdata[0];result=readdata[0]+1;readdata[0]=result;if(result>255){readdata[1]++;}}readdata[1]=readdata[1]<<4;readdata[1]=readdata[1] & 0x70;x=readdata[0];x=x>>4;x=x & 0x0f;readdata[1]=readdata[1] | x;x=2;result=readdata[1];while(result/10){displaybuf[x]=result%10;result=result/10;x++;}displaybuf[x]=result;if(sflag==1){displaybuf[x+1]=17;}x=readdata[0] & 0x0f;x=x<<1;displaybuf[0]=(dotcode[x])%10;displaybuf[1]=(dotcode[x])/10;while(resetpulse());writecommandtods18b20(0xcc);writecommandtods18b20(0x44);}}
温馨提示:内容为网友见解,仅供参考
第1个回答  2010-10-24

很遗憾,现成的只有1602,也发给你凑数吧

P3是数据,P2.012分别是RS RW E

附张仿真给你

/***************   writer:shopping.w   ******************/

#include <reg52.h>

#include <intrins.h>

#define uint unsigned int

#define uchar unsigned char

#define delayNOP() {_nop_();_nop_();_nop_();_nop_();}

sbit DQ = P3^3;

sbit LCD_RS = P2^0;

sbit LCD_RW = P2^1;

sbit LCD_EN = P2^2;

uchar code Temp_Disp_Title[]={"Current Temp : "};

uchar Current_Temp_Display_Buffer[]={" TEMP:   "};

uchar code Temperature_Char[8] = 

{

  0x0c,0x12,0x12,0x0c,0x00,0x00,0x00,0x00

};

uchar code df_Table[]=

{

  0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9

};

uchar CurrentT = 0;

uchar Temp_Value[]={0x00,0x00};

uchar Display_Digit[]={0,0,0,0};

bit DS18B20_IS_OK = 1;

void DelayXus(uint x)

{

  uchar i;

 while(x--)

 {

   for(i=0;i<200;i++);

 }

}

bit LCD_Busy_Check()

{

  bit result;

 LCD_RS = 0;

 LCD_RW = 1;

 LCD_EN = 1;

 delayNOP();

 result = (bit)(P0&0x80);

 LCD_EN=0;

 return result;

}

void Write_LCD_Command(uchar cmd)

{

 while(LCD_Busy_Check());

 LCD_RS = 0;

 LCD_RW = 0;

 LCD_EN = 0;

 _nop_();

 _nop_();

 P0 = cmd;

 delayNOP();

 LCD_EN = 1;

 delayNOP();

 LCD_EN = 0;

}

void Write_LCD_Data(uchar dat)

{

 while(LCD_Busy_Check());

 LCD_RS = 1;

 LCD_RW = 0;

 LCD_EN = 0;

 P0 = dat;

 delayNOP();

 LCD_EN = 1;

 delayNOP();

 LCD_EN = 0;

}

void LCD_Initialise()

{

  Write_LCD_Command(0x01);

 DelayXus(5);

 Write_LCD_Command(0x38);

 DelayXus(5);

 Write_LCD_Command(0x0c);

 DelayXus(5);

 Write_LCD_Command(0x06);

 DelayXus(5); 

}

void Set_LCD_POS(uchar pos)

{

  Write_LCD_Command(pos|0x80); 

}

void Delay(uint x)

{

  while(--x);

}

uchar Init_DS18B20()

{

  uchar status;

 DQ = 1;

 Delay(8);

 DQ = 0;

 Delay(90);

 DQ = 1;

 Delay(8);

 DQ = 1;

 return status;

}

uchar ReadOneByte()

{

  uchar i,dat=0;

 DQ = 1;

 _nop_();

 for(i=0;i<8;i++)

 {

   DQ = 0;

  dat >>= 1;

  DQ = 1;

  _nop_();

  _nop_();

  if(DQ)

   dat |= 0X80;

  Delay(30);

  DQ = 1;

 }

 return dat;

}

void WriteOneByte(uchar dat)

{

  uchar i;

 for(i=0;i<8;i++)

 {

   DQ = 0;

  DQ = dat& 0x01;

  Delay(5);

  DQ = 1;

  dat >>= 1;

 }

}

void Read_Temperature()

{

  if(Init_DS18B20()==1)

  DS18B20_IS_OK=0;

 else

 {

  WriteOneByte(0xcc);

  WriteOneByte(0x44);

  Init_DS18B20();

  WriteOneByte(0xcc);

  WriteOneByte(0xbe);

  Temp_Value[0] = ReadOneByte(); 

  Temp_Value[1] = ReadOneByte();

  DS18B20_IS_OK=1; 

 } 

}

void Display_Temperature()

{

  uchar i;

 uchar t = 150, ng = 0;

 if((Temp_Value[1]&0xf8)==0xf8)

 {

   Temp_Value[1] = ~Temp_Value[1];

  Temp_Value[0] = ~Temp_Value[0]+1;

  if(Temp_Value[0]==0x00)

   Temp_Value[1]++;

  ng = 1; 

 }

 Display_Digit[0] = df_Table[Temp_Value[0]&0x0f];

 CurrentT = ((Temp_Value[0]&0xf0)>>4) | ((Temp_Value[1]&0x07)<<4);

 Display_Digit[3] = CurrentT/100;

 Display_Digit[2] = CurrentT%100/10;

 Display_Digit[1] = CurrentT%10;

 Current_Temp_Display_Buffer[11] = Display_Digit[0] + '0';

 Current_Temp_Display_Buffer[10] = '.';

 Current_Temp_Display_Buffer[9]  = Display_Digit[1] + '0';

 Current_Temp_Display_Buffer[8]  = Display_Digit[2] + '0';

 Current_Temp_Display_Buffer[7]  = Display_Digit[3] + '0';

 if(Display_Digit[3] == 0)

  Current_Temp_Display_Buffer[7]  = ' ';

 if(Display_Digit[2] == 0&&Display_Digit[3]==0)

  Current_Temp_Display_Buffer[8]  = ' ';

 if(ng)

 {

   if(Current_Temp_Display_Buffer[8]  == ' ')

   Current_Temp_Display_Buffer[8]  = '-';

  else if(Current_Temp_Display_Buffer[7]  == ' ')

   Current_Temp_Display_Buffer[7]  = '-';

  else 

   Current_Temp_Display_Buffer[6]  = '-';

 }

 Set_LCD_POS(0x00);

 for(i=0;i<16;i++)

 {

  Write_LCD_Data(Temp_Disp_Title[i]);  

 }

 Set_LCD_POS(0x40);

 for(i=0;i<16;i++)

 {

  Write_LCD_Data(Current_Temp_Display_Buffer[i]);  

 }  

 Set_LCD_POS(0x4d);

 Write_LCD_Data(0x00);

 Set_LCD_POS(0x4e);

 Write_LCD_Data('C');

}

void main()

{

  LCD_Initialise();

 Read_Temperature();

 Delay(50000);

 Delay(50000);

 while(1)

 {

   Read_Temperature();

  if(DS18B20_IS_OK) 

   Display_Temperature();

  DelayXus(100);  

 }

}

本回答被提问者采纳
第2个回答  2010-10-24
我有现成的,支持热插拔的。不过是要花钱的。

用51单片机和18b20做一个温度计,求一个完整程序,要求用12864显示。
这个是用数码显示的 你自己改改显示就ok了 12864 有带字库的那种,只要输入ASCII码就行了 程序有点乱,你注意换行就行 1.DS18B20基本知识 DS18B20数字温度计是DALLAS公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很...

51单片机上18B20如何在12864上显示两个小数点
temp <<= 8; \/\/两个字节组合为1个字 temp = temp | a;---在1个字之中,最低四位是小数 f_temp = temp * 0.0625; --这里是除以16,就已经把小数的信息,都弄没了 temp = f_temp * 10 + 0.5;\/\/乘以10表示小数点后面只取1位,加0.5是四舍五入 再乘以100,得出的也...

求高手教怎样用18b20测温并且显示在12864中,最好带电路图...
只用18B20和128X64是不能实现的,还需要单片机加程序

用液晶12864和DS18B20传感器做的温度传感器为什么不会变化,老是显示85...
你好 没见你的源程序 显示没变化 可能是你两个子程序中的一个或两个都有问题 再就是在主程序中没有进行循环检测及显示刷新。贴上我的程序 你自己看看吧。老是显示85是上电时18B20没有进入正常状态,读出的数据。把我主程序中对你没有用的删了 自己看着搞吧 硬件接口上须从新对应一下。我的仿真库没有新型...

各位帮我看下这个18B20显示温度程序有什么问题~~多谢了
本制作芯片采用数字温度传感器18b20,利用51单片机控制。DS18B20基本知识 DS18B20数字温度计是DALLAS公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。 1、DS18B20产品的特点 (1)、只要求一个端口即可实现通信。

温度传感器与单片机结合 设计一个电路 不要太复杂 要电路图 和 具体数 ...
也就是做一个数字温度计(体温计)是吧,18B20数字温度计,显示可以用数码管或者LCD1602显示,或者12864都可以的。电路为PROTEL绘制。,程序都有的论文也有的 需要QQ我

为什么单片机控制18B20测温初始总是显示85度然后显示测量值
其他回答 ROM上电的默认值,有的也不是85,只要在上电后先初始化18B20,等一段时间再显示和其他操作就可以了。 changdacekong | 发布于2012-05-13 举报| 评论 0 1 为您推荐: 51单片机原理及应用 单片机测温报告 单片机头 51单片机流水灯电路图 单片机t12测温 51单片机教程 单片机测温显示电路 ...

18b20与lm35dz 程序区别以及lm35dz+12864如何编程 用单片机C语言
端输出为5V,但是由LM358 的数据手册可知:OUT 输出最大值为Vcc-1.5V=3.5V,所示实际测量温度最大值为70℃。当温度大于70℃后LM358 输出为恒定的3.5V,所以不可做大于70℃的恒温控制实训(除非358电源大于7V)。采用5 倍放大的计算公式如下:T=20*ADC\/51,精度为20\/51=0.39216度 ...

求STC12C5204单片机AD功能如何使用,例如,用其中一个I\/O做为AD采样一个...
\/\/本程序主要演示了 \/\/1、12864液晶的编程与使用,包括显示定位、4位整数、显示浮点数等 \/\/2、STC12C5A32S2单片机的ADC 采样功能(以第0、1通道为例)\/\/ \/\/注:本示例仅仅演示如何进行ADC 和显示,每ADC 一次就显示一次,实际应用时,\/\/应多次ADC 并进行相应处理,比如取平均值后,才能得到比较...

如何在液晶上显示汉字,单片机用的ATmega16,液晶是1602,求详细代码
1、此款采用并口ISP下载线,配AT89S52单片机,可以很方便的下载程序到单片机。下载后不用插拔线缆, 下载好后自动直接运行程序。2、USB供电系统,直接插接到电脑USB口即可提供电源,不需另接直流电源。 3、8位数码管(可做数码管的静态扫描以及动态扫描显示实验 不如 0-999 计数器实验 18B20温度检测实验 遥控解码实验等...

相似回答