DS18B20与LCD1602结合显示温度汇总(可编辑修改word版)
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+LCD(原理图+汇编程序)
;****************************************************************************** ***;****************************************************************************** **;* 描述: *;* DS18B20温度控制1602LCD显示*;**;* 使用方法参考readme.txt文档*;**;**;****************************************************************************** ***;****************************************************************************** **TEMP_ZH DATA 24H ;实时温度值存放单元TEMPL DATA 25H ;TEMPH DATA 26H ;TEMP_TH DATA 27H ;高温报警值存放单元TEMP_TL DATA 28H ;低温报警值存放单元TEMPHC DATA 29H ;TEMPLC DATA 2AHK1 EQU P1.4K2 EQU P1.5K3 EQU P1.6K4 EQU P1.7BEEP EQU P3.7RELAY EQU P1.3LCD_X EQU 2FH ;LCD 地址变量LCD_RS EQU P2.0LCD_RW EQU P2.1LCD_EN EQU P2.2flag1 equ 20H.0 ;DS18B20是否存在标记KEY_UD EQU 20H.1 ;设定KEY 的UP与DOWN 标记date_line equ p3.3;=====================================================ORG 0000HJMP MAINORG 0030HMAIN: MOV SP,#60HMOV A,#00HMOV R0,#20H ;将20H-2FH 单元清零MOV R1,#10HCLEAR: MOV @R0,AINC R0DJNZ R1,CLEARCALL SET_LCDCALL RE_18B20start: CALL RESET ;18B20复位子程序JNB FLAG1,START1 ;DS1820不存在CALL MENU_OKCALL READ_E2CALL TEMP_BJ ;显示温度标记JMP START2START1: CALL MENU_ERRORCALL TEMP_BJ ;显示温度标记JMP $START2:CALL RESETJNB FLAG1,START1 ;DS1820不存在MOV A,#0CCH ; 跳过ROM匹配CALL WRITEMOV A,#44H ; 发出温度转换命令CALL WRITECALL RESETMOV A,#0CCH ; 跳过ROM匹配CALL WRITEMOV A,#0BEH ; 发出读温度命令CALL WRITECALL READcall CONVTEMPCall DISPBCDCALL CONVCALL TEMP_COMPCALL PROC_KEY ; 键扫描SJMP START2;-----------------------------------------------------PROC_KEY:JB K1,PROC_K1 ; 按键K1处理CALL BEEP_BLJNB K1,$MOV DPTR,#M_ALAX1MOV A,#1CALL LCD_PRINTCALL LOOK_ALARMJB K3,$CALL BEEP_BLJMP PROC_K2PROC_K1: ; 按键K2处理JB K2,PROC_ENDCALL BEEP_BLJNB K2,$MOV DPTR,#RESET_A1MOV A,#1CALL LCD_PRINTCALL SET_ALARMCALL RE_18B20 ;将设定的TH,TL值写入DS18B20内CALL WRITE_E2PROC_K2:CALL MENU_OKCALL TEMP_BJPROC_END:RET;============================================;设定报警值TH、TL;============================================SET_ALARM:;CALL RESET_ALARMCALL LOOK_ALARMAS0:JB K1,AS00CALL BEEP_BLJNB K1,$CPL 20H.1 ;UP/DOWN 标记AS00: JB 20H.1,ASZ01 ;20H.1=1,UPJMP ASJ01 ;20H.1=0,DOWNASZ01: JB K2,ASZ02 ;TH值调整(增加)CALL BEEP_BLINC TEMP_THMOV A,TEMP_THCJNE A,#120,ASZ011MOV TEMP_TH,#0ASZ011: CALL LOOK_ALARMMOV R5,#10CALL DELAYJMP ASZ01ASZ02: JB K3,ASZ03 ;TL值调整(增加)CALL BEEP_BLINC TEMP_TLMOV A,TEMP_TLCJNE A,#99,ASZ021MOV TEMP_TL,#00HASZ021: CALL LOOK_ALARM ;MOV R5,#10CALL DELAYJMP ASZ02ASZ03: JB K4,AS0 ;确定调整OKCALL BEEP_BLJNB K4,$RETASJ01:JB K2,ASJ02 ;TH值调整(减少)CALL BEEP_BLDEC TEMP_THMOV A,TEMP_THCJNE A,#0FFH,ASJ011JMP ASJ022ASJ011: CALL LOOK_ALARMMOV R5,#10CALL DELAYJMP AS0ASJ02: JB K3,ASJ03 ;TL值调整(减少)CALL BEEP_BLDEC TEMP_TLMOV A,TEMP_TLCJNE A,#0FFH,ASJ021JMP ASJ022ASJ021: CALL LOOK_ALARM ;MOV R5,#10CALL DELAYJMP AS0ASJ022: CPL 20H.1JMP ASZ01ASJ03: JMP ASZ03RETRESET_ALARM:MOV DPTR,#RESET_A1 ;指针指到显示信息区MOV A,#1 ;显示在第一行CALL LCD_PRINTRETRESET_A1:DB "RESET ALERT CODE";==================================================== ;实际温度值与标记温度值比较子程序;==================================================== TEMP_COMP:MOV A,TEMP_THSUBB A,TEMP_ZH ;减数>被减数,则JC CHULI1 ;借位标志位C=1,转MOV A,TEMP_ZHSUBB A,TEMP_TL ;减数>被减数,则JC CHULI2 ;借位标志位C=1,转MOV DPTR,#BJ5CALL TEMP_BJ3CLR RELAY ;继电器吸合RETCHULI1:MOV DPTR,#BJ3CALL TEMP_BJ3SETB RELAY ;继电器关闭CALL BEEP_BLRETCHULI2:MOV DPTR,#BJ4CALL TEMP_BJ3CALL BEEP_BLRET;-----------------------------------------TEMP_BJ3:MOV A,#0CEHCALL WCOMMOV R1,#0MOV R0,#2BBJJ3: MOV A,R1MOVC A,@A+DPTRCALL WDATAINC R1DJNZ R0,BBJJ3RETBJ3:DB ">H"BJ4:DB "<L"BJ5:DB " !";================================================== ;显示温度标记子程序;================================================== TEMP_BJ:MOV A,#0CBHCALL WCOMMOV DPTR,#BJ1 ;指针指到显示消息MOV R1,#0MOV R0,#2BBJJ1: MOV A,R1MOVC A,@A+DPTRCALL WDATAINC R1DJNZ R0,BBJJ1RETBJ1:DB 00H,"C";================================================= MENU_OK:MOV DPTR,#M_OK1 ;指针指到显示消息MOV A,#1 ;显示在第一行CALL LCD_PRINTMOV DPTR,#M_OK2 ;指针指到显示消息MOV A,#2 ;显示在第一行CALL LCD_PRINTRETM_OK1:DB " DS18B20 OK ",0M_OK2:DB " TEMP: ",0;-----------------------------------------------MENU_ERROR:MOV DPTR,#M_ERROR1 ;指针指到显示消息1MOV A,#1 ;显示在第一行CALL LCD_PRINTMOV DPTR,#M_ERROR2 ;指针指到显示消息1MOV A,#2 ;显示在第一行CALL LCD_PRINTRETM_ERROR1:DB " DS18B20 ERROR ",0M_ERROR2:DB " TEMP: ---- ",0;==================================================== reset: setb date_linenopclr date_linemov r0,#6bh ;主机发出延时复位低脉冲mov r1,#04htsr1: djnz r0,$mov r0,#6bhdjnz r1,tsr1setb date_line ;然后拉高数据线nopnopnopmov r0,#32htsr2: jnb date_line,tsr3 ;等待DS18B20回应djnz r0,tsr2jmp tsr4 ; 延时tsr3: setb flag1 ; 置标志位,表示DS1820存在jmp tsr5tsr4: clr flag1 ; 清标志位,表示DS1820不存在jmp tsr7tsr5: mov r0,#06bhtsr6: djnz r0,$ ; 时序要求延时一段时间tsr7: setb date_lineret;=======================================================RE_18B20:JB FLAG1,RE_18B20ARETRE_18B20A:CALL RESETMOV A,#0CCH ;跳过ROM匹配LCALL WRITEMOV A,#4EH ;写暂存寄存器LCALL WRITEMOV A,TEMP_TH ;TH(报警上限)LCALL WRITEMOV A,TEMP_TL ;TL(报警下限)LCALL WRITEMOV A,#7FH ;12位精确度LCALL WRITERET;------------------------------------------------------------WRITE_E2:CALL RESETMOV A,#0CCH ;跳过ROM匹配LCALL WRITEMOV A,#48H ;把暂存器里的温度报警值拷贝到EEROMLCALL WRITERET;--------------------------------------------------------------READ_E2:CALL RESETMOV A,#0CCH ;跳过ROM匹配LCALL WRITEMOV A,#0B8H ;把EEROM里的温度报警值拷贝回暂存器CALL WRITERET;--------------------------------------------------------------;将自定义字符写入LCD1602的CGRAM中;--------------------------------------------------------------STORE_DATA:MOV A,#40HCALL WCOMMOV R2,#08HMOV DPTR,#D_DATAMOV R3,#00HS_DATA:MOV A,R3MOVC A,@A+DPTRCALL WDATA ;写入数据INC R3DJNZ R2,S_DATARETD_DATA:DB 0CH,12H,12H,0CH,00H,00H,00H,00H;============================================================== write: mov r2,#8 ;一共8位数据CLR Cwr1:clr date_line ;开始写入DS18B20总线要处于复位(低)状态mov r3,#07djnz r3,$ ;总线复位保持16微妙以上rrc a ;把一个字节DATA 分成8个BIT环移给Cmov date_line,c ;写入一个BITmov r3,#3CHdjnz r3,$ ;等待100微妙setb date_line ;重新释放总线nopdjnz r2,wr1 ;写入下一个BITsetb date_lineret;--------------------------------------------------------------------read: mov r4,#4 ; 将温度低位、高位、TH、TL从DS18B20中读出mov r1,#TEMPL ; 存入25H、26H、27H、28Hre00: mov r2,#8re01: clr cysetb date_linenopnopclr date_line ;读前总线保持为低nopnopnopsetb date_line ;开始读总线释放mov r3,#09 ;延时18微妙djnz r3,$mov c,date_line ;从DS18B20总线读得一个BITmov r3,#3CHdjnz r3,$ ;等待100微妙rrc a ;把读得的位值环移给Adjnz r2,re01 ;读下一个BITmov @r1,ainc r1djnz r4,re00ret;*****************************************************; 处理温度BCD 码子程序;**************************************************** CONVTEMP: MOV A,TEMPH ;判温度是否零下ANL A,#80HJZ TEMPC1 ;温度零上转CLR CMOV A,TEMPL ;二进制数求补(双字节)CPL A ;取反加1ADD A,#01HMOV TEMPL,AMOV A,TEMPHCPL AADDC A,#00HMOV TEMPH,ASJMP TEMPC11TEMPC1: MOV TEMPHC,#0AH ;+TEMPC11: MOV A,TEMPHCSWAP AMOV TEMPHC,AMOV A,TEMPLANL A,#0FH ;乘0.0625MOV DPTR,#TEMPDOTTABMOVC A,@A+DPTRMOV TEMPLC,A ;TEMPLC LOW=小数部分BCDMOV A,TEMPL ;整数部分ANL A,#0F0H ;取出高四位SWAP AMOV TEMPL,AMOV A,TEMPH ;取出低四位ANL A,#0FHSWAP AORL A,TEMPL ;重新组合MOV TEMP_ZH,ALCALL HEX2BCD1MOV TEMPL,AANL A,#0F0HSWAP AORL A,TEMPHC ;TEMPHC LOW = 十位数BCDMOV TEMPHC,AMOV A,TEMPLANL A,#0FHSWAP A ;TEMPLC HI = 个位数BCDORL A,TEMPLCMOV TEMPLC,AMOV A,R4JZ TEMPC12ANL A,#0FHSWAP AMOV R4,AMOV A,TEMPHC ;TEMPHC HI = 百位数BCDANL A,#0FHORL A,R4MOV TEMPHC,ATEMPC12: RET;---------------------------------------------------------------HEX2BCD1:MOV B,#064H ;十六进制-> BCDDIV AB ;B= A % 100MOV R4,A ;R7 = 百位数MOV A,#0AHXCH A,BDIV AB ;B = A % BSWAP AORL A,BRET;-------------------------------------------------------------; 小数部分码表;------------------------------------------------------------- TEMPDOTTAB:DB 00H,00H,01H,01H,02H,03H,03H,04HDB 05H,05H,06H,06H,07H,08H,08H,09H;===================================================== LOOK_ALARM:MOV DPTR,#M_ALAX2 ;指针指到显示信息区MOV A,#2 ;显示在第二行CALL LCD_PRINTMOV A,#0C6HCALL TEMP_BJ1MOV A,TEMP_TH ;加载TH数据MOV LCD_X,#3 ;设置位置CALL SHOW_DIG2H ;显示数据MOV A,#0CEHCALL TEMP_BJ1MOV A,TEMP_TL ;加载TL数据MOV LCD_X,#12 ;设置位置CALL SHOW_DIG2L ;显示数据RET;--------------------------------------------M_ALAX1:DB " LOOK ALERT CODE",0M_ALAX2:DB "TH: TL: ",0;--------------------------------------------TEMP_BJ1:CALL WCOMMOV DPTR,#BJ2 ;指针指到显示信息区MOV R1,#0MOV R0,#2BBJJ2: MOV A,R1MOVC A,@A+DPTRCALL WDATAINC R1DJNZ R0,BBJJ2RETBJ2:DB 00H,"C";---------------------------------------------------SHOW_DIG2H: ;在LCD 的第二行显示数字MOV B,#100DIV ABADD A,#30HPUSH BMOV B,LCD_XCALL LCDP2POP BMOV A,#0AHXCH A,BDIV ABADD A,#30HINC LCD_XPUSH BMOV B,LCD_XCALL LCDP2POP BINC LCD_XMOV A,BMOV B,LCD_XADD A,#30HCALL LCDP2RETSHOW_DIG2L: ;在LCD 的第二行显示数字MOV B,#100DIV ABMOV A,#0AHXCH A,BDIV ABADD A,#30HPUSH BMOV B,LCD_XCALL LCDP2POP BINC LCD_XMOV A,BMOV B,LCD_XADD A,#30HCALL LCDP2RET;-------------------------------------------------------------;显示区BCD 码温度值刷新子程序;-------------------------------------------------------------DISPBCD:MOV A,TEMPLCANL A,#0FHMOV 70H,A ;小数位MOV A,TEMPLCSWAP AANL A,#0FHMOV 71H,A ;个位MOV A,TEMPHCANL A,#0FHMOV 72H,A ;十位MOV A,TEMPHCSWAP AANL A,#0FHMOV 73H,A ;百位MOV A,TEMPHCANL A,#0F0HCJNE A,#010H,DISPBCD0SJMP DISPBCD2DISPBCD0: MOV A,TEMPHCANL A,#0FHJNZ DISPBCD2 ;十位数是0MOV A,TEMPHCSWAP AANL A,#0FHMOV 73H,#0AH ;符号位不显示MOV 72H,A ;十位数显示符号DISPBCD2: RET;========================================================== ; LCD 1602 显示子程序;========================================================== CONV:MOV A,73H ;加载百位数据MOV LCD_X,#6 ;设置位置CJNE A,#1,CONV1JMP CONV2CONV1: MOV A,#" "MOV B,LCD_XCALL LCDP2JMP CONV3CONV2: CALL SHOW_DIG2 ;显示数据CONV3: INC LCD_X ;mov a,72h ;十位CALL SHOW_DIG2inc LCD_Xmov a,71h ;个位CALL SHOW_DIG2inc LCD_XMOV A,#'.'MOV B,LCD_XCALL LCDP2MOV A,70h ;加载小数点位INC LCD_X ;设置位置CALL SHOW_DIG2 ;显示数据RET;-------------------------------------------------------SHOW_DIG2: ;在LCD 的第二行显示数字ADD A,#30HMOV B,LCD_XCALL LCDP2RET;---------------------------------------------------------LCDP2: ;在LCD的第二行显示字符PUSH ACC ;MOV A,B ;设置显示地址ADD A,#0C0H ;设置LCD的第二行地址CALL WCOM ;写入命令POP ACC ;由堆栈取出ACALL WDATA ;写入数据RET;---------------------------------------------------------SET_LCD: ;对LCD 做初始化设置及测试CLR LCD_ENCALL INIT_LCD ;初始化LCDCALL STORE_DATA ;将自定义字符存入LCD的CGRAMRETINIT_LCD: ;8位I/O控制LCD 接口初始化MOV A,#38H ;双列显示,字形5*7点阵CALL WCOMcall delay1MOV A,#38HCALL WCOMcall delay1MOV A,#38HCALL WCOMcall delay1MOV A,#0CH ;开显示,显示光标,光标不闪烁CALL WCOMcall delay1MOV A,#01H ;清除LCD 显示屏CALL WCOMcall delay1RET;==================================================CLR_LINE1: ;清除LCD的第一行字符MOV A,#80H ;设置LCD 的第一行地址CALL WCOM ;MOV R0,#24 ;设置计数值C1: MOV A,#' ' ;载入空格符至LCDCALL WDATA ;输出字符至LCDDJNZ R0,C1 ;计数结束RET;==================================================LCD_PRINT: ;在LCD的第一行或第二行显示字符CJNE A,#1,LINE2 ;判断是否为第一行LINE1: MOV A,#80H ;设置LCD 的第一行地址CALL WCOM ;写入命令CALL CLR_LINE ;清除该行字符数据MOV A,#80H ;设置LCD 的第一行地址CALL WCOM ;写入命令JMP FILLLINE2: MOV A,#0C0H ;设置LCD 的第二行地址CALL WCOM ;写入命令CALL CLR_LINE ;清除该行字符数据MOV A,#0C0H ;设置LCD 的第二行地址CALL WCOMFILL: CLR A ;填入字符MOVC A,@A+DPTR ;由消息区取出字符CJNE A,#0,LC1 ;判断是否为结束码RETLC1: CALL WDATA ;写入数据INC DPTR ;指针加1JMP FILL ;继续填入字符RET;=========================================CLR_LINE: ;清除该行LCD 的字符MOV R0,#24CL1: MOV A,#' 'CALL WDATADJNZ R0,CL1RETDE: MOV R7,#250DJNZ R7,$RET;============================================WCOM: ;以8位控制方式将命令写至LCD MOV P0,A ;写入命令CLR LCD_RS ;RS=L,RW=L,D0-D7=指令码,E=高脉冲CLR LCD_RWSETB LCD_ENACALL DELAY1CLR LCD_ENRET;=============================================WDATA: ;以8位控制方式将数据写至LCD MOV P0,A ;写入数据SETB LCD_RSCLR LCD_RWSETB LCD_ENCALL DECLR LCD_ENCALL DERET;=============================================;PRINT A CHAR ON LINE 1;A=ASC DATA, B=LINE X POS;==============================================LCDP1: ;在LCD的第一行显示字符PUSH ACC ;MOV A,B ;设置显示地址ADD A,#80H ;设置LCD的第一行地址CALL WCOM ;写入命令POP ACC ;由堆栈取出ACALL WDATA ;写入数据RET;============================================== BEEP_BL:MOV R6,#100BL2: CALL DEX1CPL BEEPDJNZ R6,BL2MOV R5,#10CALL DELAYRETDEX1: MOV R7,#180DE2: NOPDJNZ R7,DE2RETDELAY: ;(R5)*延时10MSMOV R6,#50DL1: MOV R7,#100DJNZ R7,$DJNZ R6,DL1DJNZ R5,DELAYRETDELAY1: ;延时5MSMOV R6,#25DL2: MOV R7,#100DJNZ R7,$DJNZ R6,DL2RET;================================================ END。
DS18B20温度传感器LCD1602显示
DS18B20温度传感器LCD1602显示#include < reg51.h >#include < intrins.h >#define uchar unsigned char#define uint unsigned intsbit DQ = P3^3 ; //定义DS18B20端口DQbit presence ; //检测18b20是否插好sbit RS = P2^4 ;sbit RW = P2^5 ;sbit EN = P2^6 ;uchar code cdis1[ ] = {" The third group"} ;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} ; //显示单元数据,共4个数据和一个运算暂用unsigned char code ditab[16] = {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09} ;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_() ;}}}bit Lcd_BusyTest() //lcd_busy为1时,忙,等待。
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测温 1602显示
/***********************************************程序名称:DS18b20温度显示编写:wdc日期:2010-4-27简要说明:使用DS18b20A/D转化器,P3^7接数据I/O口DQ,P2^0-P2^7接1602的D0-D7,P3^0接rs,P3^1接r/w,P3^2接en 函数列表:void delay(int a);延时,以us计算void delayms(int z); 延时,以ms计算unsigned char reset(void) 复位程序unsigned char read_bit(void) 从DS18b20读一个位unsigned char read_byte(void) 从DS18b20读一个字节void write_bit(char bitval) 向DS18b20写一个位void write_byte(char val) 向DS18b20写指令一个字节void tmconvert(void) 温度转化int gettm(void) 读取温度修改记录:增加1602显示:void display(long m)定时器0中断:void timer0() interrupt 1***********************************************/#include <reg51.h>#define uchar8 unsigned char#define uint16 unsigned intuchar8 dis[6] = { 0, 0, 0, 0, 0, 0 };uchar8 code wendu[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; //0到9的代码uchar8 code name[]={"by:wdc 2010-5-1"};uchar8 flag,sig; //flag用于判定是否有中断,sig判定温度符号sbit rs = P3^0; //1602 数据/命令sbit rw = P3^1; // 读/写sbit en = P3^2; // 使能端sbit DQ = P3^7; //18b20与单片机连接的DQ总线/*延时函数*/void delay (int us) //DELAY-11.0592MHZ 调用程序大约为24us,每次循环为16us {int s;for(s=0;s<us;s++);}void delayms(int z) //z为毫秒数{int x,y;for(x=z;x>0;x--)for(y=125;y>0;y--);}/**********************函数名称:写指令输入参数:指令输出参数:数据口输出指令功能:对1602执行特定命令***********************/void write_com(uchar8 com) //写指令{delayms(5);rs = 0; //选择写指令rw = 0;P2 = com;en = 1; //en先1后0为高脉冲delayms(5);en = 0;}/**********************函数名称:写数据输入参数:数据,字母则是ASCIL值输出参数:数据口输出数据功能:令1602显示数据***********************/void write_dat(uchar8 dat) //写数据{delayms(5);rs = 1; //选择写数据rw = 0;P2 = dat;en = 1; //en先1后0为高脉冲delayms(5);en = 0;}/**********************函数名称:初始化输入参数:无输出参数:无调用函数:void w_cmd(uchar cmd)功能:对1602进行初始化,具体过程应严格参照产品说明书***********************/void init(viod) //初始化{TMOD=0x01; //定时器0设为工作方式1TH0 =0x3c; //(65536-50000)/256;TL0 =0xb0; //(65536-50000)%256;EA=1; //开总中断ET0=1; //开定时器0中断TR0=1; //启动定时器0rw = 0; //读/写置低write_com(0x38); //设置16x2显示,5x7点阵,8位数据口write_com(0x08); //显示关闭write_com(0x01); //显示清屏,数据指针以及所有显示清零write_com(0x06); //读写数据,光标及数据指针加一write_com(0x0c); //开显示,光标不显示}/***************函数名称:写字符串输入参数:字符串首地址输出参数:无功能:使1602显示字符串****************/void write_char(uchar8 *cha) //字符串的输入{uchar8 i = 0;while (cha[i] != 0){write_dat(cha[i]); //写一个数据i++; //i自加一次delayms(50); //延时50ms}}/*复位程序*/unsigned char reset(void){uchar8 presence;DQ=0; //拉低总线。
DS18B20温度计(1602显示)苏州大学
本程序以52单片机为基础。
实现在LCD1602上显示出序列码或温度(教学实验用)#include <reg52.h>#define uchar unsigned char#define uint unsigned intsbit DQ=P2^2; //单总线uint temp; //温度uchar flag1; //符号sbit rs = P1^0; // 控制LCDsbit rw = P1^1; // 控制LCDsbit lcden = P2^5; //led使能端sbit K2=P3^4; //独立按键k2sbit K1=P3^5; //独立按键k1uchar a,b,c,d,e,f,g,h,A1,A2,A2t,A3,A4;void delay(uint count) //延迟{uint i;while(count){i=200;while(i>0)i--;count--;}}void DQreset(void) //单总线初始化将DQ拉高(上升沿){uint i;DQ=0;i=103;while(i>0)i--;DQ=1;i=4;while(i>0)i--;}bit tmpreadbit() //18b20读位{uint i;bit dat;DQ=0;i++;DQ=1;i++;i++;dat=DQ;i=8;while(i>0)i--;return (dat); //返回dat}uchar tmpread() //18b20读字节{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) //18b20写{uint i;uchar j;bit testb;for(j=1;j<=8;j++){testb=dat&0x01;dat=dat>>1;if(testb){DQ=0;i++;i++;DQ=1;i=8;while(i>0)i--;}else{DQ=0;i=8;while(i>0)i--;DQ=1;i++;i++;}}}void tmpchange(void) //温度转换子程序{DQreset();delay(1);tmpwritebyte(0xcc);tmpwritebyte(0x44);}uint tmp() //读取温度子程序{float tt;uchar a,b;DQreset();delay(1);tmpwritebyte(0xcc);tmpwritebyte(0xbe);a=tmpread(); //a为低八位b=tmpread(); //b为高八位temp=b;temp<<=8;temp=temp|a;tt=temp*0.0625;temp=tt*100+0.5; //(+0.5)四舍五入return temp;}void LCD_WriteCom(uchar com)//LCD写入命令{rs = 0;rw = 0;P0 = com;delay(5);lcden = 0;delay(5);lcden = 1;delay(5);lcden = 0;}void LCD_WriteData(uchar dat) //写入数据rs = 1;rw = 0;lcden = 0;P0 = dat;delay(5);lcden = 1;delay(5);lcden = 0;delay(5);}void LCD_Init() //LCD初始化{LCD_WriteCom(0x38);delay(15);LCD_WriteCom(0x08);delay(3);LCD_WriteCom(0x01);delay(3);LCD_WriteCom(0x06);delay(3);LCD_WriteCom(0x0c);}void Display18B20Rom(char Rom) //display rom {uchar h,l;l = Rom & 0x0f;h = Rom & 0xf0;h >>= 4;if( ( h >= 0x00 )&&( h <= 0x09 ) )LCD_WriteData(h+0x30);elseLCD_WriteData(h+0x37);if( ( l >= 0x00 )&&( l <= 0x09 ) )LCD_WriteData(l+0x30);elseLCD_WriteData(l+0x37);}void temshow() //温度显示{tmpchange();temp=tmp();A1=temp/1000;A2=(temp%1000)/100;A3=((temp%1000)%100)/10;A4=((temp%1000)%100)%10;LCD_WriteCom(0x80) ;LCD_WriteData('t') ;LCD_WriteData('e');LCD_WriteData('m') ;LCD_WriteData('p') ;LCD_WriteData(':') ;LCD_WriteCom(0x80+0x40) ;LCD_WriteData('+') ;LCD_WriteData('0'+A1);LCD_WriteData('0'+A2) ;LCD_WriteData('.') ;LCD_WriteData('0'+A3) ;LCD_WriteData('0'+A4) ;}void romshow() //序列码显示{LCD_Init();rw = 0;DQreset();delay(1);tmpwritebyte(0x33);delay(1);a = tmpread();b = tmpread();c = tmpread();d = tmpread();e = tmpread();f = tmpread();g = tmpread();h = tmpread();LCD_WriteCom(0x80);LCD_WriteData('n');LCD_WriteData('u');LCD_WriteData('m');LCD_WriteData('b');LCD_WriteData('e');LCD_WriteData('r');LCD_WriteCom(0x80+0x40);Display18B20Rom(a);Display18B20Rom(b);Display18B20Rom(c);Display18B20Rom(d);Display18B20Rom(e);Display18B20Rom(f);Display18B20Rom(g);Display18B20Rom(h);}void main(){if(K1==0) //独立键盘k1按下{LCD_WriteCom(0x01);romshow(); //显示序列码}if(K2==0) //独立键盘k2按下{LCD_WriteCom(0x01);while(K1!=0) //实时扫描{temshow();}}}。
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温度计 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程序(含1602显示液晶程序)
lcden=0;
write_com(0x38); //设置16*2显示,5*7点阵,8位数据接口
write_com(0x0c); //设置开显示,不显示光标
write_com(0x06); //写一个字符后地址指针加1
write_com(0x01); //显示清0,数据指针清0
{
uint i; //初始化,先将数据线置高电平(单片机管脚默认高电平,故不用拉高),延时,时间尽可能短
ds=0; //数据线拉到低电平0
i=103;
while(i>0)i--; //循环执行相当于延时,延时480-960us,一条指令周期相当于1~4个及其周期(1us)
b=tempread(); //读高8位
temp=b;
temp<<=8; //temp=temp<<8,左移8位
temp=temp|a; //两个8位数据合并成一个数据,两个字节组合为1个字
f_temp=temp*0.0625; //温度在寄存器中为12位 分辨率位0.0625°
{
do
{
SBUF = *parr++; //发送数据
while(!TI); //等待发送完成标志为1
TI =0; //标志清零
}while(*parr); //保持循环直到字符为'\0'
uint temp;
float f_temp;
void delay(uint z)//延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
(完整word版)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以实现多点监测.2、9字节的暂存器单元表1DS18B20的暂存器单元如表1所示,各部分介绍如下。
52单片机DS18B20温度计(1602显示)
//按下K1显示序列码,按下K2显示实时温度(本实验适合初学者调试理解18B20用,)#include <reg52.h>//52单片机#define uchar unsigned char#define uint unsigned int //uint 无符号整数sbit DQ=P2^2; //单总线(与自己的开发板相匹配)uint temp; //温度uchar flag1; //符号sbit rs = P1^0; // 控制LCD (与自己的开发板相匹配)sbit rw = P1^1; // 控制LCD (与自己的开发板相匹配)sbit lcden = P2^5; //led使能端(与自己的开发板相匹配)sbit K1=P3^4; //独立按键k1(与自己的开发板相匹配)sbit K2=P3^5; //独立按键k2 (与自己的开发板相匹配)sbit du=P2^6; //位选(防LED灯乱闪)(与自己的开发板相匹配)sbit we=P2^7; //段选(防LED灯乱闪) (与自己的开发板相匹配)uchar a,b,c,d,e,f,g,h,A1,A2,A2t,A3,A4,A5;//写在LCD上的字符,具体在程序中看void delay(uint count) //延迟程序 (200*count)/8 毫秒{uint i;while(count){i=200;while(i>0)i--;count--;}}void DQreset(void) //初始化,主机将DQ拉高 (上升沿) (从机检测到上升沿后延时15到60毫秒,从机拉低总线60到240毫秒表示“我”在线){ //从机的工作是自动完成的uint i;DQ=0;i=103;while(i>0)i--;DQ=1;i=4;while(i>0)i--;}bit tmpreadbit() //从18b20读1位{uint i;bit dat;DQ=0;i++;DQ=1;i++;i++;dat=DQ;i=8;while(i>0)i--;return (dat); //返回dat}uchar tmpread() //从18b20读1字节{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) //18b20写1bit (只能用于写命令){uint i;uchar j;bit testb;for(j=1;j<=8;j++) //一位一位地传{testb=dat&0x01;dat=dat>>1;if(testb){DQ=0;i++;i++;DQ=1;i=8;while(i>0)i--;}else{DQ=0;i=8;while(i>0)i--;DQ=1;i++;i++;}}}void tmpchange(void) //温度转换子程序{DQreset();delay(1);tmpwritebyte(0xcc); //CCH跳过ROMtmpwritebyte(0x44); //44H温度转换}uint tmp() //读取温度子程序{float tt;uchar a,b;DQreset(); //无论什么命令, 首先都要发起初始化delay(1);tmpwritebyte(0xcc); //跳过ROM(本实验中实验板上只连接一块18B20) tmpwritebyte(0xbe); //读便签存储器(温度以二进制储存于BEH)a=tmpread(); //a为低八位b=tmpread(); //b为高八位temp=b;temp<<=8;temp=temp|a;tt=temp*0.0625; //二进制乘0.0625为十进制temp=tt*1000; //精度为0.001return temp;}void LCD_WriteCom(uchar )//LCD写入命令{rs = 0;rw = 0;P0 = ;delay(5);lcden = 0;delay(5);lcden = 1;delay(5);lcden = 0;}void LCD_WriteData(uchar dat)//LCD写入数据{rs = 1;rw = 0;lcden = 0;P0 = dat;delay(5);lcden = 1;delay(5);lcden = 0;delay(5);}void LCD_Init() //LCD初始化{LCD_WriteCom(0x38);delay(15);LCD_WriteCom(0x08);delay(3);LCD_WriteCom(0x01);delay(3);LCD_WriteCom(0x06);delay(3);LCD_WriteCom(0x0c);}void Display18B20Rom(char Rom) //display rom {uchar h,l;l = Rom & 0x0f;h = Rom & 0xf0;h >>= 4;if( ( h >= 0x00 )&&( h <= 0x09 ) )LCD_WriteData(h+0x30); elseLCD_WriteData(h+0x37);if( ( l >= 0x00 )&&( l <= 0x09 ) )LCD_WriteData(l+0x30); elseLCD_WriteData(l+0x37); }void temshow() //温度显示{//LCD_WriteCom(0x01); 写命令不能放在此位置DQreset(); //无论什么命令, 首先都要发起初始化tmpchange(); //温度转换(相当于读温度前的初始化)temp=tmp(); //读温度A1=temp/10000;A2=(temp%10000)/1000;A3=((temp%10000)%1000)/100;A4=(((temp%10000)%1000)%100)/10;A5=(((temp%10000)%1000)%100)%10;LCD_WriteCom(0x80) ;LCD_WriteData('t') ;LCD_WriteData('e');LCD_WriteData('m') ;LCD_WriteData('p') ;LCD_WriteData(':') ;LCD_WriteCom(0x80+0x40) ;LCD_WriteData('+') ;LCD_WriteData('0'+A1);LCD_WriteData('0'+A2) ;LCD_WriteData('.') ;LCD_WriteData('0'+A3) ;LCD_WriteData('0'+A4) ;LCD_WriteData('0'+A5) ;}void romshow() //序列码显示{LCD_Init();rw = 0;DQreset(); //无论什么命令, 首先都要发起初始化delay(1);tmpwritebyte(0x33); //读ROM,允许主机读出DS18B20的64为二进制序列码(仅限于总线上存在单只DS18B20)delay(1);a = tmpread();b = tmpread();c = tmpread();d = tmpread();e = tmpread();f = tmpread();g = tmpread();h = tmpread();LCD_WriteCom(0x80);//LCD第一行开始LCD_WriteData('n');LCD_WriteData('u');LCD_WriteData('m');LCD_WriteData('b');LCD_WriteData('e');LCD_WriteData('r');LCD_WriteCom(0x80+0x40);//lCD第二行开始Display18B20Rom(a);Display18B20Rom(b);Display18B20Rom(c);Display18B20Rom(d);Display18B20Rom(e);Display18B20Rom(f);Display18B20Rom(g);Display18B20Rom(h);}void main(){du=0;//(防LED灯乱闪)we=0;//(防LED灯乱闪)if(K2==0) //独立键盘k2按下{LCD_WriteCom(0x01);while(K1!=0) //用while循环实时扫描,当K1没被按下,一直扫描{temshow();}}if(K1==0) //独立键盘k1按下{LCD_WriteCom(0x01);romshow();}}。
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温度控制数码管显示(汇编非常详细)
D S18B20温度控制数码管显示(汇编非常详细)-CAL-FENGHAI-(2020YEAR-YICAI)_JINGBIAN; DS18B20温度控制数码管显示(汇编非常详细)*;* 1、= → 进入设定温度报警值 TL 状态: *;* L--20 *;* 2、→ 进入设定温度报警值 TH 状态: *;* H--28 *;* 3、→ 返回 *;* 4、设定过程:→加键(UP),→减键(DOWN),可快速调。
* ;* **TIMER_L DATA 23HTIMER_H DATA 24HTIMER_COUN DATA 25HTEMPL DATA 26HTEMPH DATA 27HTEMP_TH DATA 28HTEMP_TL DATA 29HTEMPHC DATA 2AHTEMPLC DATA 2BHTEMP_ZH DATA 2CHBEEP EQUDATA_LINE EQURELAY EQUFLAG1 EQUFLAG2 EQU;-------------------------------------------------K1 EQUK2 EQUK3 EQUK4 EQU;=================================================ORG 0000HJMP MAINORG 000BHAJMP INT_T0;--------------------------------------------------MAIN: MOV SP,#30HMOV TMOD,#01H ;T0,方式1MOV TIMER_L,#00H ;50ms定时值MOV TIMER_H,#4CHMOV TIMER_COUN,#00H ;中断计数MOV IE,#82H ;EA=1,ET0=1LCALL READ_E2;LCALL RE_18B20MOV 20H,#00HSETB BEEPSETB RELAYMOV 7FH,#0AH ;熄灭符CALL RESET ;复位与检测DS18B20JNB FLAG1,MAIN1 ;FLAG1=0,DS18B20不存在JMP STARTMAIN1: CALL RESETJB FLAG1,STARTLCALL BEEP_BL ;DS18B20错误,报警JMP MAIN1START:MOV A,#0CCH ; 跳过ROM匹配CALL WRITEMOV A,#044H ; 发出温度转换命令CALL WRITECALL RESETMOV A,#0CCH ; 跳过ROM匹配CALL WRITEMOV A,#0BEH ; 发出读温度命令CALL WRITECALL READ ;读温度数据CALL CONVTEMPCALL DISPBCDCALL DISP1CALL SCANKEYLCALL TEMP_COMPJMP MAIN1;===================================================== ;DS18B20 复位与检测子程序;FLAG1=1 OK, FLAG1=0 ERROR;====================================================== RESET:SETB DATA_LINENOPCLR DATA_LINEMOV R0,#64H ;主机发出延时600微秒的复位低脉冲MOV R1,#03HRESET1: DJNZ R0,$MOV R0,#64HDJNZ R1,RESET1SETB DATA_LINE ;然后拉高数据线NOPMOV R0,#25HRESET2: JNB DATA_LINE,RESET3 ;等待DS18B20回应DJNZ R0,RESET2JMP RESET4 ; 延时RESET3: SETB FLAG1 ; 置标志位,表示DS1820存在JMP RESET5RESET4: CLR FLAG1 ; 清标志位,表示DS1820不存在JMP RESET6RESET5: MOV R0,#064HDJNZ R0,$ ; 时序要求延时一段时间RESET6: SETB DATA_LINERET;=========================================================== ;;=========================================================== WRITE: MOV R2,#8 ;一共8位数据CLR CYWR1:CLR DATA_LINE ;开始写入DS18B20总线要处于复位(低)状态 MOV R3,#09DJNZ R3,$ ;总线复位保持18微妙以上RRC A ;把一个字节DATA 分成8个BIT环移给CMOV DATA_LINE,C ;写入一个BITMOV R3,#23DJNZ R3,$ ;等待46微妙SETB DATA_LINE ;重新释放总线NOPDJNZ R2,WR1 ;写入下一个BITSETB DATA_LINERET;============================================================ ;从DS18B20中读出温度低位、高位和报警值TH、TL;存入26H、27H、28H、29H;============================================================ READ: MOV R4,#4 ; 将温度高位和低位从DS18B20中读出MOV R1,#26H ; 存入26H、27H、28H、29HRE00: MOV R2,#8RE01: CLR CSETB DATA_LINENOPNOPCLR DATA_LINE ;读前总线保持为低NOPNOPNOPSETB DATA_LINE ;开始读总线释放MOV R3,#09 ;延时18微妙DJNZ R3,$MOV C,DATA_LINE ;从DS18B20总线读得一个BITMOV R3,#23DJNZ R3,$ ;等待46微妙RRC A ;把读得的位值环移给ADJNZ R2,RE01 ;读下一个BITMOV @R1,AINC R1DJNZ R4,RE00RET;--------------------------------------------;200ms对闪动标记取反一次;--------------------------------------------INT_T0:PUSH ACCPUSH PSWMOV TL0,TIMER_LMOV TH0,TIMER_HINC TIMER_COUNMOV A,TIMER_COUNCJNE A,#04H,INT_ENDMOV TIMER_COUN,#00HCPL FLAG2INT_END:POP PSWPOP ACCRETI;========================================================== ;重新对 DS18B20 初始化;将设定的温度报警值写入 DS18B20;========================================================== RE_18B20:JB FLAG1,RE_18B20ARETRE_18B20A:CALL RESETMOV A,#0CCH ;跳过ROM匹配LCALL WRITEMOV A,#4EH ;写暂存寄存器LCALL WRITEMOV A,TEMP_TH ;TH(报警上限)LCALL WRITEMOV A,TEMP_TL ;TL(报警下限)LCALL WRITEMOV A,#7FH ;12位精确度LCALL WRITERET;====================================================;功能键扫描子程序;==================================================== SCANKEY:MOV P1,#0F0HJB K1,SCAN_K2CALL BEEP_BLSCAN_K1: CALL ALERT_TLCALL ALERT_PLAYJB K1,SCAN_K1CALL BEEP_BLSCAN_K11: CALL ALERT_THCALL ALERT_PLAYJB K1,SCAN_K11CALL BEEP_BLSCAN_K2: JB K2,SCAN_K3CALL BEEP_BLSCAN_K3: JB K3,SCAN_K4CALL BEEP_BLLCALL RESET_ALERTLCALL RE_18B20LCALL WRITE_E2SCAN_K4: JB K4,SCAN_ENDCALL BEEP_BLSCAN_END: RET;================================================ ;设置温度报警值;================================================ RESET_ALERT:CALL ALERT_TLCALL ALERT_PLAYJNB K3,$ ;K3为位移键SETB TR0RESET_TL:CALL ALERT_PLAYJNB FLAG2,R_TL01mov 75H,7fh ;送入熄灭符mov 76H,7fhCALL ALERT_PLAYJMP R_TL02R_TL01: CALL ALERT_TLmov 75h,7Eh ;送设定值mov 76h,7DhCALL ALERT_PLAY ;显示设定值R_TL02: JNB K1,K011AJNB K2,K011BJNB K3,RESET_THJMP RESET_TLK011A:INC TEMP_TLMOV A,TEMP_TLCJNE A,#120,K012A ;没有到设定上限值,转MOV TEMP_TL,#0K012A: CALL TL_DELJMP RESET_TLK011B:DEC TEMP_TLMOV A,TEMP_TLCJNE A,#00H,K012B ;没有到设定下限值,转MOV TEMP_TL,#119K012B: CALL TL_DELJMP RESET_TL;-------------------------------------------------------RESET_TH:CALL BEEP_BLJNB K3,$RESET_TH1:CALL ALERT_PLAYJNB FLAG2,R_TH01mov 75H,7fh ;送入熄灭符mov 76H,7fhCALL ALERT_PLAYJMP R_TH02R_TH01: CALL ALERT_THmov 75h,7Eh ;mov 76h,7DhCALL ALERT_PLAYR_TH02: JNB K1,K021AJNB K2,K021BJNB K3,K002JMP RESET_TH1K021A:INC TEMP_THMOV A,TEMP_THCJNE A,#120,K022A ;没有到设定上限值,转 MOV TEMP_TH,#0K022A: CALL TH_DELJMP RESET_TH1K021B:DEC TEMP_TH ;减1MOV A,TEMP_THCJNE A,#00H,K022B ;没有到设定下限值,转 MOV TEMP_TH,#119K022B: CALL TH_DELJMP RESET_TH1K002: CALL BEEP_BLCLR TR0 ;关闭中断RET;-----------------------------------------------------;键延时子程序;多次调用报警值显示程序来延时;-----------------------------------------------------TL_DEL: ;报警低值延时MOV R2,#0AHTL_DEL1: CALL ALERT_TLCALL ALERT_PLAYDJNZ R2,TL_DEL1RETTH_DEL: ;报警高值延时MOV R2,#0AHTH_DEL1: CALL ALERT_THCALL ALERT_PLAYDJNZ R2,TH_DEL1RET;==================================================== ;实时温度值与设定报警温度值 TH、TL 比较子程序;当实际温度大于 TH 的设定值时,显示“H”,继电器关闭。
DS18B20温度测量 1602显示
这是我写的DS18B20测温程序,使用51单片机,STC89C52。
1602的RW引脚连接单片机P2.1,E连接P2.2,1602数据口接单片机P0口。
DS18B20引脚连接P3^3。
#include<reg52.h> //包含单片机寄存器的头文件#include<intrins.h> //包含_nop_()函数定义的头文件#define uint unsigned int#define uchar unsigned charsbit RS=P2^0; //寄存器选择位,将RS位定义为P2.0引脚//1602引脚定义sbit RW=P2^1; //读写选择位,将RW位定义为P2.1引脚sbit E=P2^2; //使能信号位,将E位定义为P2.2引脚sbit BF=P0^7; //忙碌标志位,,将BF位定义为P0.7引脚//1602数据口接单片机P0口sbit ds=P3^3; //DS18B20引脚定义uint temp;float f_temp;unsigned char code User[]={0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00};//自定义字符℃/*****************************************************以下为1602模块语句***************************************************//*****************************************************函数功能:延时1ms***************************************************/void delay1ms(){unsigned char i,j;for(i=0;i<10;i++)for(j=0;j<33;j++);}/*****************************************************函数功能:延时若干毫秒入口参数:n***************************************************/void delay(unsigned int n){unsigned int i;for(i=0;i<n;i++)delay1ms();}/*****************************************************函数功能:判断液晶模块的忙碌状态返回值:result。
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);//把松手检测部分去除后,按下后时间一直减小}}}}原理图:。
ds18b20+1602温度
#include<at89x52.h>#include"ds1602.h"sbit DQ=P2^7; //ds18b20温度接口控制管脚bit f; //负号标志位uchar tempint,tempp; //整数和小数分别存储void delayus(uchar t) //us的延时{while(t--);}void start() //初始化ds18b20{DQ=1; //总线拉高电平delayus(2); //稍微延时DQ=0; //总线拉低delayus(80); //延时一段时间DQ=1; //总线拉高delayus(30); //延时60uswhile(!DQ); //等待外接电阻拉高电平}void writeds(uchar cmd) //写8位{uchar i;DQ=1; //拉高总线for(i=8;i>0;i--) //循环8次写入{DQ=0; //总线拉低DQ=cmd&0x01; //将数据放在总线上,进行采集delayus(10);DQ=1; //释放总线delayus(1);cmd=cmd>>1; //数据右移一位,准备下次数据}}void readds() //读ds18b20的数据{uint k;uchar i,j,temp,th,tl;j=2; //读2位字节数据do{for(i=8;i>0;i--) //一个字节分8位读取{DQ=0; //数据线置低电平temp>>=1; //读取1位右移1位DQ=1; //拉高总线delayus(1);if(DQ)temp|=0x80; //读取1位数据delayus(10);}if(j==2) //读取的第一字节存tltl=temp;else //读取的第二字节存thth=temp;}while(--j);f=0; //初始温度标志为正if((th&0xf8)!=0x00) //若温度为负的处理,对二进制补码的处理{f=1; //f=1时为负温度th=~th; //负数的补码是求反加1tl=~tl;k=tl+1;tl=k;if(k>255) //若超过8位的最大值,th加1th++;}tempp=tl&0x0f; //tl的低四位为小数部分tl>>=4;th<<=4;tempint=th|tl; //tl的高四位,th的低三位组成整数部分}void get_temperature() //温度转换,获得温度子程序{start(); //初始化ds18b20writeds(0xcc); //发跳过ROM匹配命令writeds(0x44); //发温度转换命令start(); //初始化ds18b20writeds(0xcc); //发跳过ROM匹配命令writeds(0xbe); //发读温度命令readds(); //将读出的温度数据保存}void display() //显示温度{uchar x1,x2,x3;wcmd(0x83,0); //1602显示的首地址if(f)wdat(0x2d); //显示正号elsewdat(0x2b); //显示负号x1=tempint/100; //整数百位if(x1)wdat(x1+0x30);x2=tempint%100/10; //整数十位if(x2)wdat(x2+0x30);x3=tempint%10; //整数个位wdat(x3+0x30);wdat(0x2e); //小数点显示wdat(tempp*625/1000+0x30); //小数部分显示wdat(' ');}void main(){init(); //1602初始化while(1){get_temperature(); //获得温度display(); //显示温度}}/*****************************液晶显示1602.h的文件*****************************/#ifndef ds1820#define ds1820#include<at89x52.h>#define uchar unsigned char#define uint unsigned int#define rs P2_2 //1602的RS端由P2.2端口控制#define e P2_0 //1602的e端由P2.0端口控制#define rw P2_1 //1602的rw端由P2.1端口控制#define BF 0X80 //忙检测标志/***************************延时1ms的程序***************************/void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=115;y>0;y--);}/**************************1602的基本设计**************************/uchar busy() //忙检测子程序{rs=0; //低电平代表选择指令寄存器rw=1; //高电平代表读操作e=1; //高电平时,进行读操作delay(1);while(P0&BF);e=0; //下降沿时用于执行命令操作return P0;}void wdat(uchar dat) //写数据到1602子程序{P0=dat;busy();rs=1; //高电平时代表选择数据寄存器rw=0; //低电平时进行读操作delay(2);e=1;delay(2);e=0;}void wcmd(uchar cmd,uchar BFC) //写指令到1602{P0=cmd;if(BFC) busy();rs=0;rw=0;delay(2);e=1;delay(2);e=0;}void init(){e=0;wcmd(0x38,0);wcmd(0x38,0);wcmd(0x38,0);wcmd(0x38,1); //工作模式设置,8位数据线,双行显示,要忙检wcmd(0x08,1); //关闭显示屏幕和光标wcmd(0x01,1); //显示清屏wcmd(0x06,1); //显示光标向右移动wcmd(0x0c,1); //显示屏幕开启,但光标不出现}#endif。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
单总线系统包括一个总线控制器和一个或多个从机。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);外接供电电源输入端
3(VDD,在寄生电源接线方式时接地)。它是一种单总线数字温度传感器,所有的数据交
提示:DS18B20 外形酷似三极管,分辨引脚时,面对着扁平的那一面,左负右正,一
旦接反就会立刻发热,甚至有可能烧毁。
二、DS18B20 存储器结构
DS18B20 的内部有 64 位的 ROM 单元,和 9 字节的暂存器单元。
1、64 位(激)光刻只读存储器
每只 DS18B20 都有一个唯一存储在 ROM 中的 64 位编码(跟人的身份证号类似,一人
时间越短、反应越快、精度越低。 单总线没有时钟线,只有一根通信线,其读写数据是靠
控制起始时间和采样时间来完成,所以时序要求很严格。图 1(a)为 DS18B20 与单片机的连
接电路图,它的数据线通常要求外接一个 4.7K -10K 的上拉电阻(该电阻画原理图时靠
近单片机画故没有显示出来),故其闲置时状态位高电平。
CRC 的计算等式如下: CRC = X8 + X5 + X4 + 1
单总线 CRC 可以由一个由移位寄存器和 XOR 门构成的多项式发生器来产生。这个回 路包括一个移位寄存器和几个 XOR 门,移位寄存器的各位都被初始化为 0。从 ROM 中的 最低有效位或暂存器中的位 0 开始,一次一位移入寄存器。在传输了 56 位 ROM 中的数据 或移入了暂存器的位 7 后,移位寄存器中就存储了 CRC 值。下一步,CRC 的值必须被循 环移入。此时,如果计算得到的 CRC 是正确的,移位寄存器将复 0。
图3 表2
2
4)、CRC 发生器 CRC 字节作为 DS18B2064 位 ROM 的一部分存储在存储器中。CRC 码由 ROM 的前
56 位计算得到,被包含在 ROM 的重要字节当中。CRC 由存储在存储器中的数据计算得到, 因此当存储器中的数据发生改变时,CRC 的值也随之改变。
CRC 能够在总线控制器读取 DS18B20 时进行数据校验。为校验数据是否被正确读取, 总线控制器必须用接受到的数据计算出一个 CRC 值,和存储在 DS18B20 的 64 位 ROM 中 的值(读 ROM 时)或 DS18B20 内部计算出的 8 位 CRC 值(读存储器时)进行比较。如 果计算得到的 CRC 值和读取出来的 CRC 值相吻合,数据被无错传输。CRC 值的比较以及 是否进行下一步操作完全由总线控制器决定。当在 DS18B20 中存储的或由其计算到 CRC 值和总线控制器计算的值不相符时,DS18B20 内部并没有一个能阻止命令序列进行的电路。
换和控制都通过这根数据线来完成。测试温度范围-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 数据位越低、转换
点监测。
2、9 字节的暂存器单元
表1
1
DS18B20 的暂存器单元如表 1 所示,各部分介绍如下。 1)、温度传感器
图2 暂存器的第 0(LSB)字节,第 1(MSB)字节为 DS18B20 的温度传感器,它们负责保存对 温度的测量结果,用 16 位二进制提供,格式如图 2 所示。DS18B20 读取温度时共读取 16 位,前 5 个位(MSB 的高 5 位)为符号位,当前 5 位为 1 时,读取的温度为负数;当前 5 位 为 0 时,读取的温度为正。温度为正时读取方法为:将 16 进制数转换成 10 进制即可。温 度为负时读取方法为(实际就是取补码):将 16 进制取反后加 1,再转换成 10 进制。例: 0550H = +85 度,FC90H = -55 度,0191H 为 25.0625 度。LSB 的低四位用于表示测量值中 小数点后的数值。 2)、非挥发的温度报警触发器 TH 和 TL 位于第 2 和第 3 字节,用于写入温度报警值,实际上就是设定温度的最高和最低界限。 3)、配置寄存器 配置寄存器位于存储器的第 4 字节,其组织如图 3 所示。配置寄存器的 0~4 位和 7 位 被器件保留,禁止写入;在读回数据时全部为逻辑 1。R1 和 R0 用于设置 DS18B20 的精度, 具体如表 2 所示。