资源描述
大连理工单片机课程设计
47
2020年4月19日
文档仅供参考
大连理工大学本科设计报告
题目:基于DS18B20、ZLG7290的温度 采集系统设计
课程名称: 单片机综合设计实验
学院(系): 信息与通信工程学院
专 业: 电子信息工程
班 级: 电子
学 号:
学生姓名:
成 绩:
20 16 年 5 月 6 日
题目:
1 设计要求
1.利用DS18B20实现现场环境温度的采集;
2.利用ZLG7290B实现温度数据证书的十进制显示;
3.默认一个上限温度的报警(蜂鸣器);
4.能够利用ZLG7290B的键盘操作修改“上限报警值”;
5.能够显示温度的小数位,以提高温度检测的分辨率;
6.程序中必须有中断环节。
2 设计分析及系统方案设计
利用P3.3口采集DS18B20的温度信息,采集后,经过I2C协议控制ZLG7290显示温度信息,而且将小数部分显示出来,经过P1.3连接一个拨码用来做模式控制,控制是温度显示状态模式或者设定温度上限模式,其中温度上限存放在28H单元中。
利用T0定时器控制蜂鸣器发声一段时间,超过温度上限报警声音提示,同时数码管进行闪烁以报警。
利用INT0外部中断读取按键值,用于设定上限温度并保存。
3 系统电路图
P1.3
P1.3
P1.2
5 主程序中主要变量说明
内存单元的定义、功能等。
变量名称
内存单元
功能
TEMPER_L
36H
存放温度低四位
TEMPER_H
35H
存放温度高四位
TEMPER
34H
转换后的温度值
TEMPER_BCD
33H
BCD形式温度值
TEMPER_NUM
60H
温度值缓冲单元
WSLA_7290
70H
7290写控制单元
RSLA_7290
71H
7290读控制单元
20-27H
数码管显示缓冲区
28H
存放温度上限值
30-31H
存放温度BCD码个位十位
6 系统软件中各个子程序的功能描述
子程序的名称、功能,以及入口、出口参数。
子程序名称
功能 描述
GET_TEMPER
读取18B20的温度值
WRITE_1820
向18b20写控制字
READ_18200
向18b20读控制字
TEMPER_COV
温度转换成十进制BCD码形式
CF
拆分子程序,拆分送数码管显示
INIT_1820
温度传感器初始化
BUZZER
蜂鸣器控制发声子程序
INT_7290:
读取按键外部中断子程序
RDKEY
读取键值子程序
DELAY
延时子程序
7 主程序程序流程图
8 程序清单(I2C库函数省略)
SDA BIT P1.0
SCL BIT P1.1
TEMPER_L EQU 36H
TEMPER_H EQU 35H
TEMPER EQU 34H ;转换后温度值
TEMPER_BCD EQU 33H ;BCD码温度值
TEMPER_NUM EQU 60H ;缓冲单元
WSLA_7290 EQU 70H
RSLA_7290 EQU 71H
FLAG1 BIT 00H
DQ BIT P3.3 ;总线控制单元
ORG 0000H
LJMP MAIN
ORG 0003H
LJMP INT_7290
ORG 0100H
MAIN: MOV SP,#70H
;ZLG7290复位
CLR P1.7
LCALL DELAY
SETB P1.7
MOV 28H,#1EH ;温度上限初始值30度
MOV TMOD,#01H ;模式一,16位计数器
SETB EA ;允许中断
MODE: JB P1.3,SETTMP ;拨码为0时采集温度
;温度采集
TMP: CLR EX0
MOV 27H,#1FH ;t
LP1: LCALL GET_TEMPER
LCALL TEMPER_COV
;7290显示
MOV R7,#08H
MOV R0,#20H
MOV R2,#10H
MOV R3,#WSLA_7290
LCALL WRNBYT
LCALL DELAY
MOV A,TEMPER
;判断温度上限
MOV 28H,R5
CLR C
CJNE A,28H,rel ;此处报警温度为30度
rel:
JC NET
LCALL BUZZER ;大于等于时蜂鸣器报警
;闪烁
MOV 28H,#70H ;闪烁命令字
MOV 29H,#7FH ;闪烁命令字
MOV R7,#02H ;设定数据个数
MOV R0,#28H ;设置源数据首地址
MOV R2,#07H ;设置外围器件内部寄存器首地址
MOV R3,#WSLA_7290 ;设定外围器件地址
LCALL WRNBYT ;调用显示子程序
LCALL DELAY
LJMP NEXTT
;设定温度上限
SETTMP:
SETB EX0
;7290复位
CLR P1.7
LCALL DELAY
SETB P1.7
;显示设定内容
MOV 27H,#0B6H ;S
MOV 26H,#9EH ;E
MOV 25H,#1FH ;T.
MOV R7,#03H
MOV R0,#25H
MOV R2,#15H
MOV R3,#WSLA_7290
LCALL WRNBYT
LCALL DELAY
SJMP NEXTT
NET: MOV 28H,#70H ;不能闪烁
MOV 29H,#00H
MOV R7,#02H
MOV R0,#28H
MOV R2,#07H
MOV R3,#WSLA_7290
LCALL WRNBYT
LCALL DELAY
NEXTT: CALL DELAY
SJMP MODE
GET_TEMPER:
SETB DQ ;定时入口
BCD: LCALL INIT_1820
JB FLAG1,S22
LJMP BCD ;若ds18b20不存在则返回
S22: LCALL DELAY1
MOV A,#0CCH ;跳过rom匹配0cch
LCALL WRITE_1820
MOV A,#44H ;发出温度转换命令
LCALL WRITE_1820
LCALL DELAY
CBA: LCALL INIT_1820
JB FLAG1,ABC
LJMP CBA
ABC: LCALL DELAY1
MOV A,#0CCH ;跳过rom匹配
LCALL WRITE_1820
MOV A,#0BEH ;发出读温度命令
LCALL WRITE_1820
LCALL READ_18200
RET
WRITE_1820: ;写ds18b20程序
MOV R2,#8
CLR C
WR1: CLR DQ
MOV R3,#6 ;延时24us
DJNZ R3,$
RRC A
MOV DQ,C
MOV R3,#23 ;延时60us
DJNZ R3,$
SETB DQ
NOP
DJNZ R2,WR1
SETB DQ
RET
READ_18200: ;从1820中读出两个字节温度数据
PUSH 01H
MOV R4,#2
MOV R1,#36H
RE00: MOV R2,#8
RE01: CLR C
SETB DQ
NOP
CLR DQ
NOP
NOP
SETB DQ
MOV R3,#2
DJNZ R3,$
MOV C,DQ
MOV R3,#23H
DJNZ R3,$
RRC A
DJNZ R2,RE01
MOV @R1,A
DEC R1
DJNZ R4,RE00
POP 01H
RET
TEMPER_COV: ;将读出的数据转换
PUSH DPH
PUSH DPL
PUSH 02H
MOV A,#0F0H
ANL A,TEMPER_L ;舍去小数点后的四位
SWAP A
MOV TEMPER_NUM,A
MOV A,TEMPER_H
ANL A,#07H
SWAP A
ADD A,TEMPER_NUM
MOV TEMPER,A
;转换成十进制数显示
MOV B,#10
DIV AB
MOV 30H,B ;个位
MOV B,#10
DIV AB
MOV 31H,B ;十位
ANL A,#0FH ;百位
SWAP A
ADD A,B
MOV TEMPER_BCD,A
LCALL CF2 ;拆分查表
MOV 25H,R3
MOV 26H,R4
MOV A,30H
ANL A,#0FH
LCALL CF
MOV 24H,R3
;处理四位小数位数据
MOV A,TEMPER_L
ANL A,#0FH ;取低四位数据
MOV B,#02H
MUL AB
MOV DPTR,#NUMSEG
MOVC A,@A+DPTR
MOV TEMPER_BCD,A
LCALL CF2
MOV 22H,R3
MOV 23H,R4
MOV A,TEMPER_L
ANL A,#0FH
MOV B,#02H
MUL AB
INC A
MOVC A,@A+DPTR
MOV TEMPER_BCD,A
LCALL CF2
MOV 20H,R3
MOV 21H,R4
POP 02H
POP DPL
POP DPH
RET
;--------------小数部分查表------------------------
NUMSEG: DW 0000H,0625H,1250H,1875H,2500H,3125H,3750H,4375H
DW 5000H,5625H,6250H,6875H,7500H,8125H,8750H,9375H
;--------------------------------------------------
;--------------拆分显示整数子程序------------------
CF: PUSH 02H
PUSH DPH
PUSH DPL
MOV DPTR,#LEDSEG
MOV R2,TEMPER_BCD
ANL A,#0FH
MOVC A,@A+DPTR
MOV R3,A
MOV A,R2
SWAP A
ANL A,#0FH
MOVC A,@A+DPTR
MOV R4,A
INC R3 ;加上小数点
POP DPL
POP DPH
POP 02H
RET
;-----------------------------------------------
;--------------拆分显示小数子程序------------------
CF2: PUSH 02H
PUSH DPH
PUSH DPL
PUSH ACC
MOV DPTR,#LEDSEG
MOV R2,TEMPER_BCD
MOV A,R2
ANL A,#0FH
MOVC A,@A+DPTR
MOV R3,A
MOV A,R2
SWAP A
ANL A,#0FH
MOVC A,@A+DPTR
MOV R4,A
;加上小数点
POP ACC
POP DPL
POP DPH
POP 02H
RET
;-----------------------------------------------
;-----------------led字型码---------------------
LEDSEG: DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E4H
DB 0FEH,0F6H,0EEH,3EH,9CH,7AH,9EH,8EH
;-----------------------------------------------
INIT_1820:
SETB DQ
NOP
CLR DQ
MOV R0,#80H
TSR1: DJNZ R0,TSR1 ;延时300us
SETB DQ
MOV R0,#25H ;96us
TSR2: DJNZ R0,TSR2
JNB DQ,TSR3
LJMP TSR4 ;延时
TSR3: SETB FLAG1 ;致标志位
LJMP TSR5 ;ds18b20存在
TSR4: CLR FLAG1 ;清标志位
LJMP TSR7 ;ds18b20不存在
TSR5: MOV R0,#06BH ;延时200us
TSR6: DJNZ R0,TSR6
TSR7: SETB DQ
RET
DELAY1: MOV R7,#20H ;80us延时
DJNZ R7,$
RET
;---------------蜂鸣器驱动子程序--------------
BUZZER:
PUSH 07H
MOV R7,#00H
MOV TL0,#33H ;设置定时0.5us初值
MOV TH0,#0FEH
SETB TR0 ;启动t0
WAIT: JNB TF0,$
CLR TF0
MOV TL0,#33H
MOV TH0,#0FEH
CPL P1.2
DJNZ R7,WAIT
CLR TR0
SETB P1.2
POP 07H
RET
;---------------------------------------------
;-------------外部中断服务程序----------------
INT_7290:
PUSH 00H
PUSH 01H
PUSH 02H
PUSH 03H
PUSH 04H
PUSH 07H
PUSH ACC
PUSH PSW
SJMP RD1
RD1:
JB P3.2,$ ;以查询方式等待下一次按键操作
SWAP A
LCALL RDKEY
CJNE A,#0AH,WAITT ;容错功能调整
WAITT: JNC RD1
MOV TEMPER_BCD,A
LCALL CF2
MOV B,#0AH
MUL AB
MOV R5,A
MOV 23H,R3
MOV R7,#01H
MOV R0,#23H
MOV R2,#13H
MOV R3,#WSLA_7290
LCALL WRNBYT
KEY2: JB P3.2,$ ;以查询方式等待下一次按键操作
LCALL RDKEY
CJNE A,#0AH,WAITT2
WAITT2: JNC KEY2
MOV TEMPER_BCD,A
LCALL CF2
MOV A,R5
ADD A,TEMPER_BCD
MOV R5,A
MOV 22H,R3
MOV 21H,#9CH ;C
MOV R7,#02H
MOV R0,#21H
MOV R2,#11H
MOV R3,#WSLA_7290
LCALL WRNBYT
;确定键
COMF: JB P3.2,$ ;等待确认键
LCALL RDKEY
CJNE A,#0FH,COMF
MOV 28H,R5 ;上限值放入28h中
DOWN:
;7290复位
CLR P1.7
LCALL DELAY
SETB P1.7
CLR IE0 ;必须清标志
POP PSW
POP ACC
POP 07H
POP 04H
POP 03H
POP 02H
POP 00H
RETI
;---------------------------------------------
;------------读取键值子程序(键值保存在A中)---
RDKEY: MOV R0,#1FH
MOV R7,#01H
MOV R2,#01H
MOV R3,#WSLA_7290
MOV R4,#RSLA_7290
LCALL RDADD
MOV A,1FH
DEC A
RET
;----------------------------------------------
;------------延时子程序-----------------------
DELAY: PUSH 00H ;延时子程序
PUSH 01H
MOV R1,#00
LP: MOV R1,#00H
DJNZ R1,$
DJNZ R0,LP
POP 01H
POP 00H
RET
;---------------------------------------------
;【附录一】由汇编语言编制的I2C通讯子程序
;【提 示】下列程序是在系统时钟为12MHZ(或11.0592MHZ),即NOP指令为1微秒左右。
;(1)带有内部单元地址的多字节写操作子程序 WRNBYT
;*******************************************************************
;通用的I2C通讯子程序(多字节写操作)
;入口参数R7字节数,R0:源数据块首地址
;R0原数据块首地址;R2从器件内部子地址;R3:外围器件地址(写)
;相关子程序WRBYT、STOP、CACK、STA
;*******************************************************************
WRNBYT: PUSH PSW
PUSH ACC
WRADD: MOV A,R3 ;取外围器件地地址(包含r/w=0)
LCALL STA ;发送起始信号S
LCALL WRBYT ;发送外围地址
LCALL CACK ;检测外围器件的应答信号
JB F0,WRADD ;如果应
MOV A,R2
LCALL WRBYT ;发送内部寄存器首地址
LCALL CACK ;检测外围器件的应答信号
JB F0,WRADD ;如果应答不正确返回重来
WRDA: MOV A,@R0
LCALL WRBYT ;发送外围地址
LCALL CACK ;检测外围器件的应答信号
JB F0,WRADD ;如果应答不正确返回重来
INC R0
DJNZ R7,WRDA
LCALL STOP
POP ACC
POP PSW
RET
;*******************************************************************
;(2)带有内部单元地址的多字节读操作子程序 RDADD
;*******************************************************************
;通用的I2C通讯子程序(多字节读操作)
;入口参数R7字节数;
;R0目标数据块首地址;R2从器件内部子地址;
;R3器件地址(写);R4器件地址(读)
;相关子程序WRBYT、STOP、CACK、STA、MNACK
;*******************************************************************
RDADD: PUSH PSW ;从PCF8563的02H单元读入7个参数
PUSH ACC ;存放于20H-26H单元
RDADD1: LCALL STA
MOV A,R3 ;取器件地址(写)
LCALL WRBYT ;发送外围地址
LCALL CACK ;检测外围器件的应答信号
JB F0,RDADD1 ;如果应答不正确返回重来
MOV A,R2 ;取内部地址
LCALL WRBYT ;发送外围地址
LCALL CACK ;检测外围器件的应答信号
JB F0,RDADD1 ;如果应答不正确返回重来
LCALL STA
MOV A,R4 ;取器件地址(读)
LCALL WRBYT ;发送外围地址
LCALL CACK ;检测外围器件的应答信号
JB F0,RDADD1 ;如果应答不正确返回重来
RDN: LCALL RDBYT
MOV @R0,A
DJNZ R7,ACK
LCALL MNACK
LCALL STOP
POP ACC
POP PSW
RET
ACK: LCALL MACK
INC R0
SJMP RDN
;(3)I2C各个信号子程序
;**********************************************************************
; 启动信号子程序S
;**********************************************************************
STA: SETB SDA ;启动信号S
SETB SCL
NOP ;产生4.7US延时
NOP
NOP
NOP
NOP
CLR SDA
NOP ;产生4.7US延时
NOP
NOP
NOP
NOP
CLR SCL
RET
;**********************************************************************
; 停止信号子程序P
;**********************************************************************
STOP: CLR SDA ;停止信号P
SETB SCL
NOP ;产生4.7US延时
NOP
NOP
NOP
NOP
SETB SDA
NOP ;产生4.7US延时
NOP
NOP
NOP
NOP
CLR SCL
CLR SDA
RET
;**********************************************************************
; 应答信号子程序 MACK
;**********************************************************************
MACK: CLR SDA ;发送应答信号ACK
SETB SCL
NOP ;产生4.7US延时
NOP
NOP
NOP
NOP
CLR SCL
SETB SDA
RET
;**********************************************************************
; 非应答法信号子程序MNACK
;**********************************************************************
MNACK: SETB SDA ;发送非应答信号NACK
SETB SCL
NOP ;产生4.7US延时
NOP
NOP
NOP
NOP
CLR SCL
CLR SDA
RET
;**********************************************************************
; 应答检测子程序CACK
;**********************************************************************
CACK: SETB SDA ;应答位检测子程序
SETB SCL
CLR F0
MOV C,SDA ;采样SDA
JNC CEND ;应答正确时转CEND
SETB F0 ;应答错误时F0置一
CEND: CLR SCL
RET
;**********************************************************************
; 发送一个字节子程序WRBYT
;**********************************************************************
WRBYT: PUSH 06H
MOV R6,#08H ;发送一个字节子程序
WLP: RLC A ;(入口参数A)
MOV SDA,C
SETB SCL
NOP ;产生4.7US延时
NOP
NOP
NOP
NOP
CLR SCL
DJNZ R6,WLP
POP 06H
RET
;**********************************************************************
; 接收一个字节子程序RDBYT
;**********************************************************************
RDBYT: PUSH 06H
MOV R6,#08H ;接收一个字节子程序
RLP: SETB SDA
SETB SCL
; *******************************************
NOP ;!!!!!产生大于15微秒的延时!!!!!!
NOP ;注意这是专门为ZLG7290
NOP ;添加的20微秒延时部分
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
; ********************************************
MOV C,SDA
MOV A,R2
RLC A
MOV R2,A
CLR SCL
DJNZ R6,RLP ;(出口参数R2)
POP 06H
RET
;**********************************************************************
end
9 系统调试运行结果说明、分析所出现问题,设计体会与建议
硬件使用ZLG51单片机开发平台,软件使用KEil2软件进行程序的编写编译以及调试。
运行结果:能够实现当前环境温度的采集以及显示、以及超过设定上限温度进行报警,数码管闪烁功能。同时能够经过拨码控制模式切换,切换到设定上限温度模式,经过按键输入上限温度值改变当前上限温度。
调试问题:
(1)采集的温度为十六进制数字,如何转换成十进制BCD码。经过查询上学期学习的计算机原理的相关算法,解决了此问题,成功显示
(2)小数部分的显示问题。经过将所有可能的小数情况列举并进行查表显示,最后成功显示。
(3)读取按键值时键入非0-9的键值也会录入,但不符合实际情况。后来经过判断大小语句改正,保证了按键输入的容错功能
(4)温度上限值保存问题,不能够及时改变,发现无论如何保护R1或是28H单元值,其中的上限值总会发生跳变。后来发现R5寄存器一直没有使用,于是将上限温度保存在R5中,再赋给28H单元,成功保存上限值。可是还出现了如果给了R5初值则上限值又无法成功保存的问题,至今无法解决,故初始上限值为0度。
10结论及设计体会
本次实验综合性比较强,将前几次实验所学习运用的知识都用上了,而且综合整合到一起,调试的过程并不是特别费劲,一切都比较顺利,可是也遇到了不少困难,从中学到了不少东西。
本次实验是基于一个现如今非常普及以及实用性非常强的单片机的开发平台完成的实验,此项实验也具有非常大的实际生活应用意义,对我们今后更进一步的完成单片机的开发甚至嵌入式的开发都有很大的帮助!
本次试验最大的收获有两点:第一点,编程能力有了显著的提高,特别是汇编语言的编程能力,刚开始的时候感觉比较困难,先要将温度用十进制显示出来,刚开始的时候有些不知所措,后来想到了上学期学习汇编时用的算法成功解决了问题,之后一点一点将以前的代码加入整合调整。第二点,调试程序的能力,特别是结合硬件调试程序的能力,以前总是喜欢一个人窝在寝室码代码,可是这次实验不同,需要跟开发板硬件相结合,光靠自己凭空写代码是没有用的,只有结合硬件接口才能找到软件跟硬件连接的问题所在,才能够更好的完成功能的实现。
参考文献
[1] 教材《MCS-51单片机应用实验教程》,秦晓梅,陈育斌等
展开阅读全文