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

📄 shuiwen.asm

📁 水温控制
💻 ASM
字号:
        TEMPER_L EQU 29H     ;用于保存读出温度的低8位
        TEMPER_H EQU 28H     ;用于保存读出温度的高8位
        FLAG1    EQU 38H     ;是否检测到DS18B20标志位
        FLAG2    EQU 39H     ;存放设定的温度
        FLAG3    EQU 40H     ;存放当前的温度
        a_bit    EQU 20H     ;数码管个位数存放内存位置
        b_bit    EQU 21H     ;数码管十位数存放内存位置
        K_OLD    EQU 30H     ;存放按键未按下时的按键端口值
        K_NEW    EQU 31H     ;存放按键按下时的按键端口值
;------------------------------------------------------
        ORG     0000H
        AJMP    MAIN
        ORG     0030H
;------------------------------------------------------
MAIN:   ACALL   CHUSHI       ;初始化
        LCALL   DS1820       ;显示当前温度
        LCALL   DS1820
        MOV     FLAG3,R5
        MOV     29H,FLAG3
        LCALL   DISPLAY
        LCALL   LOSS         ;判断是否缺水
        LCALL   KEY          ;判断是否有按键
MAIN1:  LCALL   KEY00        ;温度设定
MAIN2:  LCALL   WENBI        ;当前温度与设定温度比较
MAIN3:  LCALL   DS1820
        AJMP    MAIN
;---------- 初始化 -----------------------------------
CHUSHI: MOV     P0,#78H
        MOV     P2,#1CH
        RET
;---------- 当前温度与设定温度比较 -------------------
WENBI:  CLR     C           ;标志位清零
        MOV     A,FLAG3     ;当前温度存入A
        MOV     FLAG2,R2    ;设定温度存入FLAG2
        SUBB    A,FLAG2     ;设定温度减去当前温度
        JNC     MAIN        ;设定温度小于当前温度则跳回主程序
WENBI1: MOV     P0,#7FH     ;判断是否缺水
        LCALL   LOSS        ;缺水报警
        MOV     P2,#12H     ;亮灯,接通继电器,加热
        LCALL   DS1820
        MOV     A,R5
        SUBB    A,FLAG2     ;设定温度减去当前温度
        JC      WENBI1      ;设定温度大于当前温度,继续加热
        MOV     P2,#01H
        LCALL   DS1820
        LCALL   DS1820
        LCALL   DS1820
        LCALL   DS1820
;---------------- 保持温度不变 -----------------------

        CLR     C           ;标志位清零
WENBI2: MOV     P2,#00H
        LCALL   DS1820
        MOV     P0,#7FH     ;判断是否缺水
        LCALL   LOSS
        MOV     A,R5        ;当前温度存入A
        SUBB    A,FLAG2
        JNC     WENBI2      ;设定温度小于当前温度,则继续测试,否则加热
WENBI3: MOV     P2,#12H     ;亮灯,接通继电器,加热
        LCALL   DS1820
        MOV     P0,#7FH     ;判断是否缺水
        LCALL   LOSS
        MOV     A,R5
        SUBB    A,FLAG2
        JC      WENBI3      ;设定温度大于当前温度,则继续加热
        JMP     WENBI2
;--------------- 3号键十位设置 -----------------------
KEY11:	ACALL	K_SCAN2
	MOV	A,K_NEW
	CJNE	A,K_OLD,KEY21
	JMP	KEY11
KEY21:	CALL	K_DELAY
	CALL	K_SCAN2
	MOV	A,K_NEW
	CJNE	A,K_OLD,KEY31
	JMP	KEY11
KEY31:  MOV     A,R3            ;90跳转
        SUBB    A,#5AH
        JZ      KEY00
        MOV     A,R3            ;91跳转
        SUBB    A,#5BH
        JZ      KEY00
        MOV     A,R3            ;92跳转
        SUBB    A,#5CH
        JZ      KEY00
        MOV     A,R3            ;93跳转
        SUBB    A,#5DH
        JZ      KEY00
        MOV     A,R3            ;94跳转
        SUBB    A,#5EH
        JZ      KEY00
        MOV     A,R3            ;95跳转
        SUBB    A,#5FH
        JZ      KEY00
        MOV     A,R3            ;96跳转
        SUBB    A,#60H
        JZ      KEY00
        MOV     A,R3            ;97跳转
        SUBB    A,#61H
        JZ      KEY00
        MOV     A,R3            ;98跳转
        SUBB    A,#62H
        JZ      KEY00
        MOV     A,R3            ;99跳转
        SUBB    A,#63H
        JZ      KEY00
        MOV     A,R3
        ADD     A,#0AH
        MOV     29H,A
        CALL    DISPLAY
        JMP     KEY01
K_SCAN2:MOV  	K_NEW,#00H
        MOV     A,P0.4
        MOV  	K_NEW,A
        RET
;----------------- 中转 --------------------------
MIDDLE1:;JMP     MAIN2
        RET
;----------------- KEY判断 -----------------------
KEY00:  MOV     R2,#00H
        MOV     29H,#00H
        LCALL   DISPLAY
        CALL    KEY01
        RET
KEY01:  LCALL   DISPLAY
	MOV	K_OLD,#00H   ;保存初始值
        JNB     P0.5,KEY10   ;2号键个位有按下则跳转
        JNB     P0.4,KEY11   ;3号键十位有按下则跳转
        JNB     P0.6,MIDDLE1
        JMP     KEY01
;---------------- 2号键个位设置 --------------------------
KEY10:	ACALL	K_SCAN1
	MOV	A,K_NEW
	CJNE	A,K_OLD,KEY20
	JMP	KEY10
KEY20:	CALL	K_DELAY
	CALL	K_SCAN1
	MOV	A,K_NEW
	CJNE	A,K_OLD,KEY30
	JMP	KEY10
KEY30:  MOV     A,#63H
        SUBB    A,R2
        JZ      KEY00
        INC     R2
        MOV     29H,R2
        CALL    DISPLAY
        JMP     KEY01
K_SCAN1:
        MOV  	K_NEW,#00H
        MOV  	A,P0.5
        MOV  	K_NEW,A
        RET
;--------------------- 按键判断 ---------------------------
KEY:    MOV  	P0,#07FH          ;按键端口初始化
	MOV	K_OLD,#70H        ;存储按键未按时的按键端口值
KEY1:   LCALL   DS1820
        LCALL   LOSS
        ACALL	K_SCAN            ;扫描键盘
	MOV	A,K_NEW
	CJNE	A,K_OLD,KEY2
	JMP	KEY1              ;没有按键按下,则继续扫描
KEY2:	CALL	K_DELAY           ;按键延时
	CALL	K_SCAN            ;再次扫描
	MOV	A,K_NEW
	CJNE	A,K_OLD,KEY3      ;有按键按下,跳转运行
	JMP	KEY1              ;没有按键按下,则继续扫描
KEY3:   MOV     P2,#18H
        RET
K_SCAN:
        MOV  	K_NEW,#00H
        MOV  	A,P0
        MOV  	K_NEW,A
        RET
K_DELAY:
        MOV  	R6,#200
K_DEL:
        MOV  	R7,#0FFH
        DJNZ  	R7,$
        DJNZ  	R6,k_DEL
        RET
;-------------- 缺水报警子程序 --------------------------
LOSS:   MOV     A,P0
        MOV     R1,#08H
        ANL     A,R1
        ANL     A,R1
        CJNE    A,#00H,BAOJING
        RET
BAOJING:LCALL   DS1820
        CLR     P2.1
        SETB    P2.0
        Nop
        LCALL   DELAY
        CLR     P2.0
        Nop
        LCALL   DELAY
        LJMP    LOSS
DELAY:  MOV    R1,#10   ;延时0.5s子程序,使用参数R0,R7和R6
DELY0:  MOV    R2,#100  ;延时0.05s
DELY1:  MOV    R3,#250  ;延时0.5ms
        DJNZ   R3,$
        DJNZ   R2,DELY1
        DJNZ   R1,DELY0
        RET
;---------------- DS1820子程序 ------------------------------------
DS1820: LCALL GET_TEMPER;调用读温度子程序
        ;进行温度显示,这里我们考虑用网站提供的两位数码管来显示温度
        ;显示范围00到99度,显示精度为1度
        ;因为12位转化时每一位的精度为0.0625度,我们不要求显示小数所以可以抛弃29H的低4位
        ;将28H中的低4位移入29H中的高4位,这样获得一个新字节,这个字节就是实际测量获得的温度
        ;这个转化温度的方法非常简洁无需乘于0.0625系数
        MOV    A,29H
        MOV    C,40H    ;将28H中的最低位移入C
        RRC    A
        MOV    C,41H
        RRC    A
        MOV    C,42H
        RRC    A
        MOV    C,43H
        RRC    A
        MOV    29H,A
        MOV    R5,29H
        LCALL  DISPLAY  ;调用数码管显示子程序
        ;CPL    P2.2
        RET
; 这是DS18B20复位初始化子程序
INIT_1820:
        SETB   P1.0
        NOP
        CLR    P1.0
;主机发出延时537微秒的复位低脉冲
        MOV    R1,#3
TSR1:   MOV    R0,#107
        DJNZ   R0,$
        DJNZ   R1,TSR1
        SETB   P1.0     ;然后拉高数据线
        NOP
        NOP
        NOP
        MOV    R0,#25H
TSR2:   JNB    P1.0,TSR3;等待DS18B20回应
        DJNZ   R0,TSR2
        LJMP   TSR4     ;延时
TSR3:   SETB   FLAG1    ;置标志位,表示DS1820存在
        ;CLR    P2.3     ;检查到DS18B20就点亮P1.7LED
        LJMP   TSR5
TSR4:   CLR    FLAG1    ;清标志位,表示DS1820不存在
        ;CLR    P2.4
        LJMP   TSR7
TSR5:   MOV    R0,#117
TSR6:   DJNZ   R0,TSR6  ;时序要求延时一段时间
TSR7:   SETB   P1.0
        RET
; 读出转换后的温度值
GET_TEMPER:
        SETB   P1.0
        LCALL  INIT_1820;先复位DS18B20
        JB     FLAG1,TSS2
        RET              ;判断DS1820是否存在?若DS18B20不存在则返回
TSS2:   ;CLR    P2.4      ;DS18B20已经被检测到!!!!!!!!!!!!!!!!!!
        MOV    A,#0CCH   ;跳过ROM匹配
        LCALL  WRITE_1820
        MOV    A,#44H    ;发出温度转换命令
        LCALL  WRITE_1820
;这里通过调用显示子程序实现延时一段时间,等待AD转换结束,12位的话750微秒
        LCALL  DISPLAY
        LCALL  INIT_1820 ;准备读温度前先复位
        MOV    A,#0CCH   ;跳过ROM匹配
        LCALL  WRITE_1820
        MOV    A,#0BEH   ;发出读温度命令
        LCALL  WRITE_1820
        LCALL  READ_18200;将读出的温度数据保存到35H/36H
        RET
;写DS18B20的子程序(有具体的时序要求)
WRITE_1820:
        MOV    R2,#8     ;一共8位数据
        CLR    C
WR1:    CLR    P1.0
        MOV    R3,#6
        DJNZ   R3,$
        RRC    A
        MOV    P1.0,C
        MOV    R3,#23
        DJNZ   R3,$
        SETB   P1.0
        NOP
        DJNZ   R2,WR1
        SETB   P1.0
        RET
; 读DS18B20的程序,从DS18B20中读出两个字节的温度数据
READ_18200:
        MOV    R4,#2     ;将温度高位和低位从DS18B20中读出
        MOV    R1,#29H   ;低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)
RE00:   MOV    R2,#8     ;数据一共有8位
RE01:   CLR    C
        SETB   P1.0
        NOP
        NOP
        CLR     P1.0
        NOP
        NOP
        NOP
        SETB    P1.0
        MOV     R3,#9
RE10:   DJNZ    R3,RE10
        MOV     C,P1.0
        MOV     R3,#23
RE20:
        DJNZ    R3,RE20
        RRC     A
        DJNZ    R2,RE01
        MOV     @R1,A
        DEC     R1
        DJNZ    R4,RE00
        RET
;--------------- 显示子程序 ------------------------------------
display:mov     a,29H           ;将29H中的十六进制数转换成10进制
        MOV     R3,29H
        MOV     R2,29H
        mov     b,#10           ;10进制/10=10进制
        div     ab
        mov     b_bit,a         ;十位在a
        mov     a_bit,b         ;个位在b
        mov     dptr,#numtab    ;指定查表启始地址
        mov     r0,#4
dpl1:   mov     r1,#250         ;显示1000次
dplop:  mov     a,a_bit         ;取个位数
        MOVC    A,@A+DPTR       ;查个位数的7段代码
        mov     p1,a            ;送出个位的7段代码
        clr     p3.7            ;开个位显示
        acall   d1ms            ;显示1ms
        setb    p3.7
        mov     a,b_bit         ;取十位数
        MOVC    A,@A+DPTR       ;查十位数的7段代码
        mov     p1,a            ;送出十位的7段代码
        clr     p3.6            ;开十位显示
        acall   d1ms            ;显示1ms
        setb    p3.6
        djnz    r1,dplop        ;100次没完循环
        djnz    r0,dpl1         ;4个100次没完循环
        ret
;1MS延时(按12MHZ算)
D1MS:   MOV     R7,#80
        DJNZ    R7,$
        RET
;实验板上的7段数码管0~9数字的共阴显示代码
numtab: DB 002H,9EH,024H,0CH,98H,48H,041H,1EH,00H,08H
     ;      0    1    2   3   4   5    6   7   8   9
END

⌨️ 快捷键说明

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