📄 read-ds18b20-lcd1602.asm
字号:
;******************************************************************
;* *
;* DS18B20-64位序列码读取程序 *
;* *
;* 版本: V1.0 (2006/11/20) *
;* 作者: gguoqing (Email: gguoqing@willar.com) *
;* 网站: www.willar.com(伟纳电子) www.mcusj.com(伟纳单片机世界)*
;* 邮箱: support@willar.com *
;* *
;*【版权】COPYRIGHT(C)伟纳电子 www.willar.com ALL RIGHTS RESERVED *
;*【声明】此程序仅用于学习与参考,引用请注明版权和作者信息! *
;* *
;******************************************************************
RELAY EQU P1.3
BEEP EQU P3.7
DATE_LINE EQU P3.3 ;DS18B20 数据线
;--------------------------------------------------------------
LCD_RS EQU P2.0
LCD_RW EQU P2.1
LCD_EN EQU P2.2
LCD_X EQU 26H ;LCD 地址变量
FLAG1 EQU 20H.0 ;DS18B20是否存在标记
;--------------------------------------------------------------
ORG 0000H
JMP MAIN
ORG 0030H
;--------------------------------------------------------------
MAIN: MOV SP,#30H
CLR LCD_EN
ACALL SET_LCD
MOV R5,#100
MAIN1:
ACALL DELAY50ms
DJNZ R5,MAIN1
START:
ACALL RESET ;18B20复位子程序
JNB FLAG1,START4 ;DS1820不存在
CALL MENU_OK ;
MOV A,#33H
LCALL WRITE ;送入读ds1820的ROM命令
LCALL READ ;开始读出当前ds1820序列号
MOV R1,#40H
MOV R5,#08H
MOV B,#00H
START1: ;CRC 效验
MOV A,@R1
INC R1
LCALL CRC8
DJNZ R5,START1
MOV A,B ;B=0,效验成功
JNZ START6
CALL BEEP_BL
MOV LCD_X,#00H ;设置显示起始位置
MOV R1,#40H
MOV R5,#08H
START2:
LCALL CONV
INC R1
INC LCD_X
DJNZ R5,START2
START3:
ACALL RESET ;18B20复位子程序
JNB FLAG1,START4
JMP START3
START4:
ACALL MENU_ERROR ;
START5:
ACALL RESET ;18B20复位子程序
JB FLAG1,START
ACALL BEEP_BL ;DS1820不正常时,报警。
JMP START5
START6:
ACALL MENU1
ACALL BEEP_BL
JMP START
;====================================================
;DS18B20 复位与检测子程序
;DS18B20 正常 FLAG1 置 1,不正常 FLAG1 置 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
;------------------------------------------------------------------
;DS18B20 写命令、数据子程序
;根据命令的内容,进行写操作
;------------------------------------------------------------------
WRITE:
MOV R2,#8 ;8位数据长度
CLR C
WR1:
CLR DATE_LINE ;开始写入DS18B20总线要处于复位(低)状态
MOV R3,#08
DJNZ R3,$ ;总线复位保持16微妙以上
RRC A ;把一个字节DATA 分成8个BIT环移给C
MOV DATE_LINE,C ;写入一个BIT
MOV R3,#3CH
DJNZ R3,$ ;等待120微妙
SETB DATE_LINE ;重新释放总线
NOP
DJNZ R2,WR1 ;写入下一个BIT
SETB DATE_LINE
RET
;--------------------------------------------------------------------
;DS18B20 读子程序
;--------------------------------------------------------------------
READ:
MOV R4,#8 ;存入8个单元中
MOV R1,#40H ;存入单元的首地址送入 R1
RE00: MOV R2,#8 ;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
;-----------------------------------------------------
; LCD 初始化设置
;-----------------------------------------------------
SET_LCD:
CLR LCD_EN
CALL INIT_LCD ;初始化 LCD
CALL DELAY5ms
MOV DPTR,#INFO1 ;指针指到显示信息1
MOV A,#1 ;显示在第一行
CALL LCD_SHOW
MOV DPTR,#INFO2 ;指针指到显示信息2
MOV A,#2 ;显示在第二行
CALL LCD_SHOW
RET
;-----------------------------------------------------
INIT_LCD: ;8位I/O控制 LCD 接口初始化
MOV A,#38H ;双列显示,字形5*7点阵
CALL WCOM
CALL DELAY5ms
MOV A,#38H ;双列显示,字形5*7点阵
CALL WCOM
CALL DELAY5ms
MOV A,#38H ;双列显示,字形5*7点阵
CALL WCOM
CALL DELAY5ms
MOV A,#0CH ;开显示,关光标,
CALL WCOM
CALL DELAY5ms
MOV A,#01H ;清除 LCD 显示屏
CALL WCOM
CALL DELAY5ms
RET
;----------------------------------------------------
LCD_SHOW: ;在LCD的第一行或第二行显示信息字符
CJNE A,#1,LINE2 ;判断是否为第一行
LINE1: MOV A,#80H ;设置 LCD 的第一行地址
CALL WCOM ;写入命令
CALL CLR_LINE ;清除该行字符数据
MOV A,#80H ;设置 LCD 的第一行地址
CALL WCOM ;写入命令
JMP FILL
LINE2: MOV A,#0C0H ;设置 LCD 的第二行地址
CALL WCOM ;写入命令
CALL CLR_LINE ;清除该行字符数据
MOV A,#0C0H ;设置 LCD 的第二行地址
CALL WCOM
FILL: CLR A ;填入字符
MOVC A,@A+DPTR ;由信息区取出字符
CJNE A,#0,LC1 ;判断是否为结束码
RET
LC1: CALL WDATA ;写入数据
INC DPTR ;指针加1
JMP FILL ;继续填入字符
RET
;---------------------------------------------------
CLR_LINE: ;清除该行 LCD 的字符
MOV R0,#24
CL1: MOV A,#' '
CALL WDATA
DJNZ R0,CL1
RET
;----------------------------------------------------
MENU1: ;LCD 显示工作菜单信息
MOV DPTR,#MENU2
MOV A,#2 ;在第二行显示信息
CALL LCD_SHOW
RET
MENU2: DB " CRC ERROR ",0
;-----------------------------------------------------
INFO1: DB " READ DS18B20 ",0 ;LCD 第一行显示信息
INFO2: DB " SERIAL NUMBERS ",0 ;LCD 第二行显示信息
;-----------------------------------------------------
;-----------------------------------------------------
; 写指令、数据使能子程序
;-----------------------------------------------------
WCOM: ;写指令使能
MOV P0,A
CLR LCD_RS ;RS=L,RW=L,D0-D7=指令码,E=高脉冲
CLR LCD_RW
SETB LCD_EN
CALL DELAY0
CLR LCD_EN
RET
WDATA: ;写数据使能
MOV P0,A
SETB LCD_RS ;RS=H,RW=L,D0-D7=数据,E=高脉冲
CLR LCD_RW
SETB LCD_EN
CALL DELAY0
CLR LCD_EN
RET
DELAY0: MOV R7,#250 ;延时500微秒
DJNZ R7,$
RET
;---------------------------------------------------
;在 LCD 第二行显示字符
;A=ASC DATA, B=LINE X POS
;---------------------------------------------------
LCDP2: ;在LCD的第二行显示字符
PUSH ACC ;
MOV A,B ;设置显示地址
ADD A,#0C0H ;设置LCD的第二行地址
CALL WCOM ;写入命令
POP ACC ;由堆栈取出A
CALL WDATA ;写入数据
RET
CONV:
; MOV LCD_X,#00H ;设置显示起始位置
MOV A,@R1
ANL A,#0F0H ;取出高四位二进制数
SWAP A ;高四位与低四位互换
PUSH ACC ;压入堆栈
CLR C ;C=0
SUBB A,#0AH ;减10
POP ACC ;弹出堆栈
JC ASCII0 ;该数小于10,转ASCII0
ADD A,#07H ;大于10的数加上37H
ASCII0: ADD A,#30H ;小于10的数加上30H
MOV B,LCD_X
CALL LCDP2
MOV A,@R1
ANL A,#0FH ;取出低四位二进制数
PUSH ACC
CLR C
SUBB A,#0AH ;减10
POP ACC
JC ASCII1 ;该数小于10,转ASCII0
ADD A,#07H ;大于10的数加上37H
ASCII1: ADD A,#30H ;小于10的数加上30H
INC LCD_X
MOV B,LCD_X
CALL LCDP2
RET
;=================================================
MENU_OK:
MOV DPTR,#M_OK1 ;指针指到显示信息区
MOV A,#1 ;显示在第一行
CALL LCD_SHOW
MOV DPTR,#M_OK2 ;指针指到显示信息区
MOV A,#2 ;显示在第二行
CALL LCD_SHOW
RET
M_OK1:
DB " DS18B20 OK ",0
M_OK2:
DB " ",0
;-----------------------------------------------
MENU_ERROR:
MOV DPTR,#M_ERROR1 ;指针指到显示信息区
MOV A,#1 ;显示在第一行
CALL LCD_SHOW
MOV DPTR,#M_ERROR2 ;指针指到显示信息区
MOV A,#2 ;显示在第二行
CALL LCD_SHOW
RET
;----------------------------------------------------
M_ERROR1:
DB " DS18B20 ERROR ",0
M_ERROR2:
DB " CHECK DS18B20 ",0
;--------------------------------------------------------
;蜂鸣器响一声子程序
;--------------------------------------------------------
BEEP_BL:
MOV R6,#100
BL1: CALL DEX1
CPL BEEP
DJNZ R6,BL1
; MOV R5,#50
; CALL DELAY
RET
DEX1: MOV R7,#180
DEX2: NOP
DJNZ R7,DEX2
RET
DELAY: ;延时R5×10MS
MOV R6,#50
D1: MOV R7,#100
DJNZ R7,$
DJNZ R6,D1
DJNZ R5,DELAY
RET
;-----------------------------------------------------
DELAY5ms: ;延时5MS
MOV R6,#25
D2: MOV R7,#100
DJNZ R7,$
DJNZ R6,D2
RET
;-----------------------------------------------------
DELAY50ms: ;延时50MS
MOV R6,#250
D3: MOV R7,#100
DJNZ R7,$
DJNZ R6,D3
RET
;-----------------------------------------------------
CRC8:
PUSH ACC ;移位前保存数据
MOV R7,#08H ;设置循环次数
CRC8LOOP1:
XRL A,B ;计算CRC
RRC A ;移入进位位C中
MOV A,B ;读取上次计算的CRC值
JNC CRC8LOOP2 ;C为0跳转
XRL A,#18H ;与生成器的第4、5位异或
CRC8LOOP2:
RRC A ;
MOV B,A ;保存新的CRC值
POP ACC ;读取剩余位
RR A ;置下一位于LSB
PUSH ACC ;保存剩余位
DJNZ R7,CRC8LOOP1 ;循环8次
POP ACC ;清楚堆栈
RET
;-----------------------------------------------------
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -