📄 28.asm
字号:
;------------------------------------------------------------------------------------------
;DS18B20实时温度检测实验参考程序(实验28.asm)
;------------------------------------------------------------------------------------------
LIST P=16F877
INCLUDE"P16F877.INC"
;------------------------------------------------------------------------------------------ ;计数器
FSR_TEP EQU 69H ;FSR保护缓冲器
INF_TEP EQU 6AH ;INDF保护缓冲器
ORG 0000
NOP
BSF STATUS,5 ;转到体1
CLRF TRISD ;置D口方向控制字
MOVLW B'00010000' ;
MOVWF TRISC ;置C口方向控制字
CLRF SSPSTAT ;清除SMP、CKE位
BCF STATUS,5 ;转回体0
MOVLW B'00110010' ;设置SSP控制方式:取FOSC/64、SPI主控、CKP=1
MOVWF SSPCON
CLRF PORTD ;D口数据清0
CALL CHUSHIHUA ;调用显示初始化子程序
TEMPER CLRF 2AH ;清除温度数据低位存放寄存器
CLRF 2BH ;清除温度数据高位存放寄存器
CALL INIT18B20 ;调用DS18B20初始化子程序
GOTO GET_TEMPER ;转跳至获取温度子程序
END_TEMP MOVF 2AH,0 ;将温度数据低位转入寄存器28H保存
MOVWF 28H
MOVF 2BH,0 ;将温度数据高位转入寄存器29H保存
MOVWF 29H
CALL DISPLAY ;调用显示数据转换子程序
GOTO TEMPER ;转跳至温度检测程序进行温度的循环实时检测
DISPLAY CLRF 20H ;清转换寄存器
CLRF 21H
CLRF 22H
CLRF 23H
MOVLW 0FH
ANDWF 28H,0 ;采用与方式屏蔽高4位
MOVWF 23H ;取温度数据低字节中低4位放寄存器23H的低4位
MOVLW 0F0H ;
ANDWF 28H,0 ;采用与方式屏蔽低4位
MOVWF 22H ;取温度数据低字节中高4位放寄存器22H的高4位
MOVLW 07H
ANDWF 29H,0 ;采用与方式屏蔽低3位
ADDWF 22H,1 ;取温度数据高字节中低3位放22H低3位,此时bit3=0
SWAPF 22H,1 ;寄存器22H中高4位与低4位互换
MOVF 22H,0
MOVWF PORTD ;将寄存器22H数据送D口显示
MOVWF S1L ;将寄存器22H数据送S1L
CLRF S1H
CALL BINTOBCD ;调用二进制转十进制子程序
MOVF R1H,W
MOVWF 38H
MOVF R1Z,W
ANDLW 0FH
MOVWF 38H
MOVF R1L,W
ANDLW 0FH
MOVWF 60H
SWAPF R1L,W
ANDLW 0FH
MOVWF 61H
CALL XSHI
RETLW 0 ;这段程序与之后的有冲突
MOVLW 0F8H
ANDWF 29H,0 ;采用与方式判断温度高字节中高5位为全0还是全1
BTFSC STATUS,2 ;判断状态寄存器Z位
GOTO TO10 ;全0,直接进行数据的十进制转换
COMF 22H ;全1,将22H,23H温度数据取反加1
COMF 23H
INCF 23H,1
BTFSC STATUS,2 ;判断两字节温度数据的低字节是否有向高字节进位
INCF 22H ;是,高字节进位
BCF 22H,7 ;否,将22H中bit7始终置为0
BSF 23H,7 ;置1表示此温度数据为负数
TO10 CLRF 20H ;将22H中的二进制数转成十进制,表示温度的整数部分
CLRF 21H ;清楚转换寄存器
L0 MOVLW 0AH ;个位转换f22=f22-10
SUBWF 22H,0
BTFSS STATUS, 0 ;判断是否减为0
GOTO L10 ;是,转入十位转换
MOVWF 22H ;否,将余数存入22H
INCF 21H,1 ;十位加1
GOTO L0
L10 MOVLW 0AH ;十位转换f21=f21-10
SUBWF 21H,0
BTFSS STATUS, 0 ;判断是否减为0
GOTO L100 ;是,转入百位转换
MOVWF 21H ;否,将余数存入21H
INCF 20H,1 ;百位加1
GOTO L10
L100 BTFSS 23,7 ;判断温度正负值
GOTO L1000 ;GOTO L1000;正
MOVF 21, 1 ;负
BTFSS STATUS, 2 ;判十位为0?
GOTO $+4 ;21H不等于0
MOVLW 0AH ;21H等于0十位显示负号
MOVWF 21
GOTO $+3 ;转换完毕返回
MOVLW 0AH ;f11不等于0百位显示负号
MOVWF 20
L1000 RETURN ;转换完毕返回
INIT18B20 NOP
BSF STATUS,RP0 ;转到体1
BCF TRISC,7 ;置C口Bit7方向位
BCF STATUS,RP0 ;返回体0
BSF PORTC,7 ;C口Bit7置1
NOP
BCF PORTC,7 ;等待1uS,复位Bit7,发送复位脉冲
MOVLW D'200' ;软件延时600uS
MOVWF 24H
DECFSZ 24H,1
GOTO $-1
BSF STATUS,RP0 ;置C口Bit7为输入方式
BSF TRISC,7
BCF STATUS,RP0
RECHECK MOVLW D'20' ;器件响应子程序, 软件延时60uS
MOVWF 24H
BTFSS PORTC,7 ;延时期间检测C口Bit7数据
GOTO $+4 ;0,由于上拉电阻使线路常为1,当器件有响应则为0
DECFSZ 24H,1 ;1,进入软件延时
GOTO $-3
GOTO INIT18B20 ;延时结束,重新进入器件初始化
MOVLW D'80' ;器件有响应,软件延时240uS
MOVWF 24H
DECFSZ 24H,1
GOTO $-1
BTFSS PORTC,7 ;在240uS后检测总线是否为高电平
GOTO RECHECK ;若为低电平,重新检测响应脉冲
RETLW 0 ;检测到器件响应的存在脉冲
GET_TEMPER
CALL INIT18B20 ;调用器件初始化子程序
MOVLW 0CCH ;发送命令代码0CCH,针对在线DS18B20操作
CALL WRITEY ;调用写数据子程序
MOVLW 44H ;发送命令代码44H,启动在线DS10B20做温度A/D转换
CALL WRITEY ;调用写数据子程序
MOVLW D'200' ;软件延时1S以便DS10B20做温度A/D转换
MOVWF 26H
S1 MOVLW D'20'
MOVWF 24H
MOVLW D'100'
MOVWF 25H
DECFSZ 25H,1
GOTO $-1
DECFSZ 24H,1
GOTO $-5
DECFSZ 26H,1
GOTO S1
NOP ; DS10B20做温度A/D转换完成
CALL INIT18B20 ;调用器件初始化
MOVLW 0CCH ;发送命令代码0CCH,针对在线DS18B20操作
CALL WRITEY ;调用写数据子程序
MOVLW 0BEH ;发送命令代码0BEH,读取温度寄存器的温度值
CALL WRITEY ;调用写数据子程序
CALL READY ;调用读数据子程序
GOTO END_TEMP ;转跳至温度检测完毕
WRITEY MOVWF 2DH ;将命令代码存入发送寄存器2DH
MOVLW 08H ;然后释放总线,延时2μs。
MOVWF 25H ;发送数据位个数计数器存放08H
BSF STATUS,RP0 ;每次调用结束都会把口置为输入方式
BSF TRISC,7 ;因此此处不需要置方向
BCF STATUS,RP0
WR1BY NOP
BSF STATUS,RP0 ;将C口Bit7转为输出方式
BCF TRISC,7
BCF STATUS,RP0
BCF PORTC,7 ;总线输出低电平
BTFSC 2DH,0 ;判断发送寄存器2DH的Bit0
GOTO $+2 ;Bit=1
GOTO $+4 ;Bit=0
BSF STATUS,RP0 ;1,释放总线,置C口Bit7方向位为输入
BSF TRISC,7
BCF STATUS,RP0
MOVLW D'40' ;软件延时60uS
MOVWF 26H
DECFSZ 26H,1
GOTO $-1
BSF STATUS,RP0 ;释放总线,置C口Bit7方向位为输入
BSF TRISC,7
BCF STATUS,RP0
RRF 2DH,1 ;将发送寄存器数据右移一位
DECFSZ 25H,1 ;判断发送完毕?
GOTO WR1BY ;继续发送其他位的数据
RRF 2DH,1 ;将状态位C回复原位
RETLW 0 ;带参数调用返回
READY MOVLW 02H
MOVWF 24H ;读入字节个数计数器存放02H;然后进入输入模式延时10μs,
BSF STATUS,RP0 ;释放总线,置C口Bit7方向位为输入
BSF TRISC,7
BCF STATUS,RP0
R1BYTE MOVLW 08H
MOVWF 25H ;读入数据位个数计数器存放08H
R1BIT BSF STATUS,RP0 ;置C口Bit7方向位为输出
BCF TRISC,7
BCF STATUS,RP0
BCF PORTC,7 ;总线输出0
NOP ;延时2uS
BSF STATUS,RP0 ;释放总线,置C口Bit7方向位为输入
BSF TRISC,7
BCF STATUS,RP0
NOP ;软件延时10uS
MOVLW 01H
MOVWF 26H
DECFSZ 26H,1
GOTO $-1
BTFSC PORTC,7 ;读取总线状态,判断0? 1?
GOTO $+3 ;
BCF 2BH,0 ;0,置接收寄存器Bit0=0
GOTO $+2
BSF 2BH,0 ;1,置接收寄存器Bit0=1
NOP ;软件延时60uS
NOP
MOVLW D'20'
MOVWF 26H
DECFSZ 26H,1
GOTO $-1
RRF 2BH,1 ;将接收寄存器数据右移一位
DECFSZ 25H,1 ;判断一个字节8位是否接收完
GOTO R1BIT ;接收其他位数据
RRF 2BH,1 ;状态位C回复原位
DECF 24H,1 ;字节计数器减1
BTFSC STATUS,2 ;判断两字节数据是否接收完毕
GOTO $+4
MOVF 2BH,0 ;0,将温度数据的低字节存入2AH
MOVWF 2AH
GOTO R1BYTE ;读下一字节数据
RETLW 0 ;读取温度数据结束返回
;------------------------------------------------------------------------------------------
;编码查询
;------------------------------------------------------------------------------------------
BMA ADDWF PCL,F
RETLW 3FH ;"0" 编码
RETLW 06H ;"1" 编码
RETLW 5BH ;"2" 编码
RETLW 4FH ;"3" 编码
RETLW 66H ;"4" 编码
RETLW 6DH ;"5" 编码
RETLW 7DH ;"6" 编码
RETLW 07H ;"7" 编码
RETLW 7FH ;"8" 编码
RETLW 6FH ;"9" 编码
RETLW 00H ;"暗" 编码
RETLW 40H ;"-" 编码
;------------------------------------------------------------------------------------------
;显示驱动子程序
;------------------------------------------------------------------------------------------
XSHI MOVLW 67H ;设置显示缓冲器的数据地址
MOVWF FSR
LOOP MOVF INDF,W ;取出数据
CALL BMA ;查询对应编码
CALL OUTXSH ;利用SPI方式输出编码数据
DECF FSR
BTFSS FSR,4 ;直到8位数码全部输出
GOTO LOOP
RETURN
;------------------------------------------------------------------------------------------
;SPI方式输出编码数据子程序
;------------------------------------------------------------------------------------------
OUTXSH MOVWF SSPBUF ;送至SSPBUF后开始逐位发送
LOOP1 BSF STATUS,RP0 ;选择体1
BTFSS SSPSTAT,BF ;是否发送完毕
GOTO LOOP1 ;否,继续查询
BCF STATUS,RP0 ;发送完毕,选择体0
MOVF SSPBUF,W ;移空SSPBUF
RETURN
;------------------------------------------------------------------------------------------
;8位数码全暗,仅仅最高位给出"-"键控提示符
;------------------------------------------------------------------------------------------
SHUAN MOVLW 60H ;除最高位外,均设置为全暗
MOVWF FSR
TUN MOVLW 0AH
MOVWF INDF
INCF FSR
BTFSS FSR,3
GOTO TUN
MOVLW 0BH ;最高位67H单元送"-"编码
MOVWF 67H
RETURN
;------------------------------------------------------------------------------------------
;初始化子程序(67H-60H缓冲存储器分别赋值01-07),从数码最高位67H开始点亮,延时196MS
;------------------------------------------------------------------------------------------
CHUSHIHUA
CALL SHUAN ;首先调用数码全暗设置
CALL XSHI ;输出显示
CALL DELAY10MS ;调用10MS延时
CALL DELAY10MS ;调用10MS延时
CALL DELAY10MS ;调用10MS延时
MOVLW 67H
MOVWF FSR ;从最高位赋值,采用间接寻址
MOVLW 01H
MOVWF COUNTER ;给出赋值数据,从1开始
QT MOVF COUNTER,W
MOVWF INDF
MOVF FSR,W
MOVWF FSR_TEP ;保护FSR
CALL XSHI ;数码刷新
CALL DELAY10MS ;调用10MS延时
CALL DELAY10MS ;调用10MS延时
CALL DELAY10MS ;调用10MS延时
MOVF FSR_TEP,W ;恢复FSR
MOVWF FSR
DECF FSR ;地址减1
INCF COUNTER ;赋值数据加1
BTFSS COUNTER,3 ;8位赋值是否结束
GOTO QT ;否,继续
MOVF COUNTER,W ;已结束
MOVWF INDF ;最高为设置"-"监控状态标志
CALL XSHI ;数码显示刷新
CALL DELAY10MS ;调用10MS延时
CALL DELAY10MS ;调用10MS延时
CALL DELAY10MS ;调用10MS延时
CALL SHUAN ;进入监控状态
CALL XSHI ;数码显示刷新
RETURN
;------------------------------------------------------------------------------------------
;10MS软件延时子程序DELAY10MS
;------------------------------------------------------------------------------------------
DELLAY10MS
MOVLW 0DH ;外循环常数
MOVWF 20H ;外循环寄存器
LOP1 MOVLW 0FFH ;内循环常数
MOVWF 21H ;内循环寄存器
LOP2 DECFSZ 21H ;内循环寄存器递减
GOTO LOP2 ;继续内循环
DECFSZ 20H ;外循环寄存器递减
GOTO LOP1 ;继续外循环
RETURN ;子程序返回
;------------------------------------------------------------------------------------------
;二进制到BCD码转换子程序
;------------------------------------------------------------------------------------------
BINTOBCD MOVLW 10H
MOVWF COUNT
CLRF R1H
CLRF R1Z
CLRF R1L
LOP RLF S1L
RLF S1H
RLF R1L
RLF R1Z
RLF R1H
DECFSZ COUNT
GOTO ADJDET
RETLW 00H
ADJDET MOVLW R1L
MOVWF FSR
CALL ADJBCD
MOVLW R1Z
MOVWF FSR
CALL ADJBCD
MOVLW R1H
MOVWF FSR
CALL ADJBCD
GOTO LOP
ADJBCD MOVLW 03H
ADDWF INDF,W
MOVWF TEMP
BTFSC TEMP,3
MOVWF INDF
MOVLW 30H
ADDWF INDF,W
MOVWF TEMP
BTFSC TEMP,7
MOVWF INDF
RETLW 00H
;------------------------------------------------------------------------------------------
;10MS软件延时子程序DELAY10MS
;------------------------------------------------------------------------------------------
DELAY10MS
MOVLW 0DH ;外循环常数
MOVWF 20H ;外循环寄存器
LP1 MOVLW 0FFH ;内循环常数
MOVWF 21H ;内循环寄存器
LP2 DECFSZ 21H ;内循环寄存器递减
GOTO LP2 ;继续内循环
DECFSZ 20H ;外循环寄存器递减
GOTO LP1 ;继续外循环
RETURN ;子程序返回
;------------------------------------------------------------------------------------------
END
;------------------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -