分享用16F877A和DS18B20的测温程序
[PIC16F877A+汇编语言]DS18B20温度采集程序
[PIC16F877A+汇编语言]DS18B20温度采集程序DS18B20温度采集程序[PIC16F877A+汇编语言];六位数码管显示温度结果,其中整数部分2位,小数部分4位;每次按下RB0键后进行一次温度转换。
;硬件要求:把DS18B20插在18B20插座上; 拨码开关S10第1位置ON,其他位置OFF; 拨码开关S5、S6全部置ON,其他拨码开关全部置OFF;*****************以下是暂存器的定义*****************************#INCLUDE#DEFINE DQ PORTA,0 ;18B20数据口__CONFIG_DEBUG_OFF&_CP_ALL&_WRT_HALF&_CPD_ON&_LVP_OFF &_BODEN_OFF&_PWRTE_ON&_W DT_OFF&_HS_OSC;调试模式关闭,写保护,一半ROM可在线改写,EEPROM加密,低压编程关闭,掉电检测关闭,上电延时开,看门狗关,4M晶振HS 振荡CBLOCK 20HDQ_DELAY1DQ_DELAY2TEMPTEMP1TEMP2 ;存放采样到的温度值TEMP3COUNTCOUNT1ENDCTMR0_VALUE EQU 0AH ;寄存器初值为6,预分频比1:4,中断一次时间为4*(256-6)=1000us DQ_DELAY_VALUE1 EQU 0FAHDQ_DELAY_VALUE2 EQU 4H;**********************以下是程序的开始************************ORG 00HNOPGOTO MAIN ;入口地址ORG 04HRETFIE ;在中断入口出放置一条中断返回指令,防止干扰产生中断TABLEADDWF PCL,1RETLW 0C0H ;0的编码(公阳极数码管)RETLW 0F9H ;1的编码RETLW 0A4H ;2的编码RETLW 0B0H ;3的编码RETLW 99H ;4的编码RETLW 92H ;5的编码RETLW 082H ;6RETLW 0F8H ;7RETLW 080H ;8RETLW 090H ;9;***************************主程序*******************************MAINCLRF PORTACLRF PORTBBANKSEL TRISACLRF TRISA ;A口所有先设置为输出CLRF TRISDMOVLW 01HMOVWF TRISB ;B0口为输入,其他为输出MOVWF ADCON1 ;关闭所有A/D口MOVLW 01HMOVWF OPTION_REG ;分频比1:4,定时器,内部时钟源 BCF STATUS,RP0CLRF TEMPCLRF TEMP1CLRF TEMP2 ;清零临时寄存器MOVLW 8HMOVWF COUNTMOVLW 38HMOVWF FSRCLRF INDFINCF FSR,1DECFSZ COUNT,1GOTO $-3;****************************循环处理部分************************;先启动18B20温度转换程序,在判断温度转换是否完成(需750us);未完成则调用显示子程序,直到完成温度转换;完成后读取温度值;送LCD显示LOOPBTFSC PORTB,0 ;判断温度转换按键是否按下GOTO LOOP1 ;否,转显示CALL DELAY ;消抖BTFSC PORTB,0 ;再次判断GOTO LOOP1CALL RESET_18B20 ;调用复位18B20子程序MOVLW 0CCHCALL WRITE_18B20 ;SKIP ROM命令MOVLW 44HMOVWF TEMPCALL WRITE_18B20 ;温度转换命令CLRF STATUSCALL DELAY_750MS ;调用温度转换所需要的750MS延时NOP CALL RESET_18B20MOVLW 0CCHMOVWF TEMPCALL WRITE_18B20 ;SKIP ROM命令MOVLW 0BEHMOVWF TEMPCALL WRITE_18B20 ;读温度命令CALL READ_18B20 ;调用读温度低字节MOVFW TEMPMOVWF TEMP1 ;保存到TEMP1CALL READ_18B20 ;调用读温度高字节MOVFW TEMPMOVWF TEMP2 ;保存到TMEP2CALL RESET_18B20LOOP1CALL TEMP_CHANGE ;调用温度转换程序CALL DISPLAY ;调用LCD显示程序GOTO LOOP ;循环工作;*********************复位DS18B20子程序************************** RESET_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;主控制器把总线拉低至少480us,;18B20等待15-60us后,把总线拉低做为返回给控制器的应答信号BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF DQMOVLW 0A0HMOVWF COUNT ;160USDECFSZ COUNT,1GOTO $-1 ;拉低480usBSF DQ ;释放总线MOVLW 14HMOVWF COUNTDECFSZ COUNT,1GOTO $-1 ;等待60usBANKSEL TRISABSF TRISA,0 ;DQ设置为输入BCF STATUS,RP0BTFSC DQ ;数据线是否为低GOTO RESET_18B20 ;否则继续复位MOVLW 4HMOVWF COUNTDECFSZ COUNT,1 ;延时一段时间后再次判断GOTO $-1BTFSC DQGOTO RESET_18B20MOVLW 4BHMOVWF COUNTDECFSZ COUNT,1GOTO $-1BANKSEL TRISABCF TRISA,0 ;DQ设置为输出BCF STATUS,RP0RETURN;*********************写DS18B20子程序**************************** WRITE_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;写数据0时,主控制器把总线拉低至少60us;写数据1时,主控制器把总线拉低,但必须在15us内释放MOVLW 8HMOVWF COUNT ;8位数据BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF STATUS,CWRITE_18B20_1BSF DQ ;先保持DQ为高MOVLW 5HMOVWF COUNT1BCF DQ ;拉低DQ15usDECFSZ COUNT1,1GOTO $-1RRF TEMP,1BTFSS STATUS,C ;判断写的数据为0还是1 GOTO WRITE_0BSF DQ ;为1,立即拉高数据线GOTO WRITE_ENDWRITE_0BCF DQ ;继续保持数据线为低WRITE_ENDMOVLW 0FHMOVWF COUNT1 ;保持45msDECFSZ COUNT1,1GOTO $-1BSF DQ ;释放总线DECFSZ COUNT,1 ;是否写完8位数据GOTO WRITE_18B20_1RETURN;**********************读DS18B20子程序**************************** READ_18B20;根据DATASHEET介绍,读数据时应遵照如下规定:;读数据0时,主控制器把总线拉低后,18B20再把总线拉低60us ;读数据1时,主控制器把总线拉低后,保持总线状态不变;主控制器在数据线拉低后15us内读区数据线上的状态。
DS18B20测温程序
DS18B20测温程序(数码显示)*;************************************************************************** ;*接线方法: *;* 1、用一8P的数据线,一头插在J1,另一头插在J5,接通数码管的段选*;* 2、用一8P的数据线,一头插在J4,另一头插在J6,接通数码管的位选*;* 3、将DS18B20插在主机上的测温部份 *;* 4、用一根单根的数据线,一头插在DS18B20所在数据插针,另一头插到P2.7 * ;**************************************************************************TEMPER_L EQU 36H ;从DS18B20中读回高位,低位暂存区TEMPER_H EQU 35H ;TEMPER_NUM EQU 60H;温度值存储TEMPER_GE EQU 61HTEMPER_SHI EQU 62HTEMPER_SAVE EQU 63HFLAG1 BIT 00HFLAG2 BIT 01HRS BIT p3.0;液晶控制接口RW BIT p3.1E BIT p3.2DQ BIT P2.7;单总线口ORG 0000HA JMP MAINORG 0030HMAIN: MOV SP,#70HLCALL GET_TEMPERLCALL TEMPER_COVLCALL DISPLAYLJMP MAINNOP;**************************************************;读出转换后的温度值;**************************************************GET_TEMPER:SETB DQ ; 定时入口BCD: LCALL INIT_1820JB FLAG1,S22LJMP BCD ;若DS18B20不存在则返回S22: LCALL DELAY1MO V A,#0CCH ; 跳过ROM匹配------0CC命令LCALL WRITE_1820MOV A,#44H ; 发出温度转换命令LCALL WRITE_1820LCALL DELAYCBA CALL INIT_1820JB FLAG1,ABCLJMP CBAABC CALL DELA Y1MOV A,#0CCH ; 跳过ROM匹配LCALL WRITE_1820MOV A,#0BEH ; 发出读温度命令LCALL WRITE_1820LCALL READ_18200 ;READ_1820RET;************************************************************** ;读DS18B20的程序,从DS18B20中读出一个字节的数据;************************************************************** READ_1820:MOV R2,#8RE1:CLR CSETB DQNOPNOPCLR DQNOPNOPNOPSETB DQMOV R3,#7DJNZ R3,$MOV C,DQMOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE1RET;******************************************************;写DS18B20的程序;******************************************************WRITE_1820:MOV R2,#8CLR CWR1:MOV R3,#6DJNZ R3,$RRC AMOV DQ,CMOV R3,#23DJNZ R3,$SETB DQNOPDJNZ R2,WR1SETB DQRET;****************************************************;读DS18B20的程序,从DS18B20中读出两个字节的温度数据;****************************************************READ_18200:MOV R4,#2 ; 将温度高位和低位从DS18B20中读出MOV R1,#36H ; 低位存入36H(TEMPER_L),高位存入35H(TEMPER_H) RE00:MOV R2,#8RE01:CLR CSETB DQNOPNOPCLR DQNOPNOPNOPSETB DQMOV R3,#7DJNZ R3,$MOV C,DQMOV R3,#23DJNZ R3,$RRC ADJNZ R2,RE01MOV @R1,ADEC R1DJNZ R4,RE00RET;;****************************************************;将从DS18B20中读出的温度数据进行转换;;****************************************************TEMPER_COV:MOV A,#0F0HANL A,TEMPER_L ; 舍去温度低位中小数点后的四位温度数值SWAP AMOV TEMPER_NUM,A ;得到低四位MOV A,TEMPER_LJNB ACC.3,TEMPER_COV1 ; 四舍五入去温度值INC TEMPER_NUMTEMPER_COV1:MOV A,TEMPER_HANL A,#07HSWAP AORL A,TEMPER_NUM ;得到高四位,再与低四位相或得到值MOV TEMPER_NUM,A ; 保存变换后的温度数据LCALL BIN_BCDRET;;**************************************************** ;将16进制的温度数据转换成压缩BCD码;;**************************************************** BIN_BCD:MOV A,TEMPER_NUMMOV B,#10DIV ABMOV TEMPER_SHI,AMOV TEMPER_GE,BMOV A,TEMPER_SAVECJNE A,TEMPER_GE,ZWFHRET:MOV TEMPER_SAVE,TEMPER_GERETZW:CALL LCDDISPAJMP FHRET;**************************************************** ;DS18B20初始化程序;;**************************************************** INIT_1820:SETB DQNOPCLR DQMOV R0,#250TSR1:DJNZ R0,TSR1 ; 延时520usSETB DQMOV R0,#25H ;96US-25HTSR2:DJNZ R0,TSR2JNB DQ,TSR3;如D0为低则复位成功,DS18B20存在LJMP TSR4 ; 延时TSR3:SETB FLAG1 ; 置标志位,表示DS1820存在LJMP TSR5TSR4:CLR FLAG1 ; 清标志位,表示DS1820不存在LJMP TSR7TSR5:MOV R0,#06BH ;200USTSR6:DJNZ R0,TSR6 ; 延时TSR7:SETB DQ ;拉高总线RET;************************************************* ;数码显示程序;************************************************* Display:MOV DPTR,#disptabMOV A,TEMPER_GEMOVC A,@A+DPTRMOV P1,ACLR P2.2CALL DELAYCALL DELAYSETB P2.2MOV DPTR,#disptabMOV A,TEMPER_SHIMOVC A,@A+DPTRMOV P1,ACLR P2.3CALL DELAYCALL DELAYSETB P2.3RET;************************************************* ;液晶显示程序;*************************************************mov p0,#01h;清屏call enrwmov p0,#38h;设为8位,5*7字型两行 call enrwmov p0,#0Chcall enrwmov p0,#06hcall enrwmov p0,#80hcall enrwmov dptr,#yjtabcall rwrammov p0,#0C0hcall enrwmov dptr,#yjtab1call rwramW_TEM:mov p0,#0CChcall enrwMO V DPTR,#ASCIIMO V A,TEMPER_SHIMO VC A,@A+DPTRMO V P0,Asetb rsclr rwclr ecall delaysetb eMO V DPTR,#ASCIIMO V A,TEMPER_GEMO VC A,@A+DPTRMO V P0,Asetb rsclr rwclr ecall delaysetb eRE Tenrw:clr rsclr rwclr esetb eretrwram:mov r1,#00ha1: mov a,r1movc a,@a+dptrcall rwram2inc r1cjne a,#00h,a1retrwram2:mov p0,asetb rsclr rwclr ecall delaysetb eret;*************************************************;延时子程序;*************************************************DELAY:MOV R6,#250;延时500usDJNZ R6,$RETDELAY1:MOV R7,#20HDJNZ R7,$RETdisptab:db 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H;字形代码表 ;0 1 2 3 4 5 6 7 8 9yjtab: db 'HTTP// ',00hyjtab1:db 'CHENZHOU_TE:**`C',00hASCII: DB 30H,31H,32H,33H,34H,35H,36H,37H,38H,39Hend。
ds18b20温度计程序
ORG 0000HAJMP MAINORG 0030HMAIN: MOV R5,#0FFHMAIN1:MOV P0,#00H ;系统自检。
自高位向低位带小数点显示8扫描256次CLR P2.4LCALL DELAYSETB P2.4CLR P2.5LCALL DELAYSETB P2.5CLR P2.6LCALL DELAYSETB P2.6CLR P2.7LCALL DELAYSETB P2.7DJNZ R5,MAIN1SETB P2.4 ;关显示SETB P2.5SETB P2.6SETB P2.7SJMP MAIN2DELAY:MOV R7 ,#05H //;延时LP8: MOV R6,#19HLP7:DJNZ R6,LP7DJNZ R7,LP8RET; DS18B20初始化汇编程序;*****************************************//MAIN2:LCALL DISP //;主程序SETB P3.2 // ;18B20DQ置1拉高LCALL INIT // ;调初始化MOV A,#0CCH //;跳过ROM匹配------0CCLCALL WRITE // ;调写DS18B20的程序MOV A,#44H // ;发出温度转换命令LCALL WRITE // ;调写DS18B20的程序MOV R6,#34H //;延时136微秒转换时间,写一个字约需70微秒。
DJNZ R6,$LCALL DISPLCALL INITMOV A,#0CCHLCALL WRITEMOV A,#0BEH // ;发出读温度命令LCALL WRITELCALL READCLR CLCALL CONVTEMPLCALL DISPBCDLCALL DISPSJMP MAIN2WRITE:MOV R0,#8 // ;写子程序CLR CWR1: CLR P3.2MOV 20H,#3 // ;延时17微秒DJNZ 20H,$RRC AMOV P3.2,CMOV 21H,#10 // ;发送后延时45微秒DJNZ 21H,$SETB P3.2NOPDJNZ R0,WR1 // ;8位未发送完转SETB P3.2RETREAD: MOV R6,#2 // ;读子程序CLR PSW.5 // ;清清标志F0RE0:MOV R2,#8RE1:CLR CSETB P3.2 // ;拉高DQNOP // ;延时2微秒CLR P3.2 // ;拉低DQSETB P3.2MOV 22H,#3RE2:DJNZ 22H,RE2MOV C,P3.2MOV 23H,#10RE3:DJNZ 23H,RE3RRC ADJNZ R2,RE1 //;8位未读完继续读CPL PSW.5JNB PSW.5,RE4 // ;高8位保存至28HMOV 29H,A // ;低8位及小数保存至29HRE4:MOV 28H,ADJNZ R6,RE0 //;高8位未读继续RETINIT:SETB P3.2 // ;初始化开始DQ置1(整个时隙和理论值不是很准确)NOP //;延时L0:CLR P3.2 // ;DQ拉低MOV 24H,#100 // ;延时400微秒DJNZ 24H,$SETB P3.2 // ;DQ拉高MOV 25H,#10 // ;置40微秒延时常数L01:JNB P3.2,L2 // ;有18B20响应转L2DJNZ 25H,L01 // ;无18B20响应等待40微秒SJMP L0 // ;无18B20重新初始化L2:MOV R7,#60 // ,延时240微秒L3:DJNZ R7,L3SETB P3.2 //;DQ拉高、退出RETCONVTEMP:MOV A,28H //;温度转换ANL A,#80H //;温度正负判别JZ TEMPC1 //;温度为正转CLR C // ;温度为负调整MOV A,29HCPL AADD A,#01HMOV 29H,AMOV A,28HCPL AADDC A,#00HMOV 28H,AMOV 26H,#0BH // ;温度为负26H内送#0BHSJMP TEMPC11TEMPC1:MOV 26H,#0AH //;温度为正26H内送#0AHTEMPC11:MOV A,26HSWAP AMOV 26H,A // ;26H高4位为温度符号MOV A,29H // ;取温度小数部分ANL A,#0FH ;去整数个位MOV DPTR,#DOTTABMOVC A,@A+DPTRMOV 27H,A // ;查表得小数值,并保存至27H单元MOV A,29H // ;温度整数部分拼装后暂时存入AANL A,#0F0H // ;留下整数个位SWAP AMOV 29H,AMOV A,28HANL A,#0FHSWAP AHEX2BCD1:MOV B,#64H // ;温度整数部分除100得整数百位,并存入R7中DIV ABMOV R7,A // ;R7中为百位,B中为十位和个位MOV A,#0AH // ;温度整数部分除10得整数十位和个位XCH A,B // ;除数与被除数交换DIV ABSWAP AORL A,BTEMPC10:MOV 29H,A // ;温度十位和个位存入29H单元中,十位在高4位,个位在低4位ANL A,#0F0H // ;取温度十位SWAP AORL A,26H //;十位加温度符号存入26H单元;高4位为符号MOV 26H,AMOV A,29HANL A,#0FH // ;取温度个位SWAP AORL A,27HMOV 27H,A // ;27H单元中高4位为个位,低4位为小数MOV A,R7JZ TEMPC12 // ;百位为0退出ANL A,#0FH // ;百位不为0即温度为正和十位重新拼装后存入26H,高4位为百位SWAP A // ;MOV R7,AMOV A,26HANL A,#0FH ; // ;去除26H单元的符号ORL A,R7 //;百位和十位拼装,放入26H单元高4位为百位MOV 26H,A // ;低4位为十位TEMPC12:RETDOTTAB:DB 00H,01H,01H,02H,03HDB 03H,04H,04H,05H,06HDB 06H,07H,08H,08H,09H,09HDISPBCD:MOV A,27H // ;BCD码转换ANL A,#0FHMOV 70H,A // ;取小数,并保存在70H中SWAP AANL A,#0FHMOV 71H,A // ;取整数个位,并保存在71H中MOV A,26HANL A,#0FHMOV 72H,A //;取整数十位,并保存在72H中MOV A,26HSWAP AANL A,#0FHMOV 73H,A // ;取整数百位,并保存在73H中MOV A,72H //;取整数十位ANL A,#0F0HCJNE A,#00H,DISPBCD2SJMP DISPBCD2DISPBCD0:MOV A,26H // ;取整数百位ANL A,#0F0HCJNE A,#00H,DISPBCD2 //;百位不等于0退出MOV A,26HSW AP AANL A,#0FH //;十位保留符号MOV 73H,#0AHMOV 72H,ADISPBCD2:RETDISP:MOV R1,#70H // ;显示子程序MOV R5,#11101111B // ;送Y4位码PLAY:MOV P0,#0FFH // ;关段码MOV A,R5 // ;取Yn位码MOV P2,A // ;送位码MOV A,@R1 //;取段码MOV DPTR,#TABMOVC A,@A+DPTRMOV P0,A // ;送段码MOV A,R5JB ACC.5,LOOP1 // ;位码未指向Y2(整数个位)转CLR P0.7 ;;开小数点LOOP1:LCALL DL1MS //;调显示延时INC R1 // ;指向下一位显示段码MOV A,R5 ;取显示位码JNB ACC.7,ENDOUTRL A // ;向下一位位码MOV R5,AAJMP PLAYENDOUT:MOV P0,#0FFHMOV P3,#0FFHRETTAB: DB 0C0H,0F9H,0A4H,0B0HDB 99H,92H,82H,0F8HDB 80H,90H,0FFH,0BFHDL1MS:MOV R6,#14H // ;延时1mS DL1: MOV R7,#19HDL2: DJNZ R7,DL2DJNZ R6,DL1RETEND。
DS18B20汇编程序(完整版)
DS18B20汇编程序;实验目的:熟悉DS18B20的使用;六位数码管显示温度结果,其中整数部分2位,小数部分4位;每次按下RB0键后进行一次温度转换。
;硬件要求:把DS18B20插在18B20插座上; 拨码开关S10第1位置ON,其他位置OFF; 拨码开关S5、S6全部置ON,其他拨码开关全部置OFF;*****************以下是暂存器的定义*****************************#INCLUDE<P16F877A.INC>#DEFINE DQ PORTA,0 ;18B20数据口__CONFIG_DEBUG_OFF&_CP_ALL&_WRT_HALF&_CPD_ON&_LVP_OFF&_BODEN_OFF&_PWRTE_ON&_WDT_OFF&_HS _OSCCBLOCK 20HDQ_DELAY1DQ_DELAY2TEMPTEMP1TEMP2 ;存放采样到的温度值TEMP3COUNTCOUNT1ENDCTMR0_VALUE EQU 0AH ;寄存器初值为6,预分频比1:4,中断一次时间为4*(256-6)=1000usDQ_DELAY_VALUE1 EQU 0FAHDQ_DELAY_VALUE2 EQU 4H;**********************以下是程序的开始************************ ORG 00HNOPGOTO MAIN ;入口地址ORG 04HRETFIE ;在中断入口出放置一条中断返回指令,防止干扰产生中断TABLEADDWF PCL,1RETLW 0C0H ;0的编码(公阳极数码管)RETLW 0F9H ;1的编码RETLW 0A4H ;2的编码RETLW 0B0H ;3的编码RETLW 99H ;4的编码RETLW 92H ;5的编码RETLW 082H ;6RETLW 0F8H ;7RETLW 080H ;8RETLW 090H ;9;***************************主程序******************************* MAINCLRF PORTACLRF PORTBBANKSEL TRISACLRF TRISA ;A口所有先设置为输出CLRF TRISDMOVLW 01HMOVWF TRISB ;B0口为输入,其他为输出MOVLW 06HMOVWF ADCON1 ;关闭所有A/D口MOVLW 01HMOVWF OPTION_REG ;分频比1:4,定时器,内部时钟源BCF STATUS,RP0CLRF TEMPCLRF TEMP1CLRF TEMP2 ;清零临时寄存器MOVLW 8HMOVWF COUNTMOVLW 38HMOVWF FSRCLRF INDFINCF FSR,1DECFSZ COUNT,1GOTO $-3;****************************循环处理部分************************;先启动18B20温度转换程序,在判断温度转换是否完成(需750us);未完成则调用显示子程序,直到完成温度转换;完成后读取温度值;送LCD显示LOOPBTFSC PORTB,0 ;判断温度转换按键是否按下GOTO LOOP1 ;否,转显示CALL DELAY ;消抖BTFSC PORTB,0 ;再次判断GOTO LOOP1CALL RESET_18B20 ;调用复位18B20子程序MOVLW 0CCHMOVWF TEMPCALL WRITE_18B20 ;SKIP ROM命令MOVLW 44HMOVWF TEMPCALL WRITE_18B20 ;温度转换命令CLRF STATUSCALL DELAY_750MS ;调用温度转换所需要的750MS延时NOPCALL RESET_18B20MOVLW 0CCHMOVWF TEMPCALL WRITE_18B20 ;SKIP ROM命令MOVLW 0BEHMOVWF TEMPCALL WRITE_18B20 ;读温度命令CALL READ_18B20 ;调用读温度低字节MOVFW TEMPMOVWF TEMP1 ;保存到TEMP1CALL READ_18B20 ;调用读温度高字节MOVFW TEMPMOVWF TEMP2 ;保存到TMEP2CALL RESET_18B20LOOP1CALL TEMP_CHANGE ;调用温度转换程序CALL DISPLAY ;调用LCD显示程序GOTO LOOP ;循环工作;*********************复位DS18B20子程序************************** RESET_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;主控制器把总线拉低至少480us,;18B20等待15-60us后,把总线拉低做为返回给控制器的应答信号BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF DQMOVLW 0A0HMOVWF COUNT ;160USDECFSZ COUNT,1GOTO $-1 ;拉低480usBSF DQ ;释放总线MOVLW 14HMOVWF COUNTDECFSZ COUNT,1GOTO $-1 ;等待60usBANKSEL TRISABSF TRISA,0 ;DQ设置为输入BCF STATUS,RP0BTFSC DQ ;数据线是否为低GOTO RESET_18B20 ;否则继续复位MOVLW 4HMOVWF COUNTDECFSZ COUNT,1 ;延时一段时间后再次判断GOTO $-1BTFSC DQGOTO RESET_18B20MOVLW 4BHMOVWF COUNTDECFSZ COUNT,1GOTO $-1BANKSEL TRISABCF TRISA,0 ;DQ设置为输出BCF STATUS,RP0RETURN;*********************写DS18B20子程序**************************** WRITE_18B20;根据DATASHEET介绍,写数据时应遵照如下规定:;写数据0时,主控制器把总线拉低至少60us;写数据1时,主控制器把总线拉低,但必须在15us内释放MOVLW 8HMOVWF COUNT ;8位数据BANKSEL TRISABCF TRISA,0BCF STATUS,RP0BCF STATUS,CWRITE_18B20_1BSF DQ ;先保持DQ为高MOVLW 5HMOVWF COUNT1BCF DQ ;拉低DQ15usDECFSZ COUNT1,1GOTO $-1RRF TEMP,1BTFSS STATUS,C ;判断写的数据为0还是1GOTO WRITE_0BSF DQ ;为1,立即拉高数据线GOTO WRITE_ENDWRITE_0BCF DQ ;继续保持数据线为低WRITE_ENDMOVLW 0FHMOVWF COUNT1 ;保持45msDECFSZ COUNT1,1GOTO $-1BSF DQ ;释放总线DECFSZ COUNT,1 ;是否写完8位数据GOTO WRITE_18B20_1RETURN;**********************读DS18B20子程序**************************** READ_18B20;根据DATASHEET介绍,读数据时应遵照如下规定:;读数据0时,主控制器把总线拉低后,18B20再把总线拉低60us;读数据1时,主控制器把总线拉低后,保持总线状态不变;主控制器在数据线拉低后15us内读区数据线上的状态。
ds18b20详解及程序
d s18b20详解及程序(总1页) -CAL-FENGHAI.-(YICAI)-Company One1
-CAL-本页仅作为文档封面,使用请直接删除
最近都在学习和写单片机的程序, 今天有空又模仿DS18B20温度测量显示实验写了一个与DS18B20基于单总线通信的程序.
DS18B20 数字温度传感器(参考:智能温度传感器DS18B20的原理与应用)是DALLAS 公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。
因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计。
DS18B20 产品的特点:
(1)、只要求一个I/O 口即可实现通信。
(2)、在DS18B20 中的每个器件上都有独一无二的序列号。
(3)、实际应用中不需要外部任何元器件即可实现测温。
(4)、测量温度范围在-55 到+125℃之间; 在-10 ~ +85℃范围内误差为
±5℃;
(5)、数字温度计的分辨率用户可以从9 位到12 位选择。
将12位的温度值转换为数字量所需时间不超过750ms;(6)、内部有温度上、下限告警设置。
DS18B20引脚分布图
DS18B20 详细引脚功能描述:
1、GND 地信号;
2、DQ数据输入出引脚。
开漏单总线接口引脚。
当被用在寄生电源下,此引脚可以向器件提供电源;漏极开路, 常太下高电平. 通常要求外接一个约5kΩ的上拉电阻.
3、VDD可选择的VDD 引脚。
电压范围:3~5.5V; 当工作于寄生电源时,此引脚必须接地。
DS18B20存储器结构图
暂存储器的头两个字节为测得温度信息的低位和高位字节;。
多个DS18B20温度测量程序
#include<reg51.h>#include<intrins.h> //nop函数#include<stdlib.h>#include<math.h>#define uchar unsigned char#define uint unsigned intsbit DS18B20_DQ=P2^7;sbit feng=P2^0;sbit deng=P1^0;#define LCD_data P0 //ch375数据端口uchar count1,count2,count;sbit LCD_RS=P3^5;sbit LCD_RW=P3^6; //ch375的rw也是此口sbit LCD_EN=P3^4;#include<key_fo.h>uchar ds18b20_serial[4][8]={0x28,0x51,0x8c,0x9e,0x03,0x00,0x00,0xfd, //第1个18B20的ID0x28,0x71,0x91,0x9e,0x03,0x00,0x00,0xdb, //第2个18B20的ID0x28,0x43,0xa6,0x9a,0x03,0x00,0x00,0x83, //第3个18B20的ID0x28,0xe3,0x8a,0x9e,0x03,0x00,0x00,0x08 //第4个18B20的ID};#include<12864.h>uchar temp_num1;uchar temp_num2;uint temper=0,yushe1=325,yushe2=325,yushe3=325,yushe4=325,piancha;/****************************************************函数:void Ds18b20_Delay(uint timer)功能:STC单片机严格的us级延时函数*****************************************************/void Ds18b20_Delay(uint timer) //us{while(timer--){_nop_();_nop_();_nop_();}}/***************************************************函数:void rest()功能:DS18B20芯片复位函数说明:复位时,MCU将数据线置为低电平,并且保持480uS-960uS,然后置为高电平,延时一段时间后,然后由MCU接受DS18B20的响应信号。
基于PIC16F877的DS18B20驱动程序
{
uchar i,dat=0;
for(i=0;i<8;i++)
{
DQ=1;
NOP();
NOP();
NOP();
NOP();
NOP();
dat>>=1;
DQ=0;
DQ_IN(); //定义成输入
dec=(uchar)(templ*50/8)%10; //将小数的第二位作为整数取出(templ*6.25)%10
templ=(templ*5)/8; //温度的小数部分扩大十倍(小数部分为*0.0625)
if(dec>=5)
{
templ+=1;
}
value=value*10+templ; //整数部分扩大十倍加扩大十倍后的小数部分
delay(160);
DQ=1;
DQ_IN();
delay(16); //等待DS18B20发出低电平应答
// n=DQ; //如果在工程中,并不知道总线上有没有挂测温设备,就需要返回n进行判断,n=0表示有设备
// while(DQ);
DQ_OUT();
DQ=1; //释放数据线
delay(2);
}
/*----------------------------------------
函数名称:read_byte()
作者 : haijun_zhang
入口参数:无
出口参数:dat
功能描述:从DS18B20读一个字节的数据
------------------------------------------*/
ds18b20温度检测程序(C语言)
//18B20单线温度检测的应用样例程序#include<REG52.H>#include<math.h>#include<INTRINS.H>#include<stdio.h>#define uchar unsigned char#define uint unsigned int;/*****************************************************************************/ sbit seg1=P2^0;sbit seg2=P2^1;sbit seg3=P2^2;sbit DQ=P1^7;//ds18b20 端口sfr dataled=0x80;//显示数据端口/**********************************************************************/uchar temp;uchar flag_get,count,num,minute,second;uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//7段数码管段码表共阳uchar str[3];/***********************************************************************/void delay1(uchar MS);unsigned char ReadTemperature(void);void Init_DS18B20(void);unsigned char ReadOneChar(void);void WriteOneChar(unsigned char dat);void delay(unsigned int i);void INITchuangkou(void);//void Initdingshiqi1(void);/************************************************************************/main(){TMOD|=0x21;//定时器设置TH0=0xef;TL0=0xf0;EA=1;TR0=1;//Initdingshiqi1();INITchuangkou();P2=0x00;count=0;while(1){str[2]=0x39;//显示C符号str[0]=tab[temp/10]; //十位温度str[1]=tab[temp%10]; //个位温度if(flag_get==1) //定时读取当前温度{temp=ReadTemperature();printf("%d",temp);flag_get=0;}}}void tim(void) interrupt 1 using 1//中断,用于数码管扫描和温度检测间隔{TH0=0xef;//定时器重装值TL0=0xf0;num++;if (num==50){num=0;flag_get=1;//标志位有效second++;if(second>=60){second=0;minute++;}}count++;if(count==1){P2=0;dataled=str[0];}//数码管扫描if(count==2){P2=1;dataled=str[1];}if(count==3){ P2=2;dataled=str[2];count=0;}}/******************************************************************************void delay(unsigned int i)//延时函数{while(i--);}/****************************************************************************** *********///18b20初始化函数void Init_DS18B20(void){unsigned char x=0;DQ = 1; //DQ复位delay(8); //稍做延时DQ = 0; //单片机将DQ拉低delay(80); //精确延时大于480usDQ = 1; //拉高总线delay(10);x=DQ; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay(5);}//读一个字节unsigned char 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(5);}return(dat);}//写一个字节void WriteOneChar(unsigned char dat){unsigned char i=0;for (i=8; i>0; i--){DQ = dat&0x01;delay(5);DQ = 1;dat>>=1;}delay(5);}//读取温度unsigned char ReadTemperature(void){unsigned char a=0;unsigned char b=0;unsigned char t=0;//float tt=0;Init_DS18B20();WriteOneChar(0xCC); // 跳过读序号列号的操作WriteOneChar(0x44); // 启动温度转换delay(200);Init_DS18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度a=ReadOneChar();b=ReadOneChar();b<<=4;b+=(a&0xf0)>>4;t=b;//tt=t*0.0625;//t= tt*10+0.5; //放大10倍输出并四舍五入return(t);}void INITchuangkou(void){SCON=0X50;TH1=0XFD;TR1=1;TI=1;}/*void Initdingshiqi1(void);{TMOD=0X11;TH1=0XFD;TL1=0XFD; TR1=1;}*/。
DS18b20温度测量程序。单片机C51控制
//DS18B20的读写程序,数据脚P3.3 ////温度传感器18B20汇编程序,采用器件默认的12位转化 ////最大转化时间750微秒,显示温度-55到+125度,显示精度 ////为0.1度,显示采用4位LED共阳显示测温值 ////P0口为段码输入,P24~P27为位选 ///***************************************************/#include "reg51.h"#include "intrins.h" //_nop_();延时函数用#define Disdata P1 //段码输出口#define discan P0 //扫描口#define uchar unsigned char#define uint unsigned intsbit DQ=P3^2; //温度输入口uint h;//**************温度小数部分用查表法***********//uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09 };//uchar dd[10]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};//共阳LED段码表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-"uchar scan_con[4]={0x00,0x01,0x02,0x03}; //列扫描控制字uchar temp_data[2]={0x00,0x00}; //读出温度暂放uchar display[4]={0x00,0x00,0x00,0x00,}; //显示单元数据,共4个数据和一个运算暂用///////***********11微秒延时函数**********///void delay(uint t){for(;t>0;t--);}///***********显示扫描函数**********/scan(){uchar k;for(k=0;k<3;k++){P0=0xff;dd[k]=dd[display[k]];dd[k]=dd[k]*16;dd[k]=dd[k]|scan_con[k];P0=dd[k];delay(90);P0=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); // 发转换命令}/***********温度数据处理函数**********/void work_temp(){display[3]=temp_data[0]&0x0f;display[0]=ditab[display[3]]; //小数部分display[3]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x07)<<4); display[2]=display[3]/10%10;display[1]=display[3]%10;}/////**************主函数****************/main(){Disdata=0xff; //初始化端口discan=0xff;ow_reset(); // 开机先转换一次write_byte(0xCC); // Skip ROMwrite_byte(0x44); // 发转换命令for(h=0;h<500;h++){scan();} //开机显示"0000"2秒while(1){read_temp(); //读出18B20温度数据work_temp(); //处理温度数据scan(); //显示温度值2秒}}////*********************结束**************************//。
PIC16F877A例程---DS18B20
#include <pic.h>#include <pic1687x.h>__CONFIG(0x3F32); //芯片配置字#define LCDRS RB2#define LCDRW RB1#define LCDE RB0#define LCDDA TA PORTD#define DS18B20 RE0#define TRIS_B20 TRISE0void LCD1602_INIT(void);void WRITE_LCD_CMD (char cmd);void WRITE_LCD_DA TA (char data);void LCD_Display(char *s);void LCD_Display_location (char line, char col);void LCD1602_BUSY();void US_delay ( int t);void itoa10(unsigned char *buf, int i);int strlen (const char *s);void DS18B20_INIT();void WRITE_DS18B20_CMD(char cmd);float READ_DS18B20 ();char bank1 DA T_BUFF1[]= "Temperature:";char Found_DS18B20[]="DS1820 FOUND";char DS18B20_NOT_Found[]="DS1820 NOT FOUND"; char bank1 DA T_BUFF2[]= " ";#define CLRLCD 0X01 //清屏命令#define LCDMOD 0X38 //8位,两行,5*7点#define TURNON 0X0F //#define CURMODE 0X06 //#define ORG1 0X80 //LCD 第一行首地址#define ORG2 0XC0 //LCD 第二行首地址#define SKIPROM 0XCC#define READSCRACHPAD 0XBE#define TCONVERT 0X44#define DS18b20_RESET 10#define DSRECOVER 1float temperature;char bank1 atemperature[10]; // used for store ascii code of digital temperature */void main(){int len;ADCON1=0X07;LCD1602_INIT();LCD_Display(DA T_BUFF1);LCDE=0;LCD_Display_location (1,0);while (1){DS18B20_INIT();WRITE_DS18B20_CMD(SKIPROM);WRITE_DS18B20_CMD(TCONVERT);TRIS_B20=0;DS18B20=0;TRIS_B20=1;while(1){ //判断转换是否完成if (DS18B20) break;else continue;}DS18B20_INIT();WRITE_DS18B20_CMD(SKIPROM);WRITE_DS18B20_CMD(READSCRACHPAD);temperature=READ_DS18B20();itoa10(atemperature, (int) (temperature * 10));// so use temperature * 10 to enlarge the temperature len=strlen(atemperature);atemperature[len]=atemperature[len-1];atemperature[len-1]='.';atemperature[len+1]=0;LCD_Display_location (0,0);LCD_Display (DA T_BUFF1); //LCD第一行显示Tempereture: 字符LCD_Display_location (1,0);LCD_Display (DA T_BUFF2);LCD_Display_location (1,2);LCD_Display (atemperature); //LCD第二行显示当前温度值LCD_Display (DA T_BUFF2);US_delay(5000); //每隔0.5秒读取一次温度值}}int strlen(const char * s){const char *cp;cp = s;while(*cp++)continue;return cp-s-1;}void LCD_Display(char *s){int len;int atmp;len=strlen(s);for (atmp=0; atmp<len; atmp++)WRITE_LCD_DA TA(s[atmp]);}void LCD1602_BUSY(){// char tmpbusy;TRISB &= 0xF8;TRISD=0XFF;LCDRS=0;LCDRW=1;LCDE=1;while(LCDDA TA & 0X80);}void LCD_Display_location (char line, char col){char pos;LCD1602_BUSY();pos = line * 0X40 + 0X80 + col;WRITE_LCD_CMD(pos);}void WRITE_LCD_DA TA(char data) {LCD1602_BUSY();TRISB & =0XF8;TRISD=0;LCDDA TA=data;LCDRS=1;LCDRW=0;LCDE=0;asm("NOP");asm("NOP");LCDE=1;}void WRITE_LCD_CMD(char cmd) {LCD1602_BUSY();TRISB & =0XF8;TRISD=0;LCDDA TA=cmd;LCDRS=0;LCDRW=0;LCDE=0;asm("NOP");asm("NOP");LCDE=1;}void LCD1602_INIT(void){LCD1602_BUSY();TRISB &= 0XF8;TRISD=0;WRITE_LCD_CMD(CLRLCD);WRITE_LCD_CMD(LCDMOD);WRITE_LCD_CMD(TURNON);WRITE_LCD_CMD(CURMODE);LCD_Display_location (0,0);}void DS18B20_INIT(){TRIS_B20=0;DS18B20=0;US_delay(20);TRIS_B20=1;US_delay(10);}void WRITE_DS18B20_CMD(char cmd) {char tmp;char i;TRIS_B20=0;for(tmp=8;tmp>0;tmp--){TRIS_B20=0;DS18B20= 0;asm ("NOP");asm ("NOP");asm ("NOP");asm ("NOP");asm ("NOP");if (cmd & 0x01){TRIS_B20=1;US_delay(1);for (i=5;i>0;i--);}else{DS18B20=0 ;US_delay(1);for (i=5;i>0;i--);TRIS_B20=1;}cmd=cmd/2;}}float READ_DS18B20 (){char tmp=0x01;float t;union{char c[2];int x;}temp;temp.x=0;while (tmp){ // read first 8 bitsTRIS_B20=0;DS18B20=0;asm("NOP");TRIS_B20=1;if (DS18B20)temp.c[0] |= tmp;tmp=tmp<<1;US_delay(2);}tmp=1;while (tmp){ // read first 8 bitsTRIS_B20=0;DS18B20=0;asm("NOP");TRIS_B20=1; // release the busasm("NOP");if (DS18B20) // "1" presentedtemp.c[1] |= tmp;tmp=tmp<<1;US_delay(2);}t=((float) temp.x)/16.0 ;return t;}void itoa10(unsigned char *buf, int i){unsigned int rem;unsigned char *s,length=0;s = buf;if (i == 0)*s++ = '0';else{if (i < 0){*buf++ = '-';s = buf;i = -i;}while (i){++length;rem = i % 10;*s++ = rem + '0';i /= 10;}for(rem=0; ((unsigned char)rem)<length/2; rem++){*(buf+length) = *(buf+((unsigned char)rem));*(buf+((unsigned char)rem)) = *(buf+(length-((unsigned char)rem)-1));*(buf+(length-((unsigned char)rem)-1)) = *(buf+length);}}*s=0;}void US_delay( int i){unsigned char j;while(i--){j=3;while(j--);}}。
温度传感器ds18b20检测程序说明
DS18B20美国达拉斯公司生产的单总线协议的数字温度检测芯片,数据的写入与读取都在一根总线上进行操作,在总线上可以连接多个DS18B20,因为每个DS18B20都有唯一的光刻ROM序列号,所以可以进行ROM匹配,搜索指令进行选择相应的从机序列号。
编写DS18B20的检测程序主要包括:初始化函数(复位脉冲+存在脉冲),写数据函数,读取数据的函数。
对DS18B20的操作包括:初始化函数,ROM指令,RAM指令这三个部分。
接下来我先说一下这三个部分所对应的时序图的理解吧。
初始化:由于上拉电阻的存在,总线默认状态是高电平,接着主机将总线拉低,维持480us 到960us的时间,再接着就是释放总线,维持时间为15us到60us,接着就由从机发出一个低电平信号,将总线拉低,表示该DS18B20是正常地,或者说是存在的,其维持时间为60us 到240us。
上面一图是写入数据的时序图。
写时序:默认状态为高电平,先将总线拉低,至少维持1us 的延时时间,接着就往总线上进行写数据操作,接着DS18B20就开始采样数据了,整个过程时间为60us到120us。
下面一图是读取数据的时序图。
读时序:默认状态为高电平,先将总线拉低,接着在15us 之前,主机进行数据采样,其维持时间也为60us到120us。
下面是我在理解了DS18B20的原理之后所写的程序,调试成功了,且能实时读取外界温度的功能,这里是不读取小数部分的温度,只读取温度的正数值。
#include<reg52.h>#define uint unsigned int#define uchar unsigned charuchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};sbit DQ=P2^2;sbit duan=P2^6;sbit wei=P2^7;//是在11.0592M赫兹的频率下void delay_ms(uint t){uint i;for(;t>0;t--)for(i=110;i>0;i--);} //约为tms的延时程序void delay(uint x){while(x--);}void init_ds18b20(){uchar n;DQ=1;delay(2); //约为38usDQ=0;delay(80); //约为800usDQ=1;delay(4); //约为58usn=DQ;delay(10); //约为110us}void write_byte(uchar dat){uchar i;for(i=0;i<8;i++){DQ=0; //无论是写0或写1都要有至少1us的低电平DQ=dat&0x01;//总线直接等于写入的数据(低位在前,高位在后)delay(4); //约为58usDQ=1; //释放总线,为下一步的数据变换做准备dat>>=1;//数据进行移位操作}delay(4);}uchar read_byte(){uchar i,value;for(i=0;i<8;i++){DQ=0;value>>=1; //移位7次DQ=1; //先要释放总线,那样才能采样到有效数据if(DQ) //判断8次{value|=0x80;}delay(6); //约为78us}return value;}uchar read_temperature(){uchar a,b;init_ds18b20(); //每次操作指令前,都必须进行初始化设置write_byte(0xcc);//跳过ROM指令write_byte(0x44);//进行温度转换处理delay(300);//进行一定地延时约为3ms左右init_ds18b20();write_byte(0xcc);//跳过ROM操作write_byte(0xbe);//读取温度a=read_byte();//温度低字节b=read_byte();//温度高字节b<<=4;//b左移四位,低四位为0000b=b+(a&0xf0)>>4;//将a的低四位屏蔽,不取小数点,进行右移四位,合并成一个字节的数据return b;}void display(uchar aa,uchar bb) {duan=1;P0=table[aa];duan=0;P0=0xff;wei=1;P0=0xfe;wei=0;delay_ms(5);duan=1;P0=table[bb];duan=0;P0=0xff;wei=1;P0=0xfd;wei=0;delay_ms(5);}void main(){uchar num,shi,ge;while(1){num=read_temperature();shi=num/10; //分离出十位ge=num%10; //分离出个位display(shi,ge);}}。
基于PIC16F877芯片的DS18B20测温系统设计
万方数据万方数据万方数据基于PIC16F877芯片的DS18B20测温系统设计作者:李永茂, LI Yongmao作者单位:常州机电职业技术学院电气工程系,江苏省常州市,213164刊名:信息化研究英文刊名:INFORMATIZATION RESEARCH年,卷(期):2010,36(8)被引用次数:0次1.Dallas Semiconductor Corporation DS18B20 Programmable Resolution 1-Wire Digital Thermometer 20022.廖琪梅.韩彬.杨文昭.屈景辉基于单总线器件DS18B20的温度测量仪 2008(2)3.刘静波基于AT89C2051的温度测控系统设计与分析 2008(1)4.丁晓进.史小军.朱为.堵国梁基于DS18B20的多点温度检测 2006(7)5.李学海PIC单片机实用教程 20076.陈新建PIC系列单片机程序设计与开发应用 20071.期刊论文常国锐基于PIC16F877单片机的温控系统设计研究-现代商贸工业2009,21(6)以PIC单片机为核心控制DS18B20温度传感器等外围电路模块实现了对多路温度的实时监测.论述了系统设计思路和软件设计流程.系统具有温度监测、自动拨号、语音报警功能,有较强的实用价值.2.会议论文Xin-Hua MAO.Ting-ting Huang The Design of check and control system for temperature based on the wireless communications of ZigBee2009There are several problems that high cost of chips, slow transmission distance speed in radio measuring and controlling system in corrals, this paper present the design of check and control system for temperature based on the wireless communications of ZigBee. The host controller of this system is PIC16F877 single-chip computer, and the data acquisition device is DS18B20.The system not only can realize the real time way of monitoring and controlling in corrals,but also has features such as wide monitoring range, low cost, low loss of power, many network nodes and long transmitting distance.The environment of corrals is controlled in the most suitable area for livestock growth, which favores the yield increase, raise the economic benefit.3.学位论文崔坤征未知动态环境中移动机器人的路径规划及避障研究2005移动机器人作为机器人技术的一个重要分支,近年来得到了飞速的发展,应用领域越来越广,机器人的工作环境也变得越来越复杂,动态未知环境下移动机器人的路径规划和避障是现今研究的一个热点也是难点。
DS18B20温度计完整单片机程序(汇编语言)
end
sjmp dis1
dis :
movc a,@a+dptr
CLR P2.2
clr P2.1 ;低位灭
mov p0,a
call delay3
dis1:
mov a,b
movc a,@a+dptr
setb P2.2
clr P2.1 ;高位灭
mov p0,a
call delay3
djnz r1,write_bit
ret
;*****************************************
;读一个字节(内容放在在A中)
read_byte:
mov r2,#8
read_bit:
clr p1.7
nop
nop
nop
nop
setb p1.7 ;释放总线的目的是为了读18b20发出的数据,低电平是不能读的。
sjmp f1
f:clr 20h.0 ;初始化失败置0
f1:
ret
;*****************************************
;写一个字节(内容在A中)
write_byte:
mov r1,#8
;写一位
write_bit:
rrc a ;先写低位
clr 20h.0
mov a, #0cch ;跳过序列号
call write_byte
mov a,#0BEH ;送入读内部ram命令
call write_byte
call read_byte
mov r6,a
call read_byte
郭天祥讲解的DS18B20测温度的程序
郭天祥讲解的DS18B20测温度的程序#include#include#define uchar unsigned char#define uint unsigned intsbit ds=P2^2; //温度传感器信号线sbit dula=P2^6; //数码管段选线sbit wela=P2^7; //数码管位选线sbit beep=P2^3; //蜂鸣器uint temp;float f_temp;uint warn_l1=260;uint warn_l2=250;uint warn_h1=300;uint warn_h2=320;sbit led0=P1^0;sbit led1=P1^1;sbit led2=P1^2;sbit led3=P1^3;unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //不带⼩数点的编码void delay(uint z)//延时函数{uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void dsreset(void) //18B20复位,初始化函数{uint i;ds=0;i=103;while(i>0)i--;ds=1;while(i>0)i--;}bit tempreadbit(void) //读1位函数{uint i;bit dat;ds=0;i++; //i++ 起延时作⽤ds=1;i++;i++;dat=ds;i=8;while(i>0)i--;return (dat);}uchar tempread(void) //读1个字节{uchar i,j,dat;dat=0;for(i=1;i<=8;i++){j=tempreadbit();dat=(j<<7)|(dat>>1); //读出的数据最低位在最前⾯,这样刚好⼀个字节在DA T⾥} return(dat);}void tempwritebyte(uchar dat) //向18B20写⼀个字节数据{uint i;uchar j;bit testb;for(j=1;j<=8;j++){testb=dat&0x01;dat=dat>>1;if(testb) //写1{ds=0;i++;i++;ds=1;i=8;while(i>0)i--;}elseds=0; //写0i=8;while(i>0)i--;ds=1;i++;i++;}}}void tempchange(void) //DS18B20 开始获取温度并转换{dsreset();delay(1);tempwritebyte(0xcc); // 写跳过读ROM指令tempwritebyte(0x44); // 写温度转换指令}uint get_temp() //读取寄存器中存储的温度数据{uchar a,b;dsreset();delay(1);tempwritebyte(0xcc);tempwritebyte(0xbe);a=tempread(); //读低8位b=tempread(); //读⾼8位temp=b;temp<<=8; //两个字节组合为1个字temp=temp|a;f_temp=temp*0.0625; //温度在寄存器中为12位分辨率位0.0625°temp=f_temp*10+0.5; //乘以10表⽰⼩数点后⾯只取1位,加0.5是四舍五⼊f_temp=f_temp+0.05; return temp; //temp是整型////////////////////显⽰程序//////////////////////////void display(uchar num,uchar dat){uchar i;dula=0;P0=table[dat];dula=1;dula=0;wela=0;i=0XFF;i=i&(~((0X01)<<(num)));P0=i;wela=1;wela=0;delay(1);}void dis_temp(uint t){uchar i;i=t/100;display(0,i);i=t%100/10;display(1,i+10);i=t%100%10;display(2,i);}//////////////////////////////////////////////void warn(uint s,uchar led) //蜂鸣器报警声⾳,s控制⾳调{ uchar i;i=s;dula=0;wela=0;beep=0;P1=~(led);while(i--)dis_temp(get_temp());}beep=1;P1=0XFF;i=s;while(i--){dis_temp(get_temp());}}void deal(uint t){uchar i;if((t>warn_l2)&&(t<=warn_l1)) //⼤于25度⼩于27度{warn(40,0x01);}else if(t<=warn_l2) //⼩于25度{warn(10,0x03);}else if((t=warn_h1)) //⼩于32度⼤于30度{warn(40,0x04);}else if(t>=warn_h2) //⼤于32度{warn(10,0x0c);}else{i=40;while(i--){dis_temp(get_temp());}}}void init_com(void){TMOD = 0x20;PCON = 0x00;SCON = 0x50;TH1 = 0xFd;TL1 = 0xFd;TR1 = 1;}void comm(char *parr){do{SBUF = *parr++;//发送数据while(!TI); //等待发送完成标志为1TI =0; //标志清零}while(*parr); //保持循环直到字符为'\0' }void main(){uchar buff[4],i;dula=0;wela=0;init_com();while(1){tempchange();for(i=10;i>0;i--){dis_temp(get_temp());}deal(temp);sprintf(buff,"%f",f_temp); for(i=10;i>0;i--){dis_temp(get_temp());} comm(buff);for(i=10;i>0;i--){dis_temp(get_temp());} }}。
DS18B20温度测试程序(51单片机数码管显示)+电路图
DS18B20温度测试程序(51单片机数码管显示)+电路图•下面是电路图采用4位数码管显示程序一共有2个文件:/****************************************************************************** *****************************************ds18b20.h 头文件******************************************************************************* ****************************************/#ifndef _DS18B20_H_#define _DS18B20_H_#include <reg51.h>#define led P1#define ledw P2extern unsigned char f;extern void ds18b20_reset();extern void dela(unsigned char i);extern void ds18b20_write(unsigned char dat);extern unsigned char ds18b20_read();extern unsigned char ds18b20_temp();extern unsigned char ledtab[];#endif/****************************************************************************** **************************************ds18b20.c 文件******************************************************************************* *************************************/#include"ds18b20.h"#define uchar unsigned char#define uint unsigned int#define led P1#define ledw P2uchar ledtab[]={0xc0,0xf9,0xa4, 0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};sbit dq=P3^7 ;uchar delay,f;//uchar f;void dela(uchar i) //5us t=5+i*2{while(--i);}void ds18b20_reset(){while(1){dq=1;dq=0;delay=250; //540us延时,当delay=1时延时为2us ,T=2*xwhile(--delay);dq=1;delay=25;while(--delay);while(dq==0){delay=220;while(--delay);if(dq==1)break;}delay=150;while(--delay);break;}}void ds18b20_write(uchar dat) {uchar i=0;for(i=0;i<8;i++){dq=1;dq=0;delay=3;while(--delay);dq=dat&0x01;delay=35;while(--delay);dq=1;dat=dat>>1;}}uchar ds18b20_read(){uchar i=0,m=0;for(i=0;i<8;i++){//m>>=1dq=1;dq=0;delay=4;while(--delay);dq=1;delay=4;while(--delay);if(dq==1)m|=0x01<<i;//m=m|0x80;delay=25;while(--delay);dq=1;delay=1;while(--delay);}return m;}uchar ds18b20_temp(){uchar temp=0,temph=0,templ=0,k=0; ds18b20_reset();ds18b20_write(0xcc);ds18b20_write(0x44);ds18b20_reset();ds18b20_write(0xcc);ds18b20_write(0xbe);templ=ds18b20_read();temph=ds18b20_read();if((temph&0xf80)!=0){f=1;templ=~templ;temph=~temph;k=templ+1;templ=k;if(templ>0xff){temph++;}}elsef=0;templ=templ>>4;temph=temph<<4;temp=templ|temph;return temp;}/****************************************************************************** ************************************main.c 主文件******************************************************************************* ************************************/#include<reg51.h>#include"ds18b20.h"#define uchar unsigned charvoid main(){uchar a=0,b=0,c=0,temp=0;while(1){temp=ds18b20_temp();a=temp/100;b=temp0/10;c=temp;if(f==1){led=0xbf;ledw=1;dela(5000);ledw=0;dela(600);}led=ledtab[c]; ledw=8;dela(5000); ledw=0;dela(600) ;led=ledtab[b]; ledw=4;dela(5000); ledw=0;dela(600) ;led=ledtab[a]; ledw=2;dela(5000);ledw=0;dela(600) ; }}。
DS18B20测温程序
//温度高于26摄氏度则蜂鸣器响#include<reg52.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charsbitdula=P2^6;sbitwela=P2^7;sbit beer=P2^3; //控制蜂鸣器sbitdsb=P2^2; //ds18b20的数据总线sbitrs=P3^5; //液晶显示数据命令选择端口sbitlcme=P3^4; //液晶显示使能信号sbit key=P3^7;uint temp; //温度传感器测得的温度uchar code listone[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};ucharcodelisttwo[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; ucharcodelistthree[]={"The temp is under:"};void delay(uchari){while(--i);}Voiddelayone(uint z){uintx,y;for(x=100;x>0;x--)for(y=z;y>0;y--);}/*液晶显示写命令初始化*/ Voidwritecom(uchar com) {rs=0;delayone(2);lcme=0;P0=com;lcme=1;delayone(2);lcme=0;}/*液晶显示写数据初始化*/ void writebyte(uchar byte) {rs=1;delayone(2);lcme=0;P0=byte;lcme=1;delayone(2);lcme=0;}/*液晶显示初始化*/ void ds18b20init() {uinttempone;uinti;dula=0;wela=0;lcme=0;writecom(0x38);writecom(0x0f);writecom(0x06);writecom(0x80);for(i=0;i<16;i++){writebyte(listthree[i]);delayone(2);}writecom(0x80+0x40);for(i=0;i<16;i++){tempone=temp&0x80;writebyte(tempone);delay(2);temp<<=1;}writecom(0x0c);}/*温度传感器初始化*/ voidtempinit(){dsb=1;delay(1);dsb=0;delay(250);dsb=1;delay(100);}voidwritedata(uchardat) {uinti;for(i=0;i<8;i++){dsb=1;_nop_();dsb=0;_nop_();_nop_();dsb=dat&0x01;delay(10);dat>>=1;delay(1);}dsb=1;}ucharreaddata(){uinti;for(i=0;i<8;i++){dsb=1;_nop_();dsb=0;_nop_();_nop_();// date>>=1;dsb=1;delay(1);date>>=1; //右移放于此处也可以if(dsb==1)date|=0x80;delay(10);}return date;}uint control(){floattt;// uint temp;tempinit();writedata(0xcc);writedata(0x44);tempinit();writedata(0xcc);writedata(0xbe);a =readdata();b = readdata();temp = b;temp<<= 8;temp = temp|a;tt = temp*0.0625;temp = tt*100+0.05;return temp;}voidshuma(uint temp) {ucharbai,shi,ge,xiaoshu; bai=(temp/1000);shi=temp%1000/100; ge=temp%100/10; xiaoshu=temp%10;dula=1;P0=listone[bai];dula=0;P0=0xff;wela=1;P0=0xfe;wela=0;delayone(1);dula=1;P0=listtwo[shi];dula=0;P0=0xff;wela=1;P0=0xfd;wela=0;delayone(1);dula=1;P0=listone[ge];dula=0;P0=0xff;wela=1;P0=0xfb;wela=0;delayone(1);dula=1;P0=listone[xiaoshu];dula=0;P0=0xff;wela=1;P0=0xf7;wela=0;delay(10);}void warning(uint temp){if((temp>=2600)&&(temp<2800)&&(key==1)){beer=0;P1=0x55;delayone(4);}if((key==0)||(temp<2600)){delayone(5);if((key==0)||(temp<2600)){beer=1;P1=0xff;}}}void main(){while(1){if(temp<2600){shuma(control());}if((temp>=2600)&&(temp<2800)){shuma(control());warning(temp);}if(temp>=2800){dula=0;wela=0;P0=0xff;}}}。
基于PIC16F877单片机与DS18B20的温度采集与显示
河北联合大学轻工学院QINGGONG COLLEGE, HEBEI UNITED UNIVERSITY 《PIC单片机课程设计》学生姓名:肖晓峰学号:201124520121学部:信息科学技术部专业班级:电信1指导教师:曹义2014年7 月 4 日本课程设计是在《PIC单片机原理及应用》及《单片机C语言编程》课程的基础上,通过硬件设计、软件编程及仿真调试的实践,进一步掌握PIC单片机的应用方法,熟练掌握PICC C语言程序的编写与调试,是毕业设计前的一次重要实践,为今后走上工作岗位打下坚实的单片机应用基础。
2.1 设计题目:基于PIC16F877单片机与DS18B20的温度采集与显示2.2 功能实现:实时温度显示,并具有超限报警功能。
输出显示采用LCD1602。
2.3 设计要求:自己设计硬件和程序编程,画出完整的电路原理图,用Multisim或Proteus 仿真,最终可实现脱机运行。
三、设计原理说明3.2 显示模块如用LCD1602作为显示设备,要求显示屏分两行显示,第一行显示日期(年-月-日)和星期,第二行显示时间(时:分:秒)和温度。
显示秒由00一直加到59,分钟数也由00加到59,小时采用24小时制,由00加到23,如此循环显示。
3.3 按键模块按键用来作为时间调整。
要求至少设计4个按键,按键1作为设置键;按键2、按键3分别为增加、减少键,在设置键按下时,此两个按键方有效;按键4是确定键,在设置键按下时方才有效。
3.4 温度采集模块DS18B20是美国DALLAS公司推出的单总线数字温度传感器。
DS18B20内部集成了温敏元件、数据转换芯片、存储器芯片和计算机接口芯片等多功能模块。
其主要技术特点有:具有独特的单线接口方式;可以通过数据线供电,具有超低功耗工作方式;测温范围为-55℃~125℃,测温精度为0.5℃;温度转换精度9~12位可编程,直接将温度转换值以二进制数码的方式串行输出。
四、硬件原理图(含原理图、电路仿真图)图2电路仿真图五、软件设计(含流程图、带注释的程序清单)程序设计流程图主文件he//**********************************************/#include<pic.h>__CONFIG(0x3B31);//芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡//宏定义#define DQ RC1 //温度数据口#define DQ_HIGH() TRISC1=1#define DQ_LOW() TRISC1=0;DQ=0#define uchar unsigned char#define uint unsigned int#define RS RA0 //LCD功能选择位#define RW RA1 //读写选择#define EN RA2 //使能//变量定义int temper;char f = 0 ;uchar a1,a2,a3,a4;uchar Prompt[]="P1ress K1 - K3 To Start Demo Prog";//各种申明void init();void DelayMS(uint ms);uchar Busy_Check();void Write_LCD_Command(uchar cmd);void Write_LCD_Data(uchar dat);void Initialize_LCD();void ShowString(uchar x,uchar y,uchar *str);void Showword0(uchar x,uchar y,char word );void Showword1(char word );void write_shuzi(uchar num1,uchar num2,uchar num3,uchar num4);//18b20void delay(uint x);void delayus(uint,uchar);void init();void write_byte(uchar date);uchar read_byte();void get_tem();//***子函数****************************************///系统初始化函数void init(){ADCON1=0X07; //设置A口为普通数字口TRISA =0X00; //设置A口方向为输出TRISB =0x00;OPTION=0x00; //B口电阻上拉TRISC = 1;PORTC = 0x20;TRISD =0X00;TRISD =0x00;}//延时函数void delayus(uint x,uchar y){uint i;uchar j;for(i=x;i>0;i--);for(j=y;j>0;j--);}void delay(uint x){uint a,b;for(a=x;a>0;a--)for(b=110;b>0;b--);}//ds18b20复位函数void reset(){uchar st=1;DQ_HIGH(); //开始于高电平NOP();NOP(); //延时2uswhile(st){DQ_LOW();delayus(70,30); //750DQ_HIGH(); //释放总线delayus(4,4); //等70if(DQ==1) //应答判断st=1;elsest=0;delayus(50,10); //延时450}}//ds18b20写函数void write_byte(uchar date){uchar i,temp;DQ_HIGH(); //开始于高电平NOP();NOP();for(i=8;i>0;i--){temp=date&0x01;//01010101 //分位写入DQ_LOW();delayus(0,0); //15if(temp==1)DQ_HIGH();delayus(2,2); //45DQ_HIGH();date=date>>1;//00101010}}//ds18b20读函数uchar read_byte(){uchar i,date;static bit j;for(i=8;i>0;i--){date=date>>1;DQ_HIGH(); //开始于高电平NOP();NOP();DQ_LOW();NOP();NOP();NOP();NOP();NOP();NOP(); //6DQ_HIGH();NOP();NOP();NOP();NOP(); //4j=DQ; //读取总线if(j==1)date=date|0x80;//1000 0000delayus(1,1); //30 }return (date); //返回函数值}//温度读取处理函数void get_tem(){uchar tem1,tem2,num;float aaa;reset(); //复位write_byte(0xCC);//跳过ROMwrite_byte(0x44);//温度转换reset();write_byte(0xCC); //跳过ROMwrite_byte(0xBE); //温度传递tem1=read_byte(); //读取低8位tem2=read_byte();//读取高8位if(tem2>7) //符号判断{tem2=255-tem2;tem1=255-tem1;f=1;}else {f=0;}aaa=(tem2*256+tem1)*6.25*8; //转化为实际温度值temper=(int)aaa; //强行转化位整数a1=temper/1000; //十进制分位a2=temper%1000/100;a3=temper%100/10;a4=temper%10;if(a1>7||a1<5) RD7=1;else RD7=0;}//延时void DelayMS(uint ms) //毫秒{uchar i;while(ms--) for(i=0;i<120;i++);}//LCD忙检查函数uchar Busy_Check(){uchar LCD_Status;RS=0; //寄存器选择(0指令1数据)RW=1; //读状态寄存器EN=1; //开始读DelayMS(1);LCD_Status=PORTB;EN=0;return LCD_Status;}//写LCD命令函数void Write_LCD_Command(uchar cmd){// while((Busy_Check()&0x80)==0x80); //忙等待RS=0; //选择命令寄存器RW=0; //写EN=0;PORTB=cmd;EN=1;DelayMS(1);EN=0;}//LCD发送数据函数void Write_LCD_Data(uchar dat){// while((Busy_Check()&0x80)==0x80); //忙等待RS=1;RW=0;EN=0;PORTB=dat;EN=1;DelayMS(1);EN=0;}//LCD初始化函数void Initialize_LCD(){Write_LCD_Command(0x38);DelayMS(1); //38:数据长8位,两行显示,字体5*7点阵(80)Write_LCD_Command(0x01);DelayMS(1); //清屏Write_LCD_Command(0x06);DelayMS(1); //字符进入模式:屏幕不动,字符后移Write_LCD_Command(0x0c);DelayMS(1); //显示开,光标关;0x0e 是开光标}//显示字符函数void Showword0(uchar x,uchar y,char word ) //y:行地址,x:列地址{if(y==0) Write_LCD_Command(0x80|x); //设置显示起始位置(x,0)第一行if(y==1) Write_LCD_Command(0xc0|x); // (x,1)第二行Write_LCD_Data(word+0x30); //str[i]等价于*(str+i)}//显示温度函数void write_shuzi(uchar num1,uchar num2,uchar num3,uchar num4){if(f){Showword0(0,0,-3 );} //负号Showword0(1,0,num1 ); //十位Showword0(2,0,num2 );Showword0(3,0,-2 ); //小数点Showword0(4,0,num3 );Showword0(5,0,num4 );DelayMS(5);}//主函数void main(){init(); //调用系统初始化函数Initialize_LCD(); //LCD初始化while (1){ get_tem(); //读取温度write_shuzi(a1,a2,a3,a4 ); //显示}}六、设计总结1 打好基础,清楚硬件工作原理,性能,以便于编程。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
分享用16F877A和DS18B20的测温程序以下是用本网站的MCD-demouse板做了一个0到99度的测温程序,只要把数据处理程序改一下就可以改变测量范围和精度。
#INCLUDE <P16F877A.INC>CBLOCK 20HINPUT_HIGH_8 ;high 8 bit,don't allow other P use it but temperature conversion pINPUT_LOW_8 ;low 8 bit,don't allow other P use it but temperature conversion pDELAY_TEMP0DELAY_TEMP1PASS_TEMPUNITS_ORDERTENS_DIGITCOUNT_16ENDCORG 00HNOPGOTO INITIALORG 05HTABLEADDWF PCL,1DT 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,90H,90H,90H ;comment anodeDISPLAYMOVFW UNITS_ORDERCALL TABLEMOVWF PORTCBCF PORTA,0 ;trigger transistor of NPN than display units_o rderCALL DELAY_1MSBSF PORTA,0 ;closeMOVFW TENS_DIGITCALL TABLEMOVWF PORTCBCF PORTA,1 ;trigger transistor of NPN than display tens_dig itCALL DELAY_1MSBSF PORTA,1RETURNDELAY_1MSMOVLW 12HMOVWF DELAY_TEMP0MOVLW 12HMOVWF DELAY_TEMP1DECFSZ DELAY_TEMP1GOTO $-1DECFSZ DELAY_TEMP0GOTO $-5RETURNINITIALBANKSEL TRISAMOVLW 00HMOVWF TRISA ;porta0..1 to launch led, porta2 18b20 communicatio n portMOVLW B'00000110' ;set porta as digital portMOVWF ADCON1MOVLW 00HMOVWF TRISC ;8 bits led data busMOVLW 0FFH ;portb1 as a command keyMOVWF TRISBMOVLW 00HMOVWF OPTION_REG ;portb as week pull upBANKSEL PORTACLRF UNITS_ORDERCLRF TENS_DIGITMAINCALL DISPLAY ;press key to start the functionBTFSC PORTB,2GOTO $-2BTFSS PORTB,2 ;key release?GOTO $-1CALL INITIAL_18B20BTFSS DELAY_TEMP1,1GOTO MAINMOVLW 0CCH ;skip the romMOVWF PASS_TEMPCALL WRITE_18B20MOVLW 44H ;release the command of conversionMOVWF PASS_TEMPCALL WRITE_18B20MOVLW D'30'MOVWF COUNT_16MOVLW D'90' ;delay 900ms for conversionMOVWF DELAY_TEMP1MOVLW D'110'MOVWF DELAY_TEMP0DECFSZ DELAY_TEMP0GOTO $-1DECFSZ DELAY_TEMP1GOTO $-5DECFSZ COUNT_16GOTO $-9CALL INITIAL_18B20BTFSS DELAY_TEMP1,1GOTO MAINMOVLW 0CCHMOVWF PASS_TEMPCALL WRITE_18B20 ;release the command of reading MOVLW 0BEHMOVWF PASS_TEMPCALL WRITE_18B20CALL READ_18B20CALL INITIAL_18B20 ;end the other data to transmit BTFSS DELAY_TEMP1,1GOTO MAINCALL BCD_CONVERSIONGOTO MAININITIAL_18B20BCF PORTB,2BANKSEL TRISABCF TRISA,2BANKSEL PORTAMOVLW 0BHMOVWF DELAY_TEMP0MOVLW 22HMOVWF COUNT_16DECFSZ COUNT_16,1GOTO $-1 ;delay 586usDECFSZ DELAY_TEMP0,1GOTO $-5BANKSEL TRISABSF TRISA,2 ;release the busBANKSEL PORTAMOVFW PORTAMOVLW D'25' ;delay 76usMOVWF DELAY_TEMP0DECFSZ DELAY_TEMP0,1GOTO $-1BTFSS PORTA,2GOTO $+3BCF DELAY_TEMP1,1 ;not respondenceGOTO $+2BSF DELAY_TEMP1,1MOVLW D'160' ;delay 480usMOVWF DELAY_TEMP0DECFSZ DELAY_TEMP0,1GOTO $-1BSF DELAY_TEMP1,1 ;the slave device responded and set the bit of f lagRETURNWRITE_18B20MOVLW 08HMOVWF DELAY_TEMP0BCF STATUS,CWR_LOOP1BCF PORTA,2BANKSEL TRISABCF TRISA,2BANKSEL PORTANOPNOPRRF PASS_TEMP,1BTFSS STATUS,CGOTO WR_ZEROBANKSEL TRISABSF TRISA,2BANKSEL PORTAWR_ZEROMOVLW D'25' ;delay 75usMOVWF DELAY_TEMP1DECFSZ DELAY_TEMP1GOTO $-1BANKSEL TRISABSF TRISA,2BANKSEL PORTANOPNOPDECFSZ DELAY_TEMP0,1GOTO WR_LOOP1RETURNREAD_18B20MOVLW D'16'MOVWF DELAY_TEMP0READ_LOOP2BCF PORTA,2BANKSEL TRISABCF TRISA,2BANKSEL PORTANOPNOPNOPNOPNOPBANKSEL TRISABSF TRISA,2BANKSEL PORTANOPNOPNOPNOPBTFSS PORTA,2GOTO $+3BSF STATUS,CGOTO $+2BCF STATUS,CRRF INPUT_HIGH_8,1RRF INPUT_LOW_8,1MOVLW D'20' ;delay 60usMOVWF DELAY_TEMP1DECFSZ DELAY_TEMP1,1GOTO $-1DECFSZ DELAY_TEMP0,1GOTO READ_LOOP2RETURNBCD_CONVERSIONMOVLW 08HMOVWF COUNT_16MOVLW 0FHANDWF INPUT_HIGH_8,1SWAPF INPUT_HIGH_8,1MOVLW 0F0HANDWF INPUT_LOW_8,1SWAPF INPUT_LOW_8,1MOVFW INPUT_LOW_8ADDWF INPUT_HIGH_8,1 ;save 8bits data in input_high_8CLRF INPUT_LOW_8BCF STATUS,CLOOP_8TIMESRLF INPUT_HIGH_8,1RLF INPUT_LOW_8,1DECFSZ COUNT_16GOTO $+2GOTO SEPARATE_2RSMOVLW INPUT_LOW_8MOVWF FSRCALL ADJ_BCDGOTO LOOP_8TIMESADJ_BCDMOVLW 03HADDWF INDF,WMOVWF TENS_DIGITBTFSC TENS_DIGIT,3MOVWF INDF ;if the low four bits plus 3 is more than 7,MOVLW 30H ;add 3,if less than 7,do not change itADDWF INDF,W ;if the high four bits plus 3 is more than 7,than MOVWF TENS_DIGITBTFSC TENS_DIGIT,7 ;add 3,if less than 7,do not change itMOVWF INDFRETURNSEPARATE_2RSMOVFW INPUT_LOW_8MOVWF UNITS_ORDERMOVWF TENS_DIGITMOVLW 0FHANDWF UNITS_ORDER,1MOVLW 0F0HANDWF TENS_DIGIT,1SWAPF TENS_DIGIT,1RETURNEND。