⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 18b20.asm

📁 熟悉DS18B20的使用 六位数码管显示温度结果
💻 ASM
字号:
;实验目的:熟悉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_OSC
 
    CBLOCK 20H
DQ_DELAY1
DQ_DELAY2
TEMP
TEMP1
TEMP2                         ;存放采样到的温度值
TEMP3
COUNT
COUNT1
 ENDC
TMR0_VALUE        EQU  0AH   ;寄存器初值为6,预分频比1:4,中断一次时间为4*(256-6)=1000us
DQ_DELAY_VALUE1   EQU  0FAH
DQ_DELAY_VALUE2   EQU  4H

;**********************以下是程序的开始************************
	ORG    00H              
    NOP   
	GOTO   MAIN             ;入口地址
	ORG    04H
    RETFIE                  ;在中断入口出放置一条中断返回指令,防止干扰产生中断

TABLE 
     ADDWF       PCL,1   
     RETLW       0C0H          ;0的编码(公阳极数码管)                             
     RETLW       0F9H          ;1的编码
     RETLW       0A4H          ;2的编码
     RETLW       0B0H          ;3的编码
     RETLW       99H           ;4的编码
     RETLW       92H           ;5的编码
	 RETLW       082H 	       ;6
	 RETLW       0F8H 	       ;7
	 RETLW       080H 	       ;8
	 RETLW       090H 	       ;9

;***************************主程序*******************************
MAIN
    CLRF     PORTA
    CLRF     PORTB
    BANKSEL  TRISA
    CLRF     TRISA              ;A口所有先设置为输出
    CLRF     TRISD
    MOVLW    01H
    MOVWF    TRISB              ;B0口为输入,其他为输出
    MOVLW    06H
    MOVWF    ADCON1             ;关闭所有A/D口
    MOVLW    01H
    MOVWF    OPTION_REG         ;分频比1:4,定时器,内部时钟源
	BCF      STATUS,RP0
    
	CLRF     TEMP
    CLRF     TEMP1
    CLRF     TEMP2              ;清零临时寄存器
    MOVLW    8H
    MOVWF    COUNT
    MOVLW    38H
    MOVWF    FSR
    CLRF     INDF
    INCF     FSR,1
    DECFSZ   COUNT,1
    GOTO     $-3
      
;****************************循环处理部分************************

;先启动18B20温度转换程序,在判断温度转换是否完成(需750us)
;未完成则调用显示子程序,直到完成温度转换
;完成后读取温度值
;送LCD显示
LOOP 
    BTFSC    PORTB,0          ;判断温度转换按键是否按下
    GOTO     LOOP1            ;否,转显示
    CALL     DELAY            ;消抖
    BTFSC    PORTB,0          ;再次判断
    GOTO     LOOP1
    CALL     RESET_18B20      ;调用复位18B20子程序
    MOVLW    0CCH 
    MOVWF    TEMP
    CALL     WRITE_18B20      ;SKIP ROM命令
    MOVLW    44H
    MOVWF    TEMP
    CALL     WRITE_18B20      ;温度转换命令   
    CLRF     STATUS 
    CALL     DELAY_750MS      ;调用温度转换所需要的750MS延时
    NOP
    CALL     RESET_18B20      
    MOVLW    0CCH 
    MOVWF    TEMP
    CALL     WRITE_18B20      ;SKIP ROM命令
    MOVLW    0BEH 
    MOVWF    TEMP
    CALL     WRITE_18B20      ;读温度命令
    CALL     READ_18B20       ;调用读温度低字节
    MOVFW    TEMP
    MOVWF    TEMP1            ;保存到TEMP1
    CALL     READ_18B20       ;调用读温度高字节
    MOVFW    TEMP
    MOVWF    TEMP2            ;保存到TMEP2
	CALL     RESET_18B20      
LOOP1
    CALL     TEMP_CHANGE      ;调用温度转换程序
    CALL     DISPLAY          ;调用LCD显示程序
    GOTO     LOOP             ;循环工作

;*********************复位DS18B20子程序**************************
RESET_18B20
;根据DATASHEET介绍,写数据时应遵照如下规定:
;主控制器把总线拉低至少480us,
;18B20等待15-60us后,把总线拉低做为返回给控制器的应答信号  	
    BANKSEL  TRISA
    BCF      TRISA,0
    BCF      STATUS,RP0
    BCF      DQ
    MOVLW    0A0H
    MOVWF    COUNT           ;160US
    DECFSZ   COUNT,1
    GOTO     $-1             ;拉低480us
    BSF      DQ              ;释放总线  
    MOVLW    14H
    MOVWF    COUNT
    DECFSZ   COUNT,1
    GOTO     $-1             ;等待60us
    BANKSEL  TRISA
    BSF      TRISA,2         ;DQ设置为输入
    BCF      STATUS,RP0
    BTFSC    DQ              ;数据线是否为低
    GOTO     RESET_18B20     ;否则继续复位
    MOVLW    4H
    MOVWF    COUNT
    DECFSZ   COUNT,1         ;延时一段时间后再次判断
    GOTO     $-1
    BTFSC    DQ
    GOTO     RESET_18B20
    MOVLW    4BH             
    MOVWF    COUNT
    DECFSZ   COUNT,1
    GOTO     $-1 
    BANKSEL  TRISA
    BCF      TRISA,0         ;DQ设置为输出
    BCF      STATUS,RP0
    RETURN
;*********************写DS18B20子程序****************************
WRITE_18B20
;根据DATASHEET介绍,写数据时应遵照如下规定:
;写数据0时,主控制器把总线拉低至少60us
;写数据1时,主控制器把总线拉低,但必须在15us内释放    
    MOVLW    8H
    MOVWF    COUNT           ;8位数据
    BANKSEL  TRISA
    BCF      TRISA,0
    BCF      STATUS,RP0
    BCF      STATUS,C
WRITE_18B20_1
    BSF      DQ              ;先保持DQ为高
    MOVLW    5H
    MOVWF    COUNT1
    BCF      DQ              ;拉低DQ15us
    DECFSZ   COUNT1,1
    GOTO     $-1            
    RRF      TEMP,1          
    BTFSS    STATUS,C        ;判断写的数据为0还是1
    GOTO     WRITE_0          
    BSF      DQ              ;为1,立即拉高数据线
    GOTO     WRITE_END
WRITE_0
    BCF      DQ              ;继续保持数据线为低
WRITE_END
    MOVLW    0FH
    MOVWF    COUNT1          ;保持45ms
    DECFSZ   COUNT1,1
    GOTO     $-1
    BSF      DQ              ;释放总线
    DECFSZ   COUNT,1         ;是否写完8位数据
    GOTO     WRITE_18B20_1
    RETURN
;**********************读DS18B20子程序****************************
READ_18B20
;根据DATASHEET介绍,读数据时应遵照如下规定:
;读数据0时,主控制器把总线拉低后,18B20再把总线拉低60us
;读数据1时,主控制器把总线拉低后,保持总线状态不变
;主控制器在数据线拉低后15us内读区数据线上的状态。         
     MOVLW    8H               ;一次读8位数据
     MOVWF    COUNT
READ_18B20_1
     BANKSEL  TRISA
     BCF      TRISA,0          ;数据线先设为输出
     BCF      STATUS,RP0
     BCF      DQ               ;先拉低数据线
     MOVLW    1H
     MOVWF    COUNT1          
     DECFSZ   COUNT1,1         ;拉低总线3us 
     GOTO     $-1
     BSF      DQ               ;释放总线
     BANKSEL  TRISA
     BSF      TRISA,0          ;数据线设为输入
     BCF      STATUS,RP0
     MOVLW    2H
     MOVWF    COUNT1
     DECFSZ   COUNT1,1         ;延时6ms
     GOTO     $-1
     BSF      STATUS,C
     BTFSS    DQ               ;判断数据线状态
     BCF      STATUS,C
     RRF      TEMP,1           ;移位到TEMP中
     MOVLW    12H
     MOVWF    COUNT1
     DECFSZ   COUNT1,1
     GOTO     $-1              ;读一位数据至少需要60us
     DECFSZ   COUNT,1          ;是否读完8位
     GOTO     READ_18B20_1
     RETURN
;*******************温度表示形式转换程序************************** 
;因为从18B20中读出的温度值是二进制形式,必须把它转换成对象ASCII才能在LCD上显示
;18B20中温度的表示为:S S S S S 2的6次方 2的5次方 2的4次方    2的3次方 2的2次方 。。。。2的负4次方
;结果整数放在38H开始的存储器里,小数部分放在3B开始的单元里
;38H(百位) 39H(十位) 3AH(个位) 3BH(小数点)3CH(十分位) 3DH(百分位) 3EH(千分位) 3FH(万分位)
TEMP_CHANGE 
;整数部分
;因为转换后温度值位于两个单元内,所以必须先把它们组合到一个单元内。
;因为最大值为127.9375,所以只需判断结果是否大于100来决定百位上的结果
;用循环减0AH的方法得到十位的值,最后剩下的被减数即为个位的结果    
    MOVLW    7H 
    ANDWF    TEMP2,0         ;只保留低3位
    MOVWF    3AH             ;转存3AH
    SWAPF    3AH,1
    MOVFW    TEMP1
    MOVWF    TEMP3           ;转存TEMP2
    MOVLW    0F0H            
    ANDWF    TEMP3,1         ;清除低4位
    SWAPF    TEMP3,0         ;高低半字节交换
    IORWF    3AH,1           ;组合得到结果的7位整数部分
    
    MOVLW    64H             ;计算整数部分百位的结果
    SUBWF    3AH,W           ; -100
    BTFSS    STATUS,C
    GOTO     NEXT0           ;温度小于100
    MOVWF    3AH             ;减后的结果覆盖原来的数据
    MOVLW    1H            
    MOVWF    38H             ;整数部分最高位为1(不可能大于1)
    GOTO     $+2
NEXT0
    CLRF     38H             ;温度小于100,最高位为0
    CLRF     39H             ;计算整数部分十位的结果
    MOVLW    0AH             ; -10
    SUBWF    3AH,1
    BTFSS    STATUS,C
    GOTO     NEXT1
    INCF     39H,1           ;够减 十位上加1
    GOTO     $-5
NEXT1
    MOVLW    0AH
    ADDWF    3AH,1            ;多减一次再加回来,剩下的值即为个位上的值
    
    MOVLW    '.'
    MOVWF    3BH               ;小数点
    
;小数部分
;取四位精度
;计算方法为从最低位开始依次判断是否为1 ,若为1则分别加上:
;0.0625、0.125、0.25、0.5,而且只有百分位相加时有可能结果大于0AH
	CLRF     3CH
    CLRF     3DH
    CLRF     3EH
    CLRF     3FH
    BTFSS    TEMP1,0           
    GOTO     NEXT2
    MOVLW    5H
    MOVWF    3FH
    MOVLW    2H
    MOVWF    3EH
    MOVLW    6H
    MOVWF    3DH               ;万分位  
NEXT2
    BTFSS    TEMP1,1
    GOTO     NEXT3
    MOVLW    5H
    ADDWF    3EH,1
    MOVLW    2H
    ADDWF    3DH,1
    MOVLW    1H
    MOVWF    3CH              ;千分位

NEXT3
    BTFSS    TEMP1,2
    GOTO     NEXT5
    MOVLW    5H
    ADDWF    3DH,1
    MOVLW    0AH
    SUBWF    3DH,1
    BTFSS    STATUS,C
    GOTO     NEXT4
    INCF     3CH,1
    GOTO     $+3
NEXT4
    MOVLW    0AH
    ADDWF    3DH,1
    MOVLW    2H
    ADDWF    3CH,1            ;百分位

NEXT5
    BTFSS    TEMP1,3
    GOTO     NEXT6
    MOVLW    5H
    ADDWF    3CH,1           ;十分位
NEXT6   
    RETURN

;*******************************显示子程序*******************************
;入口参数:39H(十位) 3AH(个位+小数点)3CH(十分位) 3DH(百分位) 3EH(千分位) 3FH(万分位)
;出口参数:无
DISPLAY    
    BANKSEL     TRISA
    CLRF        TRISA            ;A口全部设为输出
    CLRF        STATUS       
    MOVFW       39H             ;显示温度十位
    CALL        TABLE
    MOVWF       PORTD
    BCF         PORTA,0
    CALL        DELAY
    BSF         PORTA,0

    MOVFW       3AH             ;显示温度个位
    CALL        TABLE
    MOVWF       PORTD
    BCF         PORTD,7         ;小数点 
    BCF         PORTA,1
    CALL        DELAY
    BSF         PORTA,1
 
    MOVFW       3CH             ;显示十分位
    CALL        TABLE
    MOVWF       PORTD
    BCF         PORTA,2
    CALL        DELAY
    BSF         PORTA,2

    MOVFW       3DH             ;显示百分位
    CALL        TABLE
    MOVWF       PORTD
    BCF         PORTA,3
    CALL        DELAY
    BSF         PORTA,3

   MOVFW       3EH              ;显示千分位
   CALL        TABLE
   MOVWF       PORTD
   BCF         PORTA,4
   CALL        DELAY
   BSF         PORTA,4

   MOVFW       3FH              ;显示万分位
   CALL        TABLE
   MOVWF       PORTD
   BCF         PORTA,5
   CALL        DELAY
   BSF         PORTA,5

   RETURN
       
;***************************延时程序************************************    
DELAY
               GOTO        $+1
               GOTO        $+1
               GOTO        $+1
               GOTO        $+1
               GOTO        $+1
               GOTO        $+1
               RETURN

;**************************延时750ms******************************
DELAY_750MS
    MOVLW    DQ_DELAY_VALUE2
    MOVWF    DQ_DELAY2
DELAY_750MS_2
    MOVLW    DQ_DELAY_VALUE1
    MOVWF    DQ_DELAY1
DELAY_750MS_1
    MOVLW    TMR0_VALUE
    MOVWF    TMR0               ;开启定时器
    BTFSS    INTCON,T0IF
    GOTO     $-1
    BCF     INTCON,T0IF
    DECFSZ   DQ_DELAY1,1
    GOTO     DELAY_750MS_1
    DECFSZ   DQ_DELAY2,1
    GOTO     DELAY_750MS_2
    RETURN
;**************************程序结束******************************
    END
    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -