DS1820的C51程序
#DS18B20多点测温(51_C程序)

DS18B20多点测温<读序列,匹配序列,51 C程序,1602显示)因为本人在前两天找DS18B20多点测温<51C程序),网上下载了很多,但是都不是很理想,后来,自己总结前人的知识,重新写了这个程序。
其中包括程序一:单个读序列号。
程序二,匹配并且读两个DS18B20,当然,读多个与读两个基本原理一样,只要加上其序列号等即可。
本程序所有显示都是用LCD160 2显示。
程序一:度序列号,并用1602显示,1602从左到右分别是低到高位。
#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[]={""}。
unsigned char code str2[]={" "}。
uchar fCode[8]。
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>。
C51单总线控制2个18b20测温程序

#include<reg52.h>#include<intrins.h>#include<stdio.h>#define uchar unsigned char#define uint unsigned intuchar num;sbit lcd_en=P2^2;sbit lcd_rw=P2^3;sbit lcd_rs=P2^4;#define lcd_date P0/*****数码管端口定义*******************/sbit LEDCLK=P3^4;sbit LEDDIN=P2^3;/***************************//************************************************************** 延时函数*功能: 可随意设置延时时间,延时时间为(tt*9+16)us.晶振为12MHz***************************************************************/ void delay_us(unsigned int tt){while(tt--){;}}/*****************************************************延时函数*功能: 可随意设置延时时间,延时时间为tt ms.晶振为12MHz*****************************************************/void delay_ms(unsigned int tms){unsigned char i;while(tms--)for(i=123;i>0;i--);}void Write_com(uchar com){lcd_rs=0;lcd_date=com;delay_ms(2);lcd_en=1;delay_ms(2);lcd_en=0;}void Writ_dat(uchar dat){lcd_rs=1;lcd_date=dat;delay_ms(2);lcd_en=1;delay_ms(2);lcd_en=0;}/*------------------------------------------------写入字符函数------------------------------------------------*/void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) {if (y == 0){Write_com(0x80 + x);}else{Write_com(0xC0 + x);}Writ_dat( Data);}/************************************************写入字符串函数**************************************************/void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) {if (y == 0){Write_com(0x80 + x);}else{Write_com(0xC0 + x);}while (*s){Writ_dat( *s);s ++;}}void lcd_init(){lcd_rw=0;lcd_en=0;delay_ms(15);Write_com(0x38);delay_ms(5);Write_com(0x38);delay_ms(5);Write_com(0x38);//显示模式设置Write_com(0x08);//显示关闭Write_com(0X01);//清屏Write_com(0x06);//显示光标移动设置Write_com(0X0c);//显示开及光标设置}#define uint unsigned int#define uchar unsigned char#define dataa 2000uchar code str1[]={0x28,0x55,0xC5,0xB8,0x00,0x00,0x00,0xA6}; //ROM1 PROTUES中的rom 序列号要变化序号:B8C555uchar code str2[]={0x28,0x37,0xC5,0xB8,0x00,0x00,0x00,0x0B}; //ROM2 序号:B8C537 uchar code table[]={'0','1','2','3','4','5','6','7','8','9'};uchar SN[8];uint temper,temper2,Max;//温度寄存器uchar temp[16];bit flag_low,flag_low2;#define NOP3() _nop_();_nop_();_nop_()sbit DQ=P3^0;sbit Set=P2^7;sbit Up=P2^5;sbit Down=P2^6;sbit Beep=P3^1;bit flag_init;//DS18B20是否存在标志/****DS18B20初始化**************************************/void reset(){flag_init=1;DQ=1;NOP3();DQ=0;delay_us(60);//480~960usDQ=1;delay_us(5);//60usflag_init=DQ;delay_us(25);//241us}/****写一个字节函数*************************************/ void Write_Byte(uchar dat){uchar i;DQ=1;EA=0;for(i=8;i>0;i--){DQ=0;DQ=(bit)(dat&0x01);delay_us(5);//61usDQ=1;dat>>=1;}EA=1;}/*****读数据函数*****************************/uchar Read_Byte(){uchar i,date;DQ=1;EA=0;//关中断for(i=8;i>0;i--){DQ=0;date>>=1;DQ=1;NOP3();if(DQ){date|=0x80;}delay_us(5);//61us}EA=1;//开中断return(date);}/**************************//* 获得SN码**************************/void Get_SN(){uchar i;reset();delay_ms(2);Write_Byte(0x33);for(i=0;i<8;i++)SN[i] = Read_Byte();for(i=0;i<8;i++){sprintf(temp,"%2x",SN[i]);LCD_Write_String(0+i*2,1,temp);}}/**************************//* 对比SN码**************************/void Check_SN(uchar a){char j;Write_Byte(0x55);//发送匹配ROM命令if(a==1){for(j=0;j<8;j++)Write_Byte(str1[j]); //发送18B20的序列号,先发送低字节}if(a==2){for(j=0;j<8;j++)Write_Byte(str2[j]); //发送18B20的序列号,先发送低字节}}/**************************//* 获得温度值**************************/void GET2_tem(uchar z){uchar teml,temh;reset();Write_Byte(0xcc);Write_Byte(0x44);//启动温度转换delay_ms(750);//750msreset();if(z==1){Check_SN(1);}if(z==2){Check_SN(2);}Write_Byte(0xbe);//读取温度值teml=Read_Byte();temh=Read_Byte();if((temh&0xf0)==0xf0)//如果是负温度{flag_low=1;temper=(~((temh)*256+(teml))+1)*6.25;}elsetemper=(temh*256+teml)*6.25;//放大100倍}void GETall_tem(){uchar teml,temh,teml2,temh2;reset();Write_Byte(0xcc);Write_Byte(0x44);//启动温度转换delay_ms(750);//750msreset();Check_SN(1);Write_Byte(0xbe);//读取温度值teml=Read_Byte();temh=Read_Byte();if((temh&0xf0)==0xf0)//如果是负温度{flag_low=1;temper=(~((temh)*256+(teml))+1)*6.25;}elsetemper=(temh*256+teml)*6.25;//放大100倍reset();Check_SN(2);Write_Byte(0xbe);//读取温度值teml2=Read_Byte();temh2=Read_Byte();if((temh2&0xf0)==0xf0)//如果是负温度{flag_low2=1;temper2=(~((temh2)*256+(teml2))+1)*6.25;}elsetemper2=(temh2*256+teml2)*6.25;//放大100倍}init_mcu(){TMOD=0x11;TH1=(65536-dataa)/256;TL1=(65536-dataa)%256;ET1=1;TR1=1;EA=1;}/**************************//* 更新温度值**************************/void Uptemp(){GETall_tem();if(flag_low==1){flag_low=0;LCD_Write_Char(5,0,'-');}elseLCD_Write_Char(5,0,'+');LCD_Write_Char(6,0,table[temper/1000]);LCD_Write_Char(7,0,table[temper%1000/100]);LCD_Write_Char(8,0,'.');LCD_Write_Char(9,0,table[temper%100/10]);LCD_Write_Char(10,0,table[temper%10]);LCD_Write_Char(11,0,0xdf);LCD_Write_Char(12,0,'C');if(flag_low2==1){flag_low2=0;LCD_Write_Char(5,1,'-');}elseLCD_Write_Char(5,1,'+');LCD_Write_Char(6,1,table[temper2/1000]);LCD_Write_Char(7,1,table[temper2%1000/100]);LCD_Write_Char(8,1,'.');LCD_Write_Char(9,1,table[temper2%100/10]);LCD_Write_Char(10,1,table[temper2%10]);LCD_Write_Char(11,1,0xdf);LCD_Write_Char(12,1,'C');}void Upmax(){LCD_Write_Char(6,1,table[Max%100/10]);LCD_Write_Char(7,1,table[Max%10]);LCD_Write_Char(8,1,0xdf);LCD_Write_Char(9,1,'C');}void Key(){uchar i=0;Write_com(0x01);//清屏LCD_Write_String(1,0,"MAX Tempr Set");Upmax();while(i==0){if(Up==0){delay_ms(2);if(Up==0){Max++;if(Max==100) Max=0;Upmax();}while(Up==0);}if(Down==0){delay_ms(2);if(Down==0){Max--;if(Max>100)Max=99;Upmax();}while(Down==0);}if(Set==0){delay_ms(2);if(Set==0){i++;}while(Set==0);}}}main(){init_mcu();lcd_init();/*Get_SN();while(1);*/ Max=30;LCD_Write_String(2,0,"T0");LCD_Write_String(2,1,"T1");while(1){Uptemp();}}/***定时器1中断********************************/ void time1_int() interrupt 3{TH1=(65536-dataa)/256;TL1=(65536-dataa)%256;if(Set==0){delay_ms(2);if(Set==0){while(Set==0);Key();}Write_com(0x01);//清屏LCD_Write_String(2,0,"T0");LCD_Write_String(2,1,"T1");}if(temper/100+1>Max||temper2/100+1>Max)Beep=0;else Beep=1;}仿真图。
Ds1820 源程序

Ds1820 源程序网上有很多这样的例程啊。
给你一个STC的,STC的下载程序方便,上手也比较快CPU:STC12C5A48S2#include "18B20.h"#include<intrins.h>#include <math.h> //要用到取绝对值函数abs()/**************************************延时X微秒(STC12C5A60S2@12M)不同的工作环境,需要调整此函数此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同**************************************/sbit DQ=P1^0; //定义18B20数据脚为P1.0端口void DelayXus(uint n){while (n--){_nop_();_nop_();}}void getTmp_Update(){uint TPL,TPH,tmpvalue,value;float t;Room_tmep=0;DS18B20_Reset(); //设备复位DS18B20_WriteByte(0xCC); //跳过ROM命令DS18B20_WriteByte(0x44); //开始转换命令while (!DQ){}; //等待转换完成DS18B20_Reset(); //设备复位DS18B20_WriteByte(0xCC); //跳过ROM命令DS18B20_WriteByte(0xBE); //读暂存存储器命令TPL = DS18B20_ReadByte(); //读温度低字节TPH = DS18B20_ReadByte(); //读温度高字节tmpvalue = TPH;tmpvalue <<= 8;tmpvalue |= TPL;value = tmpvalue;t = value * 0.0625; //使用DS18B20的默认分辨率12位, 精确度为0.0625度, 即读回数据的最低位代表0.0625度/* 如果将它放大100倍, 使显示时可显示小数点后两位, 并对小数点后第三进行4舍5入, 如t=11.0625, 进行计数后, 得到value = 1106, 即11.06 度,如t=-11.0625, 进行计数后, 得到value = -1106, 即-11.06 度*/Room_tmep= t; //得到最终温度}/**************************************复位DS18B20,并检测设备是否存在**************************************/void DS18B20_Reset(){uchar i=0;CY = 1;while (CY){DQ = 0; //送出低电平复位信号DelayXus(240); //延时至少480usDelayXus(240);DQ = 1; //释放数据线DelayXus(60); //等待60usCY = DQ; //检测存在脉冲DelayXus(240); //等待设备释放数据线DelayXus(180);i++;if (i>50){AD_Error_code=1;return;}else{if (AD_Error_code==1) {AD_Error_code=0;}}}}/**************************************从DS18B20读1字节数据**************************************/uint DS18B20_ReadByte(){uchar i;uchar dat = 0;for (i=0; i<8; i++) //8位计数器{dat >>= 1;DQ = 0; //开始时间片DelayXus(1); //延时等待DQ = 1; //准备接收DelayXus(1); //接收延时if (DQ) dat |= 0x80; //读取数据DelayXus(60); //等待时间片结束}return dat;}/**************************************向DS18B20写1字节数据**************************************/void DS18B20_WriteByte(uint dat){uchar i;for (i=0; i<8; i++) //8位计数器{DQ = 0; //开始时间片DelayXus(1); //延时等待dat >>= 1; //送出数据DQ = CY;DelayXus(60); //等待时间片结束DQ = 1; //恢复数据线DelayXus(1); //恢复延时}}。
51单片机与ds18b20程序

#include <>#include <>#define uchar unsigned char#define uint unsigned intsbit DQ = P2^2; //数据口define interfacesbit dula = P2^6; //数码管段选sbit wela = P2^7; //数码管位选uint temp; //温度值 variable of temperature//不带小数点unsigned char code table[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//带小数点unsigned char code table1[] ={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};/*************精确延时函数*****************/void delay(unsigned char i){while(--i);}/******************************************此延时函数针对的是12Mhz的晶振delay(0):延时518us 误差:518-2*256=6delay(1):延时7us (原帖写"5us"是错的)delay(10):延时25us 误差:25-20=5delay(20):延时45us 误差:45-40=5delay(100):延时205us 误差:205-200=5delay(200):延时405us 误差:405-400=5*******************************************//*****************DS18B20******************/void Init_Ds18b20(void) //DS18B20初始化send reset and initialization command{DQ = 1; //DQ复位,不要也可行。
基于C51单片机,DS18B20温度计的设计与实现论文范文

EA/VPP:当/EA保持低电平时,那么在此期间外部程序存储器〔0000H-FFFFH〕,不管是否有部程序存储器。注意加密方式1时,/EA将部锁定为RESET;当/EA端保持高电平时,此间部程序存储器。在FLASH编程期间,此引脚也用于施加12V编程电源〔VPP〕。
XTAL1:反向振荡放大器的输入及部时钟工作电路的输入。
ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。在FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如想制止ALE的输出可在SFR8EH地址上置0。此时, ALE只有在执行MOVX,MOVC指令是ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE制止,置位无效。PSEN:外部程序存储器的选通信号。在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。
由DS18B20组建的温度测量单元体积小,便于携带、安装。同时,DS18B20的输出为数字量,可以直接与单片机连接,无需后级A/D转换,控制简单。
单片机设计 温度测量 ds18b20 C51 源程序

/*********************************************************************///// DS18B20温度计C程序/*********************************************************************///使用AT89C2051单片机,12MHZ晶振,用共阳LED数码管//P1口输出段码,P3口扫描//#pragma src(d:\aa.asm)#include "reg51.h"#include "intrins.h" //_nop_();延时函数用#define Disdata P1 //段码输出口#define discan P3 //扫描口#define uchar unsigned char#define uint unsigned intsbit DQ=P3^7; //温度输入口sbit DIN=P1^7; //LED小数点控制uint h;//////*******温度小数部分用查表法**********//uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x 09};//uchar code dis_7[12]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff,0xbf};/* 共阳LED段码表"0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-" */ uchar code scan_con[4]={0xfe,0xfd,0xfb,0xf7}; // 列扫描控制字uchar data temp_data[2]={0x00,0x00}; // 读出温度暂放uchar data display[5]={0x00,0x00,0x00,0x00,0x00};//显示单元数据,共4个数据,一个运算暂存用///////***********11微秒延时函数**********///void delay(uint t){for(;t>0;t--);}///***********显示扫描函数**********/scan(){char k;for(k=0;k<4;k++) //四位LED扫描控制{Disdata=dis_7[display[k]];if(k==1){DIN=0;}discan=scan_con[k];delay(90);discan=0xff;}}/////***********18B20复位函数**********/ow_reset(void){char presence=1;while(presence){while(presence){DQ=1;_nop_();_nop_();DQ=0; //delay(50); // 550usDQ=1; //delay(6); // 66uspresence=DQ; // presence=0继续下一步}delay(45); //延时500uspresence = ~DQ;}DQ=1;}/////**********18B20写命令函数*********///向1-WIRE 总线上写一个字节void write_byte(uchar val){uchar i;for (i=8; i>0; i--) //{DQ=1;_nop_();_nop_();DQ = 0;_nop_();_nop_();_nop_();_nop_();_nop_();//5us DQ = val&0x01; //最低位移出delay(6); //66usval=val/2; //右移一位}DQ = 1;delay(1);}///*********18B20读1个字节函数********///从总线上读取一个字节uchar read_byte(void){uchar i;uchar value = 0;for (i=8;i>0;i--){DQ=1;_nop_();_nop_();value>>=1;DQ = 0; //_nop_();_nop_();_nop_();_nop_(); //4usDQ = 1;_nop_();_nop_();_nop_();_nop_(); //4usif(DQ)value|=0x80;delay(6); //66us}DQ=1;return(value);}///***********读出温度函数**********///read_temp(){ow_reset(); //总线复位write_byte(0xCC); // 发Skip ROM命令write_byte(0xBE); // 发读命令temp_data[0]=read_byte(); //温度低8位temp_data[1]=read_byte(); //温度高8位ow_reset();write_byte(0xCC); // Skip ROMwrite_byte(0x44); // 发转换命令}///***********温度数据处理函数**********/work_temp(){uchar n=0; //if(temp_data[1]>127){temp_data[1]=(256-temp_data[1]);temp_data[0]=(256-temp_data[0]);n=1;}//负温度求补码display[4]=temp_data[0]&0x0f;display[0]=ditab[display[4]];display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);//display[3]=display[4]/100;display[1]=display[4]%100;display[2]=display[1]/10;display[1]=display[1]%10;if(!display[3]){display[3]=0x0A;if(!display[2]){display[2]=0x0A;}}//最高位为0时都不显示if(n){display[3]=0x0B;}//负温度时最高位显示"-"}/////**************主函数****************/main(){Disdata=0xff; //初始化端口discan=0xff;for(h=0;h<4;h++){display[h]=8;}//开机显示8888ow_reset(); // 开机先转换一次write_byte(0xCC); // Skip ROMwrite_byte(0x44); // 发转换命令for(h=0;h<500;h++){scan();} //开机显示"8888"2秒while(1){read_temp(); //读出18B20温度数据work_temp(); //处理温度数据for(h=0;h<500;h++){scan();} //显示温度值2秒}}////*********************结束**************************//。
基于C51的DS18B20多点测温系统

基于C51的DS18B20多点测温体系2013-07-22目次摘要3第一章绪论41.1 开宣布景及意义4第二章体系硬件设计52.1 单片机52.2 DS18B20温度测量模块52.3 液晶显示模块8第三章体系软件设计103. 1体系初始化103.2 温度测量程序11第四章体系仿真调试124.1 体系仿真调试12附录14摘要本文介绍了基于温度传感器DS18b20与AT89C52单片机构成的多点温度散布式测温体系.设计了其体系构成和软件计划.该体系面向现实需求,设定DS18b20温度规模为-55℃~+125℃,采取LCD1602液晶显示屏,显示两路温度传感器的测量温度值.同时经由过程串口通信与PC机进行通信.传输收集到的温度值.现实运用标明.该体系构造简略,抗干扰才能强,合适于良好情形下现场温度的测量,可运用于仓库测温.楼宇空调掌握和临盆进程监控等范畴.症结词:DS18b20,散布式,1602 串口通第一章绪论1.1 开宣布景及意义温度的测量和掌握在储粮仓库.智能楼宇空调掌握及其他的工农业临盆和科学研讨中运用普遍.传统的温度检测是运用诸如热电偶.热电阻.半导体pn结之类的模仿传感器,经旌旗灯号取样电路.放大电路和模数转换电路处理,获取暗示温度值的数字旌旗灯号,再交由微处理器.因为检测情形庞杂,测量点多,旌旗灯号传输距离远及各类干扰的影响,使得传统测量体系的稳固性和靠得住性降低.近年来跟着单片机的成长和传感器技巧的改革,温度检测范畴也完成了从模仿旌旗灯号到数字旌旗灯号的改变.DS18b20温度传感器的普遍运用更是推进了这一范畴的成长.别的液晶显示模块具有体积小.功耗低.显示内容丰硕.超薄轻盈等长处在各类内心和显示体系中得到越来越多的运用,如今也是单片机运用设计中最经常运用的信息显示模块.分解以上产品的成长特色,愿望温度检测体系在将来的成长中有更辽阔的运用空间并且具有更好的现场测量优胜性.第二章体系硬件设计本体系经由过程DS18B20温度传感器收集温度值,经由单片机处来由液晶显示模块显示当前温度值,并经由串口通信将温度传送到PC上2.1 单片机本体系采取AT89C52单片机作为微处理器.AT89C52单片机是ATMEL公司89系列单片机的一种8位Flash单片机.它最大的特色是片内含有8k可反复编程的Flash存储器,可进行1000次的擦写操纵.别的AT89c52单片机采取ATMEL高密度非易掉存储器制作技巧制作,与工业尺度的MCS-51指令集和输出管脚相兼容,并且其兼具省电耐用.机能稳固的特色,是以成为单片机市场的主流产品.本体系采取晶振依据须要肯定体系工作频率为11.0592Mhz.2.2 DS18B20温度测量模块DS18b20是美国DALLAS公司推出的单总线数字化测温集成电路,它具有奇特的单线接口方法,将非电模仿量温度值转换为数字旌旗灯号串行输出仅需占用1位I/O端口,可以或许直接读取被测现场的温度值.它体积小,电压实用规模宽(3v~5v),且可经由过程编程实现9~12位的温度读数,即具有可调的温度分辩率,是以实用性和靠得住性较高,运用普遍.以下是DS18b20的内部构造图.1DS18b20的内部构造图DS18B20有4个重要的数据部件:① 64位激光ROM.64位激光ROM从高位到低位依次为8位CRC.48位序列号和8位家族代码(28H)构成.②温度敏锐元件.③非易掉性温度报警触发器TH和TL.可经由过程软件写入用户报警高低限值.④设置装备摆设存放器.设置装备摆设存放器为高速暂存存储器中的第五个字节.DS18B20在0工作时按此存放器中的分辩率将温度转换成响应精度的数值.DS18B20的测温规模为-55℃~+125℃,在-10℃~+85℃规模内,精度为±℃.在电压低于3.4v时精度误差较大.依据当时序特色以下是DS18B20与AT89C52单片机构成的温度监测体系如下图2.温度监测体系DS18b20的典范运用在本体系中两个温度传感器与单片机衔接方法如下:图2.2.3 传感器与单片机衔接本体系为多点温度测试.DS18B20采取外部供电方法,理论上可以在一根数据总线上挂256个DS18B20,但现实运用中发明,假如挂接20个以上的DS18B20就会产生功耗问题.别的单总线长度也不宜超出0.5M,不然会影响到数据的传输.在本电路板的设计中斟酌到初步实践的精确性,暂运用2个DS18B20分离衔接单片机的p2.6口.对DS18B20的设计,须要留意以下问题(1)对硬件构造简略的单线数字温度传感器DS18B20 进行操纵,须要用较为庞杂的程序完成.编制程序时必须严厉按芯片数据手册供给的有关操纵次序进行,读.写时光片程序要严厉按请求编写.尤其在运用DS18B20 的高测温分辩力时,对时序及电气特征参数请求更高.(2)现实运用时,要留意单线的驱动才能,不克不及挂接过多的DS18B20,同时还应留意最远接线距离.别的还应依据现实情形选择其接线拓扑构造.2.3 液晶显示模块本体系运用的是1602液晶显示模块.1602液晶显示器以其微功耗.体积小.显示内容丰硕.超薄轻盈.位数多.程序简略的诸多长处,在各类内心和低功耗体系中得到普遍的运用.依据显示内容可以分为字符型液晶,图形液晶.依据显示容量又可以分为单行16字,2行16字,两行20字等等.在本体系中运用的是字符型两行16字液晶显示器.在与单片机衔接时运用接口电路(排针)相连,为并行通信.以下是1602液晶显示器外型图和液晶显示的典范运用.图2 液晶显示器外形图1602液晶显示采取尺度的16脚接口,个中:(模块不和有标注)图2.3.2 串口通信第1脚:VSS为地电源第2脚:VDD接5V正电源第3脚:V0为液晶显示器比较度调剂端,接正电源时比较度最弱,接地电源时比较度最高,比较渡过高时会产生“鬼影”,运用时可以经由过程一个10K的电位器调剂比较度第4脚:RS为存放器选择,高电日常平凡选择数据存放器.低电日常平凡选择指令存放器.第5脚:RW为读写旌旗灯号线,高电日常平凡进行读操纵,低电日常平凡进行写操纵.当RS和RW合营为低电日常平凡可以写入指令或者显示地址;当RS为高电平.RW为低电日常平凡可以写入数据.第6脚:E端为使能端,当E端由高电平跳变成低电日常平凡,液晶模块履行敕令.第7~14脚:D0~D7为8位双向数据线.第15~16脚:空脚1602液晶模块内部的字符产生计储器(CGROM)已经存储了不合的点阵字符图形,这些字符有,阿拉伯数字.英文字母的大小写.经常运用的符号.和日文化名等,每一个字符都有一个固定的代码,个中数字与字母同ASCII码兼容.UART是一种通用串行数据总线,用于异步通信.该总线双向通信,可以实现全双工传输和吸收.实现单片机和PC机的通信工作,接一个MAX232 实现电平转化.电路图如下:第三章体系软件设计图3 体系流程图全部体系的功效是由硬件电路合营软件来实现的,当硬件根本定型后,软件的功效也就根本定下来了.本体系主程序重要包含三个子程序,分离为液晶显示子程序,温度测量子程序,串口通信子程序.主体软件架构如左图:3. 1体系初始化体系初始化重要包含UART初始化,液晶显示初始化,温度传感器初始化.UART初始化包含界说准时器/计数器和串行口的工作方法,界说T1为主动重装8位计数器.液晶显示初始化主如果肯定液晶显示器的工作方法.显示开关.光标开关等.温度传感器初始化包含一个由总线掌握器发出的复位脉冲和跟有厥后由传感器发出的消失脉冲.消失脉冲是让总线掌握器知道DS18b20在总线上且已预备好操纵.一个复位脉冲跟着一个消失脉冲标明DS18b20已经预备好发送和吸收数据.以下是初始化序列图.图3.1.1 初始化序列图3.2 温度测量程序温度测量程序主如果DS18b20与单片机之间的ROM操纵敕令和DS18b20的数据读写操纵敕令.当单片机对DS18B20进行初始化,检测到一个消失脉冲后,发出匹配ROM敕令,然后发送ROM码.图3.2.1 DS18b20根本工作流程第四章体系仿真调试4.1 体系仿真调试在keil开辟情形下不克不及进行有用的仿真调试,所以在体系中采取protues单片机仿真对象进行仿真调试.下图为protues仿真读取温度后在LCD1602液晶屏上的显示成果.图4.1..1protues仿真图上位机用串口调试软件来仿真,装配了虚拟串口驱动软件和PROTEUS进行调试仿真.虚拟串口驱动软件用了VSPD 软件.VSPD软件在Window操纵体系上增长了一对在逻辑上交叉互相的虚拟串口,使串口调试助手可以或许和PROTEUS中的单片机串口相连.VSPD软件界面如下:串口仿真成果如下:在串口调试助手上显示两个温度传感器收集到的温度附录温度收集体统道理图PCB图源代码1602函数部分:#define Port P1sbit RS = P2^0; //界说端口sbit RW = P2^1;sbit E = P2^2;/**************************************************************** 微秒延时函数****************************************************************/ void delay_us(unsigned int n) //延时假如须要高精度延时{if (n == 0){return ;}while (--n);}/****************************************************************/ /* 毫秒函数声明 *//****************************************************************/ void delay_ms(unsigned char i){unsigned int b;while(i--)for (b = 1; b < 1000 ; b++) ;}/****************************************************************/ /* 写入敕令函数 *//***************************************************************/ void LCD_write_com(unsigned char com){RS = 0;E = 1;Port = com;delay_us(10);E = 0;}/****************************************************************/ /* 写入数据函数 *//****************************************************************/ void LCD_write_Data(unsigned char Data){RS = 1 ;RW = 0 ;E = 1 ;Port = Data;delay_us(10);E = 0;}/****************************************************************/ /* 写入字符串函数 *//****************************************************************/ void LCD_write_str(unsigned char x,unsigned char y,unsigned char *s){if (y == 0){LCD_write_com(0x80 + x);}else{LCD_write_com(0xc0 + x);while (*s){LCD_write_Data( *s);s++;}}/****************************************************************/ /* 初始化函数 *//****************************************************************/ void LCD_init(void){delay_ms(40);LCD_write_com(0x38); /*显示模式设置*/delay_ms(5);LCD_write_com(0x38);delay_ms(5);LCD_write_com(0x38);delay_ms(5);LCD_write_com(0x38);LCD_write_com(0x08); /*显示封闭*/LCD_write_com(0x01); /*显示清屏*/LCD_write_com(0x06); /*显示光标移动设置*/delay_ms(5);LCD_write_com(0x0C); /*显示开及光标设置*/}/***********************************************************函数名: Display_F函数解释:打印整数型数据,没有地址传入参数:用于Display_float运用传出参数:无返回值:无**********************************************************/void Display_F(unsigned int num){unsigned char sever_num[6],i = 0;if(num == 0)LCD_write_Data(0x30);else{while(num != 0){sever_num[i++] = num % 10 + 0x30 ;num /= 10 ;}while(i--){LCD_write_Data(sever_num[i]);delay_us(500);}}}/***********************************************************函数名: Display_float函数解释:打印浮点型数据,传入参数:打印地址x,y,数据num,小数点后面打印length位传出参数:无返回值:无**********************************************************/void Display_float(unsigned char x,unsigned char y,float numf,unsigned char length){unsigned long Int_num;unsigned int temp = 1;unsigned char i = 0;for (i = 0 ; i < length ; i++){numf *= 10 ;temp *= 10 ;}if (y == 0)LCD_write_com(0x80 + x);elseLCD_write_com(0xc0 + x);Int_num = (long)numf;Display_F(Int_num / temp);LCD_write_Data('.');Display_F(Int_num % temp);}DS18B20函数部分:bit flag = 0;sbit dat=P2^6;uchar xl[2][8] = {{0x28,0x30,0xc5,0xb8,0x00,0x00,0x00,0x8e},{0x28,0x31,0xc5,0xb8,0x00,0x00,0x00,0xb9}}; //两路DS18B20 ROM码void dsdelay(uchar z) //误差 0us{unsigned char a,b;for(z;z>0;z--)for(b=1;b>0;b--)for(a=2;a>0;a--);}void delay(unsigned int z)//延时函数{uchar x,y;for(x=z;x>0;x--)for(y=101;y>0;y--);}///////////////////////////////////////////////DS18B20函数部分////////////void dsinit()//DS18B20初始化{dat=1;dsdelay(4);dat=0; //给一个脉冲旌旗灯号dsdelay(50);//低脉冲旌旗灯号要保持480us——960usdat=1;//拉高dsdelay(9);//略微延时delay(1);}uchar read()//DS18B20 读一个字节{uchar i,k;for (i=8;i>0;i--){dat = 0; // 给脉冲旌旗灯号k>>=1;//将读到的一位数向后移一位dat = 1; // 给脉冲旌旗灯号if(dat) k|=0x80;//假如读到的是1,则,k和0x80进行或运算,首位变成1dsdelay(4);//每位读取中央距离大于1us}return(k);}void write(uchar date)//DS18B20 写一个字节{uchar i,k;k=date;for(i=0;i<8;i++){dat = 0;dat = k&0x01;dsdelay(7);dat = 1;k>>=1;dsdelay(1);}}float read_tempe(uchar num)//从DS18B20存储器中念书温度{int t;float tt;uchar a,b,i;dsinit();//每次对DS18B20输入指令都要先辈行初始化操纵write(0x55);//写序号列号for (i = 0 ; i < 8 ; i++){write(xl[num][i]) ;}write(0x44); // 启动温度转换dsinit();write(0x55);//写序号列号for (i = 0 ; i < 8 ; i++){write(xl[num][i]) ;}write(0xBE); //读取温度存放器等(共可读9个存放器)前两个就是温度a=read();//读出温度的低八位b=read();//读出温度的高八位t=b;t<<=8;//t是int,16位,讲高八位移到前面t=t|a;//将温度的高位与低位归并if ((b & 0x80 )== 0)//断定正负温度{tt=t*0.0625;//将带有小数点位的十六进制数化为十进制flag = 0;}else{tt=(~t + 1 )* 0.0625;flag = 1;}return(tt);}UART函数部分:void InitUART(void)//UART 初始化{TMOD = 0X20; //11.0592M 9600SCON = 0X50;TH1 = 0xfd;TL1 = 0xfd;PCON = 0X00;EA = 1;ES = 1;TR1 = 1;}void Send(unsigned char C)//UART 发送{SBUF = C;while(TI == 0);TI = 0;}主函数部分:uchar lable[]="TEMPE: 'C";//初始显示void Send_Tempe( float tempe,unsigned char num)//串口发送收集到的温度{unsigned long t ;unsigned char i ;unsigned char tt[]="NUM 0 TEMPE 12.50'C\n";tt[4] = num +0x30;tempe = tempe * 100 ;t = (unsigned int) tempe;tt[17] = t%10+0x30;t = t/10 ;tt[16] = t%10+0x30;t = t/10 ;tt[14] =t%10+0x30;t = t/10 ;tt[13] =t%10 +0x30;if(flag == 1)tt[12] = '-';for(i = 0 ; i < 22 ; i++)Send(tt[i]);}void main(){float tempe;unsigned char i;InitUART() ;LCD_init() ;LCD_write_str(0,0, lable);LCD_write_str(0,1, lable);while(1){for (i = 0; i < 2;i++ ){tempe = read_tempe(i);if(flag == 1)LCD_write_str(6,i, "-");elseLCD_write_str(6,i, " ");Display_float(7,i,tempe,2);Send_Tempe(tempe,i) ;delay(10000);}}。
DS18B20数字温度计使用与C51程序

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详细引脚功能描述3.DS18B20的使用方法由于DS18B20采用的是1-Wire总线协议方式,即在一根数据线实现数据的双向传输,而对AT89S51单片机来说,硬件上并不支持单总线协议,因此,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。
由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。
DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。
该协议定义了几种信号的时序:初始化时序、读时序、写时序。
所有时序都是将主机作为主设备,单总线器件作为从设备。
而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。
数据和命令的传输都是低位在先。
DS18B20的复位时序DS18B20的读时序对于DS18B20的读时序分为读0时序和读1时序两个过程。
对于DS18B20的读时序是从主机把单总线拉低之后,在15us之内就得释放单总线,以让DS18B20把数据传输到单总线上。
DS18B20在完成一个读时序过程,至少需要60us才能完成。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
delay(29); // leave it low for 480us
DQ = 1; // allow line to return high
delay(3); // wait for presence
presence = DQ; // get presence signal
文章编号:322----加入日期:02-4-28
『关闭窗口』
DS1820,一线数据传输,仅三条腿的单芯片温度测量,C51程序。(C51list)
//芯片资料请到查找
//DS1820 C51子程序
//这里以11.0592M晶体为Байду номын сангаас,不同的晶体速度可能需要调整延时的时间
//sbit DQ =P2^1;//根据实际情况定义端口
delay(25); // wait for end of timeslot
return(presence); // presence signal returned
} // 0=presence, 1 = no part
//从1-wire总线上读取一个字节
byte read_byte(void)
{
{
union{
byte c[2];
int x;
}temp;
ow_reset();
write_byte(0xCC); // Skip ROM
write_byte(0xBE); // Read Scratch Pad
temp.c[1]=read_byte();
temp.c[0]=read_byte();
byte i;
byte value = 0;
for (i=8;i>0;i--)
{
value>>=1;
DQ = 0; // pull DQ low to start timeslot
DQ = 1; // then return high
delay(1); //for (i=0; i<3; i++);
if(DQ)value|=0x80;
typedef unsigned char byte;
typedef unsigned int word;
//延时
void delay(word useconds)
{
for(;useconds>0;useconds--);
}
//复位
byte ow_reset(void)
{
byte presence;
ow_reset();
write_byte(0xCC); //Skip ROM
write_byte(0x44); // Start Conversion
return temp.x/2;
}
delay(6); // wait for rest of timeslot
}
return(value);
}
//向1-WIRE总线上写一个字节
void write_byte(char val)
{
byte i;
for (i=8; i>0; i--) // writes byte, one bit at a time
{
DQ = 0; // pull DQ low to start timeslot
DQ = val&0x01;
delay(5); // hold value for remainder of timeslot
DQ = 1;
val=val/2;
}
delay(5);
}
//读取温度
char Read_Temperature(void)