设计要求:
数字温度计 设计一个具有特定功能的数字温度计。该数字温度计上电或按键复位后能自动显示系统提示符“P.”,进入准备工作状态。测量温度范围0℃~99℃,测量精度小数点后两位,可以通过开始和结束键控制数字温度计的工作状态。
下面是我的仿真图和汇编程序,但是我的程序只能精确到小数点后一位(0.1),而且不能显示系统提示符“P.”
程序如下:
|
- ;================================================================
- ;DS18B20温度计
- ;采用4位LED共阳显示器显示测温值,显示精度0.1℃,测温范围-55~+125℃
- ;用AT89C51单片机,12MHz晶振
- ;============================常数定义=============================
- TIMEL EQU 0E0H ;20ms,定时器0时间常数
- TIMEH EQU 0B1H
- TEMPHEAD EQU 36H
- ;==========================工作内存定义============================
- BITST DATA 20H
- TIME1SOK BIT BITST.1
- TEMPONEOK BIT BITST.2
- TEMPL DATA 26H
- TEMPH DATA 27H
- TEMPHC DATA 28H
- TEMPLC DATA 29H
- ;============================= 引脚定义===========================
- TEMPDIN BIT P3.7
- ;============================= 中断向量区=========================
- ORG 0000H
- LJMP START
- ORG 00BH
- LJMP T0IT
- ;=============================系统初始化==========================
- ORG 100H
- START: MOV SP,#60H
- CLSMEM: MOV R0,#20H
- MOV R1,#60H
- CLSMEM1: MOV @R0,#00H
- INC R0
- DJNZ R1,CLSMEM1
- MOV TMOD,#00100001B ;定时器0工作方式1(16BIT)
- MOV TH0,#TIMEL
- MOV TL0,#TIMEH ;20ms
- SJMP INIT
- ERROR: NOP
- LJMP START
- NOP
- INIT: NOP
- SETB ET0
- SETB TR0
- SETB EA
- MOV PSW,#00H
- CLR TEMPONEOK
- LJMP MAIN
- ;====================== 定时器0中断服务程序=======================
- T0IT: PUSH PSW
- MOV PSW,#10H
- MOV TH0,#TIMEH
- MOV TL0,#TIMEL
- INC R7
- CJNE R7,#32H,T0IT1
- MOV R7,#00H
- SETB TIME1SOK ;1s定时到标志
- T0IT1: POP PSW
- RETI
- ;============================= 主程序=============================
- MAIN: LCALL DISP1 ;调用显示子程序
- JNB TIME1SOK,MAIN
- CLR TIME1SOK ;测温每1s一次
- JNB TEMPONEOK,MAIN2 ;上电时先温度转换一次
- LCALL READTEMP1 ;读出温度值子程序
- LCALL CONVTEMP ;温度BCD码计算处理子程序
- LCALL DISPBCD ;显示区BCD码温度值刷新子程序
- LCALL DISP1 ;消闪烁,显示一次
- MAIN2: LCALL READTEMP ;温度转换开始
- SETB TEMPONEOK
- LJMP MAIN
- ;============================= 子程序区===========================
- ;RESET DS18B20
- ;================================================================
- INITDS1820:SETB TEMPDIN
- NOP
- NOP
- CLR TEMPDIN
- MOV R6,#0A0H ;DELAY 480us
- DJNZ R6,$
- MOV R6,#0A0H
- DJNZ R6,$
- SETB TEMPDIN
- MOV R6,#32H ;DELAY 70us
- DJNZ R6,$
- MOV R6,#3CH
- LOOP1820: MOV C,TEMPDIN
- JC INITDS1820OUT
- DJNZ R6,LOOP1820
- MOV R6,#064H
- DJNZ R6,$
- SJMP INITDS1820
- RET
- INITDS1820OUT: SETB TEMPDIN
- RET
- ;====== 读DS18B20的程序,从DS18B20中读出一个字节的数据=============
- READDS1820: MOV R7,#08H
- SETB TEMPDIN
- NOP
- NOP
- READDS1820LOOP: CLR TEMPDIN
- NOP
- NOP
- NOP
- SETB TEMPDIN
- MOV R6,#07H ;DELAY 15us
- DJNZ R6,$
- MOV C,TEMPDIN
- MOV R6,#3CH ;DELAY 120us
- DJNZ R6,$
- RRC A
- SETB TEMPDIN
- DJNZ R7,READDS1820LOOP
- MOV R6,#3CH ;DELAY 120 us
- DJNZ R6,$
- RET
- ;======== 写DS18B20的程序,从DS18B20中写一个字节的数据=============
- WRITEDS1820: MOV R7,#08H
- SETB TEMPDIN
- NOP
- NOP
- WRITEDS1820LOP: CLR TEMPDIN
- MOV R6,#07H ;DELAY 15us
- DJNZ R6,$
- RRC A
- MOV TEMPDIN,C
- MOV R6,#34H ;DELAY 104us
- DJNZ R6,$
- SETB TEMPDIN
- DJNZ R7,WRITEDS1820LOP
- RET
- ;========================= READ TEMP ===========================
- READTEMP: LCALL INITDS1820
- MOV A,#0CCH
- LCALL WRITEDS1820 ;SKIP ROM
- MOV R6,#34H ;DELAY 104us
- DJNZ R6,$
- MOV A,#44H
- LCALL WRITEDS1820 ;START CONVERSION
- MOV R6,#34H ;DELAY 104
- DJNZ R6,$
- RET
- READTEMP1: LCALL INITDS1820
- MOV A,#0CCH
- LCALL WRITEDS1820 ;SKIP ROM
- MOV R6,#34H ;DELAY 104us
- DJNZ R6,$
- MOV A,#0BEH
- LCALL WRITEDS1820 ;SCRATCHPAD
- MOV R6,#34H ;DELAY 104us
- DJNZ R6,$
- MOV R5,#09H
- MOV R0,#TEMPHEAD
- MOV B,#00H
- READTEMP2: LCALL READDS1820
- MOV @R0,A
- INC R0
- READTEMP21: LCALL CRC8CAL
- DJNZ R5,READTEMP2
- MOV A,B
- JNZ READTEMPOUT
- MOV A,TEMPHEAD+0
- MOV TEMPL,A
- MOV A,TEMPHEAD+1
- MOV TEMPH,A
- READTEMPOUT: RET
- ;================== 处理温度BCD码子程序==========================
- CONVTEMP: MOV A,TEMPH
- ANL A,#80H
- JZ TEMPC1
- CLR C
- MOV A,TEMPL
- CPL A
- ADD A,#01H
- MOV TEMPL,A
- MOV A,TEMPH ;-
- CPL A
- ADDC A,#00H
- MOV TEMPH,A ;TEMPHC HI=符号位
- MOV TEMPHC,#0BH
- 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
- 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,R7
- JZ TEMPC12
- ANL A,#0FH
- SWAP A
- MOV R7,A
- MOV A,TEMPHC ;TEMPLC HI=百位数BCD
- ANL A,#0FH
- ORL A,R7
- MOV TEMPHC,A
- TEMPC12: RET
- ;========================= 小数部分码表===========================
- TEMPDOTTAB: DB 00H,01H,01H,02H,03H,03H,04H,04H,05H,06H
- DB 06H,07H,08H,08H,09H,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
- ;======================= 显示子程序===============================
- ;显示数据在70H~73H单元内,用4位LED共阳数码管显示,P1口输出段码数据,
- ;P3口做扫描控制,每个LED数码管亮1ms时间再逐位循环。
- DISP1: MOV R1,#70H ;指向显示数据首址
- MOV R5,#0FEH ;扫描控制字初值
- PLAY: MOV P0,#0FFH
- MOV A,R5 ;扫描字放入A
- MOV P3,A ;从P3口输出
- MOV A,@R1 ;取显示数据到A
- MOV DPTR,#TAB ;取段码表地址
- MOVC A,@A+DPTR ;查显示数据对应段码
- MOV P0,A ;段码放入P0口
- MOV A,R5
- JB ACC.1,LOOP5 ;小数点处理
- CLR P0.7
- LOOP5: LCALL DL1MS ;显示1ms
- INC R1 ;指向下一地址
- MOV A,R5 ;扫描控制字放入A
- JNB ACC.3,ENDOUT ;ACC.3=0时一次显示结束
- RL A ;A中数据循环左移
- MOV R5,A ;放回R5内
- AJMP PLAY ;跳回PLAY循环
- ENDOUT: MOV P0,#0FFH ;一次显示结束,P0口复位
- MOV P3,#0FFH ;P3口复位
- RET ;子程序返回
- TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH,0BFH
- ;共阳段码表 “0”“1”“2”“3”“4”“5”“6”“7”“8”“9”“不亮”“-”
- DL1MS: MOV R6,#14H ;1ms延时程序,LED显示程序用
- DL1: MOV R7,#19H
- DL2: DJNZ R7,DL2
- DJNZ R6,DL1
- RET
- ;===================== 单字节十六进制转BCD =======================
- HEX2BCD1: MOV B,#064H ;十六进制->BCD
- DIV AB ;B=A%100
- MOV R7,A ;R7=百位数
- MOV A,#0AH
- XCH A,B
- DIV AB ;B=A%B
- SWAP A
- ORL A,B
- RET
- ;================================================================
- ;Calculate CRC-8Values. Uses The CCITT-8Polynomial,Expressed As
- ;X^8+X^5+X^4+1
- ;================================================================
- CRC8CAL: PUSH ACC
- MOV R7,#08H ;Number Bits In Byte
- CRC8LOOP1: XRL A,B ;Calculte CRC
- RRC A ;Move To Carry
- MOV A,B ;Get The Last CRC Value
- JNC CRC8LOOP2 ;Skip If Data==0
- XRL A,#18H ;Updata The New CRC
- CRC8LOOP2: RRC A ;Position The New CRC
- MOV B,A ;Store The New CRC
- POP ACC ;Get The Remaining Bits
- RR A ;Position The Next Bit
- PUSH ACC ;Save The Remaining Bits
- DJNZ R7,CRC8LOOP1 ;Repeat For 8 Bits
- POP ACC
- RET
- END
复制代码
|