今天做了一个十分简单的系统,AT89C52和DS18B20以及数码管组成的温度检测系统,因为闲的实在无聊了;本来是要做PWM的,但是因为对PWM一点都不了解,哪怕是最基础的都不知道,也就是前几天才知道PWM的汉语全称是脉宽调制的意思。为了让今天的我有点成就感于是就促成了这么一个下系统的诞生程序是从网上下的当然自己也是要改的,要不然真能锻炼自己呢。该系统可以实现从0---128C的显示,不过呢由于还是个菜鸟,有一点问题还是没能解决希望高手指点,就是十位数是2、5、6时右竖段会有闪动。
程序如下:
ORG 0000H
TEMPER_L EQU 029H ;用于保存读出温度的低8位
TEMPER_H EQU 028H ;用于保存读出温度的高8位
FLAG1 EQU 038H ;是否检测到DS18B20标志位
A_BIT EQU 020H ;数码管个位数存放内存位置
B_BIT EQU 021H ;数码管十位数存放内存位置
C_BIT EQU 022H ;数码管佰位数存放内存位置
P0 EQU 080H
P2 EQU 0A0H
B EQU 0F0H
MAIN:
LCALL GET_TEMPER ;调用读温度子程序
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
LCALL DISPLAY ;调用数码管显示子程序
AJMP MAIN
INIT_1820: ;这是DS18B20复位初始化子程序
SETB P2.1
NOP
CLR P2.1 ;主机发出延时537微秒的复位低脉冲
MOV R1,#3
TSR1:
MOV R0,#107
DJNZ R0,$
DJNZ R1,TSR1
SETB P2.1 ;然后拉高数据线
NOP
NOP
NOP
MOV R0,#25H
TSR2:
JNB P2.1,TSR3 ;等待DS18B20回应
DJNZ R0,TSR2
LJMP TSR4 ;延时
TSR3:
SETB FLAG1 ;置标志位,表示DS1820存在
LJMP TSR5
TSR4:
CLR FLAG1 ;清标志位,表示DS1820不存在
LJMP TSR7
TSR5:
MOV R0,#117
TSR6:
DJNZ R0,TSR6 ;时序要求延时一段时间
TSR7:
SETB P2.1
RET
GET_TEMPER:
SETB P2.1 ;读出转换后的温度值
LCALL INIT_1820 ;先复位DS18B20
JB FLAG1,TSS2 ;判断DS1820是否存在?若不存在则返回
NOP
RET
TSS2: ;DS18B20已经被检测到!
MOV A,#0CCH ;跳过ROM匹配
LCALL WRITE_1820
MOV A,#44H ;发出温度转换命令
LCALL WRITE_1820
LCALL DISPLAY ;通过调用显示子程序实现延时 LCALL INIT_1820 ;准备读温度前先复位
MOV A,#0CCH ;跳过ROM匹配
LCALL WRITE_1820
MOV A,#0BEH ;发出读温度命令
LCALL WRITE_1820
LCALL READ_18200 ;将读出的温度数据保存到35H/36H
RET
WRITE_1820: ;写DS1820的子程序(有具体的时序要求)
MOV R2,#8 ;一共8位数据
CLR C
WR1:
CLR P2.1
MOV R3,#6
DJNZ R3,$
RRC A
MOV P2.1,C
MOV R3,#23
DJNZ R3,$
SETB P2.1
NOP
DJNZ R2,WR1
SETB P2.1
RET
READ_18200: ;读DS18B20的程序
MOV R4,#2 ;将温度高位和低位从DS18B20中读出
MOV R1,#29H ;低位存入29H,高位存入28H
RE00:
MOV R2,#8 ;数据一共有8位
RE01:
CLR C
SETB P2.1
NOP
NOP
CLR P2.1
NOP
NOP
NOP
SETB P2.1
MOV R3,#9
RE10:
DJNZ R3,RE10
MOV C,P2.1
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 B,#100 ;10进制/10=10进制
DIV AB
MOV B_BIT,A ;佰位在B_BIT
MOV A,B
MOV B,#10
DIV AB
MOV C_BIT,A ;十位在C_BIT
MOV A_BIT,B ;个位在A_BIT
MOV DPTR,#TAB ;指定查表启始地址
MOV R0,#4
DPL1:
MOV R1,#150 ;显示1000次
DPLOP:
MOV A,#0CH ;温度单位显示C
MOVC A,@A+DPTR ;查个位数的7段代码
MOV P0,A ;送出个位的7段代码
MOV P2,#8FH
SETB P2.7 ;温度单位显示
ACALL D1MS ;显示1ms
CLR P2.7
JB FLAG1,X1
MOV A,#12H
AJMP X2
X1:
MOV A,A_BIT ;取十位数
X2:
MOVC A,@A+DPTR ;查十位数的7段代码
MOV P0,A ;送出十位的7段代码
MOV P2,#4FH
SETB P2.6 ;开十位显示
ACALL D1MS ;显示1ms
CLR P2.6
JB FLAG1,X3
MOV A,#12H
AJMP X4
X3:
MOV A,C_BIT ;取十位数
X4:
MOVC A,@A+DPTR ;查十位数的7段代码
MOV P0,A ;送出十位的7段代码
MOV P2,#4FH
SETB P2.5 ;开十位显示
ACALL D1MS ;显示1ms
CLR P2.5
JB FLAG1,X5
MOV A,#12H
AJMP X6
X5:
MOV A,B_BIT ;取佰位数
X6:
MOVC A,@A+DPTR ;查佰位数的7段代码
MOV P0,A ;送出佰位的7段代码
MOV P2,#2FH
SETB P2.4 ;开佰位显示
ACALL D1MS ;显示1ms
CLR P2.4
MOV A,#11H ;显示-
MOVC A,@A+DPTR ;
MOV P0,A ;
MOV P2,#1FH
SETB P2.3 ;
ACALL D1MS ;显示1ms
CLR P2.3
MOV A,#11H ;显示-
MOVC A,@A+DPTR ;
MOV P0,A ;
SETB P2.3 ;
ACALL D1MS ;显示1ms
CLR P2.3
JB FLAG1,X6 ;判断DS1820是否存在?若DS18B20不存在显示0 存在显示1
MOV A,#00H
AJMP X8
X7:
MOV A,#01H
X8:
MOVC A,@A+DPTR ;
MOV P0,A ;
CLR P2.2 ;
ACALL D1MS ;显示1ms
SETB P2.2
DJNZ R1,DPLOP ;100次没完循环
DJNZ R0,DPL1 ;4个100次没完循环
RET
D1MS: ;1MS延时(按12MHZ算)
MOV R7,#160
DJNZ R7,$
RET
TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,88H,83H,0C6H,0A1H,86H,8EH,89H,0BFH,0FFH
;0 1 2 3 4 5 6 7 8 9 A B C D E F H - 消隐码
END