技术热线: 4007-888-234

适合初学者的1BUS总线-DS18B20的小例子

更新时间: 2019-03-23
阅读量:2207

十年专注单片机方案开发的方案公司英锐恩,分享适合初学者的1BUS总线-DS18B20的小例子。英锐恩现提供服务产品涉及主控芯片:8位单片机、16位单片机、32位单片机及各类运算放大器等。

#INCLUDE P16F877A.INC DAT_D EQU PORTA DAT_T EQU TRISA TMP0 EQU 30H PDBYTE EQU TMP0+1 COUNT EQU TMP0+2 IOBYTE EQU TMP0+3 WENDUH EQU TMP0+4 WENDUL EQU TMP0+5 DQ EQU 2 ORG 00H NOP NOP SETUP: BCF STATUS,RP0 BCF STATUS,GIE CLRF PORTC CLRF PORTA BSF STATUS,RP0 MOVLW H'07' MOVWF ADCON1 CLRF TRISC MOVLW H'0FF' MOVWF TRISA BCF STATUS,RP0 GOTO START START: BTFSS PORTA,DQ GOTO START CALL OW_RESET ;初始化DS18B20 BTFSS PDBYTE,0 GOTO ERROR_1 MOVLW H'0CC' ;直访ROM指令 CALL DSTXBYTE MOVLW H'44' ;转换温度指令 CALL DSTXBYTE WAIT1: CALL DELAY CALL DELAY CALL OW_RESET ;初始化DS18B20 MOVLW H'0CC' CALL DSTXBYTE ;直访ROM指令 MOVLW H'0BE' CALL DSTXBYTE ;读取温度命令 CALL DSRXBYTE NOP MOVF IOBYTE,W MOVWF PORTC ;显示温度低字节(二进制) GOTO START ERROR_1: NOP GOTO START

;************************************************************************************ OW_HIZ MACRO ;强制DQ变为高组态 BSF STATUS,RP0 ;选择数据存储器BANK1 BSF DAT_T,DQ ;使DQ引脚变为高阻态 BCF STATUS,RP0 ;选择数据存储器的BANK0 ENDM ;-------------------------------------------------------------------- OW_LO MACRO ;强制DQ变为逻辑低电平 BCF STATUS,RP0 ;选择数据存储器的BANK0 BCF DAT_D,DQ ;清除DQ位 BSF STATUS,RP0 ;选择数据存储器的BANK1 BCF DAT_T,DQ ;把DQ引脚作为输出 BCF STATUS,RP0 ;选择数据存储器的BANK0 ENDM ;-------------------------------------------------------------------- WAIT MACRO TIME ;延时TIMEUS ;时间必须是5US的整数 MOVLW (TIME/5)-1 ;处理时间:1US MOVWF TMP0 ;处理时间:1US CALL WAIT5U ;处理时间:2US ENDM ;************************************************************************************ WAIT5U: ;需要5US来完成 NOP ;处理时间为1US NOP ;处理时间为1US DECFSZ TMP0,F ;如果不为零,处理时间为1US,如果为零,处理时间为2US GOTO WAIT5U ;处理时间为2US RETLW 0 ;处理时间为2US ;************************************************************************************ OW_RESET: OW_HIZ ;以口线为高电平开始 CLRF PDBYTE ;清除PD字节 OW_LO ; WAIT D'500' ;驱动器输出低电平500US OW_HIZ ; WAIT D'70' ;释放口线,等待PD脉冲70US BTFSS DAT_D,DQ ;读PD脉冲 INCF PDBYTE,F ;如果检测到了PD脉冲,就把PDBYTE置位1 WAIT D'430' ;在PD脉冲后等待430US RETLW 0 ; ;-------------------------------------------------------------------- DSTXBYTE: MOVWF IOBYTE ;要发送的字节从W开始 MOVLW D'8' ;从IOBYTE开始发送 MOVWF COUNT ;置COUNT为8,表示要发送的比特数 DSTXLP: OW_LO ; NOP ; NOP NOP ;口线变低电平5US NOP NOP RRF IOBYTE,F ;数据字节 BTFSC STATUS,C ;检查IOBYTE的LSB是1还是0 BSF DAT_D,DQ ;如果LSB是1,线路为高电平 WAIT D'60' ;连续驱动线路60US OW_HIZ ;为了上拉,释放口线 NOP NOP ;2US的恢复时间 DECFSZ COUNT,F ;位计数器减1 GOTO DSTXLP ; RETLW 

0 ; ;-------------------------------------------------------------------- DSRXBYTE: MOVLW D'8' ;读入的字节保存入IOBYTE MOVWF COUNT ;把COUNT设为8,来进行位数计数 DSRXLP: OW_LO ; NOP NOP NOP ;把DQ变低6US NOP NOP NOP ; OW_HIZ ;变为HIZ,等待4US NOP NOP NOP NOP ; MOVF DAT_D,W ;读DQ ANDLW B'00000100' ;屏蔽DQ位 ADDLW D'255' ;如果DQ=1,则C=1;如果DQ=0则C=0 RRF IOBYTE,F ;

把C移位至IOBYTE WAIT D'50' ;等50US直到时隙末 DECFSZ COUNT,F ;位计数器减1 GOTO DSRXLP ; RETLW 0 ;************************************************************************************ DELAY ;子程序名,也是子程序入口地址 movlw 0Ffh ;将外层循环参数值FFH经过W movwf H'20' ;送入用作外循环变量的20H单元 lp0 movlw 0Ffh ;将内层循环参数值FFH经过W movwf 21h ;送入用作内循环变量的21H单元 lp1 decfsz 21h,F ;变量21H内容递减,若为0跳跃 goto lp1 ;跳转到LP1处 decfsz 20h,F ;变量20H内容递减,若为0跳跃 goto lp0 ;跳跃到LP0处 return ;返回主程序 END

(文源网络,侵删)