【Proteus仿真】51单片机汇编实现DS18B20+LCD1602显示
时间:2022-11-10 15:30:00
【Proteus模拟】51单片机汇编实现DS18B20 LCD1602显示
- Proteus仿真
汇编代码(.asm)
;******************************************************************************** ;* DS18B20温度控制1602LCD显示 * ;******************************************************************************* ;* 描述: * ;* DS18B20温度控制1602LCD显示 * ;* * ;* 使用方法参考readme.txt文档 * ;* * ;* * ;******************************************************************************** ;******************************************************************************** TEMP_ZH DATA 24H ;实时温度值存放单元 TEMPL DATA 25H ; TEMPH DATA 26H ; TEMP_TH DATA 27H ;高温报警值存放单元 TEMP_TL DATA 28H ;低温报警值存放单元 TEMPHC DATA 29H ; TEMPLC DATA 2AH K1 EQU P1.4 K2 EQU P1.5 K3 EQU P1.6 K4 EQU P1.7 BEEP EQU P3.7 RELAY EQU P1.3 LCD_X EQU 2FH ;LCD 地址变量 LCD_RS EQU P2.0 LCD_RW EQU P2.1 LCD_EN EQU P2.2 flag1 equ 20H.0 ;DS18B20是否存在标记 KEY_UD EQU 20H.1 ;设定 KEY 的UP与DOWN 标记 date_line equ p3.3 ;===================================================== ORG 0000H JMP MAIN ORG 0030H MAIN: MOV SP,#60H MOV A,#00H MOV R0,#20H ;将 20H-2FH 单元清零 MOV R1,#10H CLEAR: MOV @R0,A INC R0 DJNZ R1,CLEAR CALL SET_LCD CALL RE_18B20 start: CALL RESET ;18B20复位子程序 JNB FLAG1,START1 ;DS1820不存在 CALL MENU_OK CALL READ_E2 CALL TEMP_BJ ;显示温度标记 JMP START2 START1: CALL MENU_ERROR CALL TEMP_BJ ;显示温度标记 JMP $ START2: CALL RESET JNB FLAG1,START1 ;DS1820不存在 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 CONV CALL TEMP_COMP CALL PROC_KEY ; 键扫描 SJMP START2 ;----------------------------------------------------- PROC_KEY: JB K1,PROC_K1 ; 按键K1处理 CALL BEEP_BL JNB K1,$ MOV DPTR,#M_ALAX1 MOV A,#1 CALL LCD_PRINT CALL LOOK_ALARM JB K3,$ CALL BEEP_BL JMP PROC_K2 PROC_K1: ; 按键K2处理 JB K2,PROC_END CALL BEEP_BL JNB K2,$ MOV DPTR,#RESET_A1 MOV A,#1 CALL LCD_PRINT CALL SET_ALARM CALL RE_18B20 ;将设定的TH,TL值写入DS18B20内 CALL WRITE_E2 PROC_K2: CALL MENU_OK CALL TEMP_BJ PROC_END: RET ;============================================ ;设定报警值 TH、TL ;============================================ SET_ALARM: ;CALL RESET_ALARM CALL LOOK_ALARM AS0: JB K1,AS00 CALL BEEP_BL JNB K1,$ CPL 20H.1 ;UP/DOWN 标记 AS00: JB 20H.1,ASZ01 ;20H.1=1,UP JMP ASJ01 ;20H.1=0,DOWN ASZ01: JB K2,ASZ02 ;TH值调整(增加) CALL BEEP_BL INC TEMP_TH MOV A,TEMP_TH CJNE A,#120,ASZ011 MOV TEMP_TH,#0 ASZ011: CALL LOOK_ALARM MOV R5,#10 CALL DELAY JMP ASZ01 ASZ02: JB K3,ASZ03 ;TL值调整(增加) CALL BEEP_BL INC TEMP_TL MOV A,TEMP_TL CJNE A,#99,ASZ021 MOV TEMP_TL,#00H ASZ021: CALL LOOK_ALARM ; MOV R5,#10 CALL DELAY JMP ASZ02 ASZ03: JB K4,AS0 ;确定调整 OK CALL BEEP_BL JNB K4,$ RET ASJ01: JB K2,ASJ02 ;TH值调整 (减少) CALL BEEP_BL DEC TEMP_TH MOV A,TEMP_TH CJNE A,#0FFH,ASJ011 JMP ASJ022 ASJ011: CALL LOOK_ALARM MOV R5,#10 CALL DELAY JMP AS0 ASJ02: JB K3,ASJ03 ;TL值调整(减少) CALL BEEP_BL DEC TEMP_TL MOV A,TEMP_TL CJNE A,#0FFH,ASJ021 JMP ASJ022 ASJ021: CALL LOOK_ALARM ; MOV R5,#10 CALL DELAY JMP AS0 ASJ022: CPL 20H.1 JMP ASZ01 ASJ03: JMP ASZ03 RET RESET_ALARM: MOV DPTR,#RESET_A1 ;指针指到显示信息区 MOV A,#1 ;显示在第一行 CALL LCD_PRINT RET RESET_A1: DB "RESET ALERT CODE" ;==================================================== ;实际温度值与标记温度值比较子程序 ;==================================================== TEMP_COMP: MOV A,TEMP_TH SUBB A,TEMP_ZH ;减数>被减数,则 JC CHULI1 ;借位标志位C=1,转 MOV A,TEMP_ZH SUBB A,TEMP_TL ;减数>被减数,则 JC CHULI2 ;借位标志位C=1,转 MOV DPTR,#BJ5 CALL TEMP_BJ3 CLR RELAY ;
继电器吸合 RET CHULI1: MOV DPTR,#BJ3 CALL TEMP_BJ3 SETB RELAY ;继电器关闭 CALL BEEP_BL RET CHULI2: MOV DPTR,#BJ4 CALL TEMP_BJ3 CALL BEEP_BL RET ;----------------------------------------- TEMP_BJ3: MOV A,#0CEH CALL WCOM MOV R1,#0 MOV R0,#2 BBJJ3: MOV A,R1 MOVC A,@A+DPTR CALL WDATA INC R1 DJNZ R0,BBJJ3 RET BJ3: DB ">H" BJ4: DB "
BJ5: DB " !" ;================================================== ;显示温度标记子程序 ;================================================== TEMP_BJ: MOV A,#0CBH CALL WCOM MOV DPTR,#BJ1 ;指针指到显示消息 MOV R1,#0 MOV R0,#2 BBJJ1: MOV A,R1 MOVC A,@A+DPTR CALL WDATA INC R1 DJNZ R0,BBJJ1 RET BJ1: DB 00H,"C" ;================================================= MENU_OK: MOV DPTR,#M_OK1 ;指针指到显示消息 MOV A,#1 ;显示在第一行 CALL LCD_PRINT MOV DPTR,#M_OK2 ;指针指到显示消息 MOV A,#2 ;显示在第一行 CALL LCD_PRINT RET M_OK1: DB " DS18B20 OK ",0 M_OK2: DB " TEMP: ",0 ;----------------------------------------------- MENU_ERROR: MOV DPTR,#M_ERROR1 ;指针指到显示消息1 MOV A,#1 ;显示在第一行 CALL LCD_PRINT MOV DPTR,#M_ERROR2 ;指针指到显示消息1 MOV A,#2 ;显示在第一行 CALL LCD_PRINT RET M_ERROR1: DB " DS18B20 ERROR ",0 M_ERROR2: DB " TEMP: ---- ",0 ;==================================================== 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 tsr2: jnb date_line,tsr3 ;等待DS18B20回应 djnz r0,tsr2 jmp tsr4 ; 延时 tsr3: setb flag1 ; 置标志位,表示DS1820存在 jmp tsr5 tsr4: clr flag1 ; 清标志位,表示DS1820不存在 jmp tsr7 tsr5: mov r0,#06bh tsr6: djnz r0,$ ; 时序要求延时一段时间 tsr7: setb date_line ret ;======================================================= RE_18B20: JB FLAG1,RE_18B20A RET RE_18B20A: CALL RESET MOV A,#0CCH ;跳过ROM匹配 LCALL WRITE MOV A,#4EH ;写暂存寄存器 LCALL WRITE MOV A,TEMP_TH ;TH(报警上限) LCALL WRITE MOV A,TEMP_TL ;TL(报警下限) LCALL WRITE MOV A,#7FH ;12位精确度 LCALL WRITE RET ;------------------------------------------------------------ WRITE_E2: CALL RESET MOV A,#0CCH ;跳过ROM匹配 LCALL WRITE MOV A,#48H ;把暂存器里的温度报警值拷贝到EEROM LCALL WRITE RET ;-------------------------------------------------------------- READ_E2: CALL RESET MOV A,#0CCH ;跳过ROM匹配 LCALL WRITE MOV A,#0B8H ;把EEROM里的温度报警值拷贝回暂存器 CALL WRITE RET ;-------------------------------------------------------------- ;将自定义字符写入LCD1602的CGRAM中 ;-------------------------------------------------------------- STORE_DATA: MOV A,#40H CALL WCOM MOV R2,#08H MOV DPTR,#D_DATA MOV R3,#00H S_DATA: MOV A,R3 MOVC A,@A+DPTR CALL WDATA ;写入数据 INC R3 DJNZ R2,S_DATA RET D_DATA: DB 0CH,12H,12H,0CH,00H,00H,00H,00H ;============================================================== 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