您的位置:首页 > 其它

炎炎夏日需要一个清凉的地 - 自制水冷系统(十一 指尖的思绪之程序篇)

2012-08-10 11:13 176 查看
前段时间接手了一个项目,所以DIY的进程有些停滞。实际编写的程序并没有多长时间,得益于Keil这个强大的IDE。能在第一次做51开发的时候,如此顺利的完成代码。

不多说废话了,说明下代码的具体思路。具体思路根据(八 系统设计篇)进行拆分。分为温度显示部分、指示灯、温度获取和继电器操控部分。

LEDDisplay.c --- 温度显示模块
PilotLamp.c --- 指示灯控制模块
Temperature.c
12b20Temperature.asm --- 温度读取模块
Relays.c --- 继电器控制部分

系统主要控制的指数
1、读取温度的间隔时间
2、在调整温度的时候显示制冷控制温度时间。
3、当达到制冷温度设定值时,关闭或开启控制器一个缓冲量。防止在阀值的时候出现上下跳变问题。
4、控制调整温度的调节范围和调节量

开发中的主要阻力还是来至于温控IC。18B20的时序操作非常严格。如果要自己写调试太耗时间。因此直接从前辈取材,汇编是控制时序是最精确的,在网上找到的很多代码基本也是以汇编为主。我的代码是从杜洋老师已调整好读写时序的汇编代码改编而来。做了些小改动,把温度的精度提高到0.06°C。

另外一个让人抓狂的问题,没能找到根源解决。汇编和C混合开发中,变量的存储地址出现混乱。主程序部分的变量被汇编中的地址操作覆写,导致变量值被冲掉。不知道动了哪根筋,原来木问题后来才有这个问题。 -_-!!哭啊~~ 只能用一个方式规避这个问题,把被覆写变量的地址改为bdata段地址。修改后暂未发现程序中其他变量被覆写的问题。

调试中的效果图

18b20Temperature.asm

DSSP  SEGMENT  CODE    ;程序段

PUBLIC  GetTemperature      ;入口地址,跳转到DL标号处执行汇编程序  GetTemperature

RSEG  DSSP              ;程序段

IN           EQU     0CBH  ; P5.3 引脚地址
FLAG1     EQU   05H   ;DS18B20器件存在标志
TTL       EQU   07H   ;温度读出值(高位在TTL-1中,低位在TTL中)
;TTL_H     EQU   06H   ;温度读出值(高位在TTL-1中,低位在TTL中)

; 这是DS18B20复位初始化子程序
INIT_1820:
SETB IN
NOP
CLR IN
;主机发出延时537微秒的复位低脉冲
MOV R1,#18;#3
TSR1:
MOV R0,#107
DJNZ R0,$
DJNZ R1,TSR1
SETB IN;然后拉高数据线
NOP
NOP
NOP
NOP;12倍
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
MOV R0,#0DEH;#25H
TSR2:
JNB IN,TSR3;等待DS18B20回应
DJNZ R0,TSR2
LJMP TSR4 ; 延时
TSR3:
SETB FLAG1 ; 置标志位,表示DS1820存在
LJMP TSR5
TSR4:
CLR FLAG1 ; 清标志位,表示DS1820不存在
LJMP TSR7
TSR5:
MOV R7,#6
TSR6:
MOV R0,#117
DJNZ R0,$ ; 时序要求延时一段时间 */
DJNZ R7,TSR6 ; 时序要求延时一段时间 */
TSR7:
SETB IN
RET

GetTemperature:
DS1820PRO:
;这里通过调用显示子程序实现延时一段时间,等待AD转换结束,12位的话750微秒
SETB IN
LCALL INIT_1820;先复位DS18B20
JB FLAG1,TSS2
jmp BCD33 ; 判断DS1820是否存在?若DS18B20不存在则返回
TSS2:
MOV A,#0CCH     ; 跳过ROM匹配
LCALL WRITE_1820
MOV A,#44H         ; 发出温度转换命令
LCALL WRITE_1820
CALL  DL1MS
SETB IN
LCALL INIT_1820    ;准备读温度前先复位
MOV A,#0CCH     ; 跳过ROM匹配
LCALL WRITE_1820
MOV A,#0BEH     ; 发出读温度命令
LCALL WRITE_1820
LCALL READ_18200; 将读出的温度数据保存到35H/36H

BCD33:
JB FLAG1,BCD44
mov R6, #080H
mov R7,#00H
JMP TORET

BCD44:

;温度转换程序:精确到:0.06 ;
; 小数温度查表获取。
MOV    DPTR,#TABB
MOV A, TTL
ANL A,#0FH
MOVC A,@A+DPTR
MOV R3, A;
; 整数温度转换
MOV A,TTL
MOV B,TTL-1
MOV C,B.0
RRC A
MOV C,B.1
RRC A
MOV C,B.2
RRC A
MOV C,B.3
RRC A
; 拼接整数位和小数位温度  整数*100 + 小数位值
MOV B, #100
MUL AB
MOV    R4,B         ;保存积的高8位
ADD    A,R3         ;
MOV    R7,A
CLR    A
ADDC A,R4         ;加上进位,
MOV    R6,A

TORET:
RET

;--------------------------------写DS18B20的子程序(有具体的时序要求)
WRITE_1820:
MOV R2,#8;一共8位数据
CLR C
WR1:
CLR IN
MOV R3,#36;#6
DJNZ R3,$
RRC A
MOV IN,C
MOV R3,#192;#23
DJNZ R3,$
SETB IN
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R2,WR1
SETB IN
RET

;-----------------------------读DS18B20的程序,从DS18B20中读出两个字节的温度数据
READ_18200:
MOV R4,#2 ; 将温度高位和低位从DS18B20中读出
MOV R1,#TTL ; 低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)
RE00:
MOV R2,#8;数据一共有8位
RE01:
CLR C
SETB IN
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
CLR IN
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
SETB IN
MOV R3,#54;#9
RE10:
DJNZ R3,RE10
MOV C,IN
MOV R3,#138;#23
RE20:
DJNZ R3,RE20
RRC A
DJNZ R2,RE01
MOV @R1,A
DEC R1
DJNZ R4,RE00
RET

DL1MS:
MOV R7,#6
DL1MS2:
MOV R6,#255
DJNZ R6,$
DJNZ R7,DL1MS2
RET

TABB:
; 小数位温度0~F的查表值,18B20的最小温控精度 0.0625, 只保留两位小数

DB    00H, 06H, 0CH, 12H, 19H, 1FH, 25H, 2BH, 32H
DB  56H, 3EH, 44H, 4BH, 51H, 57H, 5DH

END
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐