📄 temp-music-alarm.asm
字号:
;----------------------------------------------------
TEMP_TH DATA 22H ;高温报警值存放单元
TEMP_TL DATA 23H ;低温报警值存放单元
TEMP_ZH DATA 24H ;实时温度值存放单元
TEMPL DATA 25H
TEMPH DATA 26H
TEMPHC DATA 29H
TEMPLC DATA 2AH
DATE_LINE EQU P2.2
BUZZER EQU P2.0
RELAY EQU P2.1 ;继电器控制端口
;--------------------------------
ORG 0000H
JMP MAIN
org 000bh ;timer0中断起始地址
jmp tim0 ;跳至timer0中断子程序
MAIN: MOV SP,#60H
MOV A,#00H
MOV R0,#20H ;将 20H-2FH 单元清零
MOV R1,#10H
CLEAR: MOV @R0,A
INC R0
DJNZ R1,CLEAR
mov temp_th,#1EH
mov temp_TL,#1CH
START2:
CALL RESET
MOV A,#0CCH ; 跳过ROM匹配
CALL WRITE
MOV A,#44H ; 发出温度转换命令
CALL WRITE
CALL RESET
MOV A,#0CCH ; 跳过ROM匹配
CALL WRITE
MOV A,#0BEH ; 发出读温度命令
CALL WRITE
CALL READ
CALL CONVTEMP
Call DISPBCD
CALL SMG
CALL main0
CALL TEMP_COMP
SJMP START2
;-----------------------------------------------------
reset: setb date_line
nop
clr date_line
mov r0,#6bh ;主机发出延时复位低脉冲
mov r1,#04h
tsr1: djnz r0,$
mov r0,#6bh
djnz r1,tsr1
setb date_line ;然后拉高数据线
nop
nop
nop
mov r0,#32h
tsr5: mov r0,#06bh
tsr6: djnz r0,$ ; 时序要求延时一段时间
tsr7: setb date_line
ret
;-------------------------------------------------------
write: mov r2,#8 ;一共8位数据
CLR C
wr1:
clr date_line ;开始写入DS18B20总线要处于复位(低)状态
mov r3,#07
djnz r3,$ ;总线复位保持16微妙以上
rrc a ;把一个字节DATA 分成8个BIT环移给C
mov date_line,c ;写入一个BIT
mov r3,#3CH
djnz r3,$ ;等待100微妙
setb date_line ;重新释放总线
nop
djnz r2,wr1 ;写入下一个BIT
setb date_line
ret
;--------------------------------------------------------------------
read: mov r4,#4 ; 将温度低位、高位、TH、TL从DS18B20中读出
mov r1,#TEMPL ; 存入25H、26H、27H、28H
re00: mov r2,#8
re01: clr cy
setb date_line
nop
nop
clr date_line ;读前总线保持为低
nop
nop
nop
setb date_line ;开始读总线释放
mov r3,#09 ;延时18微妙
djnz r3,$
mov c,date_line ;从DS18B20总线读得一个BIT
mov r3,#3CH
djnz r3,$ ;等待100微妙
rrc a ;把读得的位值环移给A
djnz r2,re01 ;读下一个BIT
mov @r1,a
inc r1
djnz r4,re00
ret
;----------------------------------------------------
; 处理温度 BCD 码子程序
;----------------------------------------------------
CONVTEMP: MOV A,TEMPH ;判温度是否零下
ANL A,#80H
JZ TEMPC1 ;温度零上转
CLR C
MOV A,TEMPL ;二进制数求补(双字节)
CPL A ;取反加1
ADD A,#01H
MOV TEMPL,A
MOV A,TEMPH
CPL A
ADDC A,#00H
MOV TEMPH,A
SJMP TEMPC11
TEMPC1: MOV TEMPHC,#0AH ;+
TEMPC11: MOV A,TEMPHC
SWAP A
MOV TEMPHC,A
MOV A,TEMPL
ANL A,#0FH ;乘0.0625
MOV DPTR,#TEMPDOTTAB
MOVC A,@A+DPTR
MOV TEMPLC,A ;TEMPLC LOW=小数部分 BCD
MOV A,TEMPL ;整数部分
ANL A,#0F0H ;取出高四位
SWAP A
MOV TEMPL,A
MOV A,TEMPH ;取出低四位
ANL A,#0FH
SWAP A
ORL A,TEMPL ;重新组合
MOV TEMP_ZH,A
LCALL HEX2BCD1
MOV TEMPL,A
ANL A,#0F0H
SWAP A
ORL A,TEMPHC ;TEMPHC LOW = 十位数 BCD
MOV TEMPHC,A
MOV A,TEMPL
ANL A,#0FH
SWAP A ;TEMPLC HI = 个位数 BCD
ORL A,TEMPLC
MOV TEMPLC,A
MOV A,R4
JZ TEMPC12
ANL A,#0FH
SWAP A
MOV R4,A
MOV A,TEMPHC ;TEMPHC HI = 百位数 BCD
ANL A,#0FH
ORL A,R4
MOV TEMPHC,A
TEMPC12: RET
;---------------------------------------------------------------
HEX2BCD1:
MOV B,#064H ;十六进制-> BCD
DIV AB ;B= A % 100
MOV R4,A ;R7 = 百位数
MOV A,#0AH
XCH A,B
DIV AB ;B = A % B
SWAP A
ORL A,B
RET
;-------------------------------
; 小数部分码表
;-------------------------------
TEMPDOTTAB:
DB 00H,00H,01H,01H,02H,03H,03H,04H
DB 05H,05H,06H,06H,07H,08H,08H,09H
;--------------------------------
;显示区 BCD 码温度值刷新子程序
;--------------------------------
DISPBCD:
MOV A,TEMPLC
ANL A,#0FH
MOV 70H,A ;小数位
MOV A,TEMPLC
SWAP A
ANL A,#0FH
MOV 71H,A ;个位
MOV A,TEMPHC
ANL A,#0FH
MOV 72H,A ;十位
MOV A,TEMPHC
SWAP A
ANL A,#0FH
MOV 73H,A ;百位
MOV A,TEMPHC
ANL A,#0F0H
CJNE A,#010H,DISPBCD0
SJMP DISPBCD2
DISPBCD0: MOV A,TEMPHC
ANL A,#0FH
JNZ DISPBCD2 ;十位数是0
MOV A,TEMPHC
SWAP A
ANL A,#0FH
MOV 73H,#0AH ;符号位不显示
MOV 72H,A ;十位数显示符号
DISPBCD2: RET
;--------------------------------
; 数码管显示
;--------------------------------
SMG:
mov dptr,#numtab
MOV A,TEMPLC
ANL A,#0FH
MOV 70H,A ;小数位
MOVC A,@A+DPTR
MOV P0,A
CLR P2.4
CALL DELAY1
SETB P2.4
MOV A,TEMPLC
SWAP A
ANL A,#0FH
MOV 71H,A ;个位
MOVC A,@A+DPTR
MOV P0,A
clr P0.0
CLR P2.5
CALL DELAY1
SETB P2.5
MOV A,TEMPHC
ANL A,#0FH
MOV 72H,A ;十位
MOVC A,@A+DPTR
MOV P0,A
CLR P2.6
CALL DELAY1
SETB P2.6
MOV A,TEMPHC
SWAP A
ANL A,#0FH
CJNE A,#010H,SMG0
SJMP SMG2
SMG0: MOV A,TEMPHC
ANL A,#0FH
JNZ SMG2 ;十位数是0
MOV A,TEMPHC
SWAP A
ANL A,#0FH
MOV 73H,#0AH ;符号位不显示
MOV 72H,A ;十位数显示符号
SMG2: RET
numtab: db 03h,9fh,25h,0dh,99h,49h,41h,1fh,01h,09h
;--------------------------------
;发送给PC机
;--------------------------------
main0: MOV 20H,#00H
MOV TMOD,#22H ;设定时器工作方式
MOV SCON,#40H
MOV TH1,#0FAH ;速度9600
MOV PCON,#80H
SETB TR1
SETB REN ;允许接收
ajmp kaishi
kaishi:
MOV DPTR,#NUMTAB1
MOV A,TEMPLC
ANL A,#0FH
MOV 70H,A ;小数位
MOV A,TEMPLC
SWAP A
ANL A,#0FH
MOV 71H,A ;个位
MOV A,TEMPHC
ANL A,#0FH
MOV 72H,A ;十位
MOV A,TEMPHC
SWAP A
ANL A,#0FH
MOV 73H,A ;百位
MOV A,TEMPHC
ANL A,#0F0H
SENDA:
CLR A
MOV A,70H
MOV SBUF,A
MOV SBUF,'$'
AJMP DELAY1
MOV A,71H
mov sbuf,a
mov sbuf,'$'
AJMP DELAY1
mov a,72H
mov sbuf,a
mov sbuf,'$'
AJMP DELAY1
mov a,73H
mov sbuf,a
mov sbuf,'$'
AJMP DELAY1
JNB TI,$
CLR TI
CJNE A,#010H,PCFS0
SJMP PCFS2
PCFS0: MOV A,TEMPHC
ANL A,#0FH
JNZ PCFS2 ;十位数是0
MOV A,TEMPHC
SWAP A
ANL A,#0FH
MOV 73H,#0AH ;符号位不显示
MOV 72H,A ;十位数显示符号
PCFS2: RET
numtab1: db 02h,9fh,25h,0dh,99h,49h,41h,1fh,01h,09h
ok: db 70H,71H,72H,73H,'$'
;--------------------------------
TEMP_COMP:
MOV A,TEMP_TH
SUBB A,TEMP_ZH ;减数>被减数,则
JC Gaowen ;借位标志位C=1,转
MOV A,TEMP_ZH
SUBB A,TEMP_TL ;减数>被减数,则
JC DiWen ;借位标志位C=1,转
clr relay
mov p1,#11110000B
RET
GaoWen: mov p1,#10101010B
ljmp L2
RET
DiWen: mov p1,#0
setb relay
RET
;--------------------------------
DE2: NOP
DJNZ R7,DE2
RET
DELAY:
MOV R6,#50
DL1: MOV R7,#100
DJNZ R7,$
DJNZ R6,DL1
DJNZ R5,DELAY
RET
DELAY1:
MOV R6,#25
DL2: MOV R7,#50
DJNZ R7,$
DJNZ R6,DL2
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
L2: push a
push psw
mov tmod,#01h ;设timer0在MODE1
mov ie,#82h ;中断使能
start0:
mov 30h,#00h ;取简谱码指针
next: mov a,30h ;简谱码指针载入A
mov dptr,#table ;至table取简谱码
movc a,@a+dptr
mov r2,a ;取到的简谱码暂存于R2
jz end0 ;是否取到00(结束码)?
anl a,#0fh ;不是,则取低4位(节拍码)
mov r5,a ;将节拍码存入R5
mov a,r2 ;将取到的简谱码再载入A
swap a ;高低四位交换
anl a,#0fh ;取低四位(音符码)
jnz sing ;取到的音符码是否为零?
clr tr0 ;是,则不发音
jmp d1
sing: dec a ;取到的音符码减1(不含0).
mov 22h,a ;存入(22H).
rl a ;乘2
mov dptr,#table1 ;至table1取相对的高位字节计数值
movc a,@a+dptr
mov th0,a ;取到的高位字节存入TH0
mov 21h,a ;取到的高位字节存入(21H)
mov a,22h ;再载入取的的音符码
rl a ;乘2
inc a ;加1
movc a,@a+dptr ;至table1取相对的低位字节计数值
mov tl0,a ;取到的高位字节存入TL0
mov 20h,a ;取到的高位字节存入(20H)
setb tr0 ;启动timer0
d1: call Adelay ;基本单位时间1/4拍187毫秒
inc 30h ;取简谱码指针加1
jmp next ;取下一个码
end0: clr tr0 ;停止timer0
; jmp start0 ;重复循环
pop a
pop psw
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;time0中断服务子程序用来产生相应的音调脉冲频率。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
tim0:
push acc ;将A的值暂存于堆栈
push psw ;将psw的值暂存于堆栈
mov tl0,20h ;重设计数值
mov th0,21h
cpl BUZZER ;将蜂鸣器反相
pop psw ;至堆栈取回psw的值
pop acc ;至堆栈取回a的值
reti ;返回主程序
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Adelay: mov r7,#02h ;187毫秒
d2: mov r4,#187
d3: mov r3,#248
djnz r3,$
djnz r4,d3
djnz r7,d2
djnz r5,Adelay ;决定节拍
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
table1:
dw 64260,64400,64524,64580
dw 64684,64777,64820,64898
dw 64968,65030,65058,65110
dw 65157,65178,65217
table:
;1
db 82h,01h,81h,94h,84h,0b4h,0a4h,04h,82h,01h,81h,94h,84h,0c4h,0b4h,04h
;2
db 82h,01h,81h,0f4h,0d4h,0b4h,0a4h,94h,0e2h,01h,0e1h,0d4h,0b4h,0c4h,0b4h,04h
;3
db 82h,01h,81h,94h,84h,0b4h,0a4h,04h,82h,01h,81h,94h,84h,0c4h,0b4h,04h
;4
db 82h,01h,81h,0f4h,0d4h,0b4h,0a4h,94h,0e2h,01h,0e1h,0d4h,0b4h,0c4h,0b4h,04h,00
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -