炎炎夏日需要一个清凉的地 - 自制水冷系统(十一 指尖的思绪之程序篇)
前段时间接手了一个项目,所以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段地址。修改后暂未发现程序中其他变量被覆写的问题。
主控
PCB设计电路板
调试的效果图
详细的系统小弟就补贴了,可以直接看发在PCB版中的内容。
贴出第一次写51代码^^。小弟有一点开发经验,只是软硬结合的这种模式属于第一个。
--------------------------------
1 #include
2
3 #include "Pins.h"
4 #include "LEDDisplay.h"
5 #include "Temperature.h"
6 #include "Relays.h"
7 #include "PilotLamp.h"
8
9 #define uchar unsigned char
10 #define uint unsigned int
11
12 // 获取温度的时间间隔
13 #define TEMPGETCOUNT 5000 // 温度读取间隔, 500ms 读一次温度,即1秒读2次温度。
14 #define CHANGINGCOUNT 20000 // 温度调控状态时会显示调控温度值,最长显示时间。
15 #define CRITICALCOUNTDOWN 5 // 温度下临界跳变阀值
16 #define CRITICALCOUNTUP 5 // 温度上临界跳变阀值
17 #define CRITICALCOUNTERR 3 // 温度错误,3次关闭
18 #define DEFAULTCRITICALTEMP 2500 // 默认跳变温度 25°C
19 #define VALIDTEMPERATURE_MAX 3000 // 最大有效温度 30°C
20 #define VALIDTEMPERATURE_MIN 2000 // 最小有效温度 20°C
21 #define TEMPERATURESPET 50 // 0.5 °C 温度调整步长
22
23
24 #define COOL_POWERALL 0xFF // 全力运行
25 #define COOL_MALAISE 0x00 // 萎靡~~~~~ 哇咔咔~~~
26
27 #define KEYPRESS_LONG 200 // 按键长按计数,如一只按住不放
28 #define KEYPRESS_SHORT 15 // 短按计数
29
30
31 #define FOSC 1843200L
32 #define T1MS (65536-FOSC/12/1000) // 计时器工作频率 12T状态
33
34
35 uint CriticalTempVal; // 临界温度,跳变温度
36 uint RealTempVal; // 当前温度,获取一定次数时都
37 uint ChangeCount; // 临界切换计数
38
39 uchar RelayVal; // 继电器状态控制位 从右到左 0x03(0000 0011) 那么第一第二个继电器打开。
40 // 指示灯状态
41 // 第一位 继电器工作状态,灯亮工作状态,灯灭停止制冷
42 // 第二位 是否为自动模式
43 // 第三位 温控器故障
44 // 0000 0111
45 uchar DirectLamp;
46 uchar bdata WorkStatus;
47 sbit InCritical = WorkStatus ^ 0; // 临界状态
48 sbit InWorking = WorkStatus ^ 1; // 工作状态
49 sbit InAuto = WorkStatus ^ 2; // 自动模式
50 sbit InHandOn = WorkStatus ^ 3; // 手动打开状态