CMF海水观赏鱼论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
楼主: fpack

炎炎夏日自己搞个小水冷

  [复制链接]

2

主题

28

回帖

65

积分

黄铜会员

Rank: 2

积分
65
发表于 2012-7-25 19:43:01 | 显示全部楼层 来自: 中国上海
fpack 发表于 2012-7-23 23:49
回复 85# 红酒

    江浙沪的打样包邮。我那个是广州打样的,快递要25元,太亏了 =_=。

江浙沪正好包邮
回复

使用道具 举报

3

主题

89

回帖

272

积分

白银会员

Rank: 3Rank: 3

积分
272
 楼主| 发表于 2012-7-25 20:47:30 | 显示全部楼层 来自: 中国上海
呵呵,是不错!

小弟双面板还没做过,所以为了减少问题,直接打样确实是比较方便。就是费点钱
回复

使用道具 举报

59

主题

630

回帖

1686

积分

铂金会员

Rank: 5Rank: 5

积分
1686
发表于 2012-7-25 21:34:54 | 显示全部楼层 来自: 中国浙江杭州
不错呀,我一直在关注,继续等上精品
回复

使用道具 举报

37

主题

1345

回帖

2844

积分

钻石会员

Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15

积分
2844
发表于 2012-7-26 10:18:38 | 显示全部楼层 来自: 中国北京
这个太牛B了,实在是佩服
回复

使用道具 举报

7

主题

85

回帖

194

积分

黄铜会员

Rank: 2

积分
194
发表于 2012-7-30 13:50:54 | 显示全部楼层 来自: 中国辽宁营口
怎么没动静了
老张
回复

使用道具 举报

4

主题

90

回帖

188

积分

黄铜会员

Rank: 2

积分
188
发表于 2012-8-1 11:03:53 | 显示全部楼层 来自: 中国江苏苏州
达人啊 神一般的制作 膜拜一下
强烈要求预定一套 QQ110747916
100 字节以内
不支持自定义 Discuz! 代码
回复

使用道具 举报

3

主题

89

回帖

272

积分

白银会员

Rank: 3Rank: 3

积分
272
 楼主| 发表于 2012-8-2 13:19:26 | 显示全部楼层 来自: 中国上海

公司接手了一个项目,脱不开身。
这段时间程序难产了,搞了很长时间程序没没搞定。
回复

使用道具 举报

0

主题

7

回帖

14

积分

黑铁会员

Rank: 1

积分
14
发表于 2012-8-7 17:28:47 | 显示全部楼层 来自: 中国香港

达人啊 神一般的制作 膜拜一下
强烈要求预定一套 QQ614006757
回复

使用道具 举报

3

主题

89

回帖

272

积分

白银会员

Rank: 3Rank: 3

积分
272
 楼主| 发表于 2012-8-9 00:57:56 | 显示全部楼层 来自: 中国上海
终于调试通过啦!哇咔咔~~ 不容易啊。
回复

使用道具 举报

3

主题

89

回帖

272

积分

白银会员

Rank: 3Rank: 3

积分
272
 楼主| 发表于 2012-8-10 01:30:14 | 显示全部楼层 来自: 中国上海
炎炎夏日需要一个清凉的地 - 自制水冷系统(十一 指尖的思绪之程序篇)


前段时间接手了一个项目,所以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段地址。修改后暂未发现程序中其他变量被覆写的问题。


调试的效果图




贴出第一次写51代码^^。小弟有一点开发经验,只是软硬结合的这种模式属于第一个。
--------------------------------
#include <STC12C5A60S2.h>

#include "Pins.h"
#include "LEDDisplay.h"
#include "Temperature.h"
#include "Relays.h"
#include "PilotLamp.h"

#define uchar unsigned char
#define uint        unsigned int

// 获取温度的时间间隔
#define TEMPGETCOUNT                       5000      // 温度读取间隔, 500ms 读一次温度,即1秒读2次温度。
#define        CHANGINGCOUNT                                        20000                        // 温度调控状态时会显示调控温度值,最长显示时间。
#define CRITICALCOUNTDOWN           5                       // 温度下临界跳变阀值
#define CRITICALCOUNTUP                    5                     // 温度上临界跳变阀值
#define CRITICALCOUNTERR      3         // 温度错误,3次关闭
#define DEFAULTCRITICALTEMP   2500      // 默认跳变温度 25°C
#define VALIDTEMPERATURE_MAX  3000      // 最大有效温度 30°C
#define VALIDTEMPERATURE_MIN  2000      // 最小有效温度 20°C
#define TEMPERATURESPET       50        // 0.5 °C 温度调整步长


#define COOL_POWERALL       0xFF        // 全力运行
#define COOL_MALAISE        0x00        // 萎靡~~~~~ 哇咔咔~~~

#define KEYPRESS_LONG       200         // 按键长按计数,如一只按住不放
#define KEYPRESS_SHORT      15          // 短按计数


#define FOSC  1843200L
#define T1MS        (65536-FOSC/12/1000)                        // 计时器工作频率 12T状态


uint CriticalTempVal;        // 临界温度,跳变温度
uint RealTempVal;     // 当前温度,获取一定次数时都
uint ChangeCount;                        // 临界切换计数

uchar RelayVal;                    // 继电器状态控制位 从右到左 0x03(0000 0011) 那么第一第二个继电器打开。
// 指示灯状态
// 第一位 继电器工作状态,灯亮工作状态,灯灭停止制冷                  
// 第二位 是否为自动模式
// 第三位 温控器故障
// 0000 0111
uchar DirectLamp;
uchar        bdata WorkStatus;
sbit InCritical                        = WorkStatus ^ 0;                                // 临界状态
sbit InWorking                        = WorkStatus ^ 1;                          // 工作状态
sbit InAuto                                        = WorkStatus ^ 2;                                // 自动模式
sbit InHandOn                                = WorkStatus ^ 3;                                // 手动打开状态
sbit CanReadTemp                = WorkStatus ^ 4;                          // 是否允许读取温度
sbit InInitTemp                        = WorkStatus ^ 5;                                // 温度读取是否在初始状态,解决第一次读取出现85°C的问题
sbit InChangingTemp        = WorkStatus ^ 6;                                // 在温度调整中


// 温度读取时间间隔,减少18B20的读取次数,
// 目的是为数码管能获得比较高的刷新频率,提高显示亮度。
// 每次读取会有固定占用时间,能看出每次读取会有变暗的闪烁情况。
uint TempTimerSpace;                                  

uint TempChangingStatusSpace;  // 温度调控状态中

void Init(void);
bit CanUpdateTemp(void);
void UpdateTemperature(void);
void ReadTemperature(void);
void UpdateStatus(void);
void InitTimer(void);
void SearchKeys(void);

unsigned int GetCriticalTemperature(void);
//void SaveCriticalTemperature(unsigned int);


// 按键
// 18 K3  17 K4  16 K5
sbit        Key_Mode          = P1 ^ 1;
sbit        Key_CTDown        = P1 ^ 0;       
sbit        Key_CTUp          = P0 ^ 0;

//enum KeyType (TNone=0, KTMode=1, KTCTDown=2, KTCTUp=4);

uchar KeyCount;
uchar KeyTypeVal;

#define        KEYTYPE_NONE                0 // 没有按键使用
#define KEYTYPE_MODE                1 // 按下模式切换状态
#define KEYTYPE_CTDOWN  2 // 按下温度切换状态
#define KEYTYPE_CTUP                4 // 按下温度切换状态


void main()
{
        Init();
        while(1){
          if (CanReadTemp)
                        ReadTemperature();
               
                SearchKeys();               
                UpdateStatus();       
                UpdateRelays(RelayVal);

                if (!InChangingTemp)
                        DisplayTemperature(RealTempVal);
                else
                        DisplayTemperature(CriticalTempVal);
               
                DisplayPilotLamp(DirectLamp);
        }
}

void Init(void){
        WorkStatus = 0x00;
        InAuto = 1;                    // 默认自动模式
       
        KeyCount = 0;
        KeyTypeVal = KEYTYPE_NONE;
        RealTempVal = DEFAULTCRITICALTEMP;
        CriticalTempVal = GetCriticalTemperature();

        InitTimer();
  InitPilotLamp();
        InitView();
        InitTemperature();
        InitRealys();
}

void SearchKeys(void){
        // 模式切换
        if (Key_Mode == 0){
                KeyTypeVal = KEYTYPE_MODE;
                KeyCount++;
        }

        // 温控温度
        if (Key_CTDown == 0) {
                KeyTypeVal = KEYTYPE_CTDOWN;
                KeyCount ++;
   
    // 长按状态
    if (KeyCount > KEYPRESS_LONG) {
      KeyCount = 0;
                        if (CriticalTempVal > VALIDTEMPERATURE_MIN) {
                                TempChangingStatusSpace = CHANGINGCOUNT;
                                CriticalTempVal -= TEMPERATURESPET;
                        }
    }
        }

        // 温控温度
        if (Key_CTUp == 0) {
                KeyTypeVal = KEYTYPE_CTUP;
                KeyCount ++;
  
    // 长按状态
    if (KeyCount > KEYPRESS_LONG) {
      KeyCount = 0;
                        if (CriticalTempVal < VALIDTEMPERATURE_MAX){
                                TempChangingStatusSpace = CHANGINGCOUNT;
                                CriticalTempVal += TEMPERATURESPET;
                        }
    }
        }

        if (KeyCount > KEYPRESS_SHORT){
                if (Key_Mode == 1 && KeyTypeVal == KEYTYPE_MODE){
                        KeyTypeVal = KEYTYPE_NONE;
                        KeyCount = 0;
                        if (InAuto){
                                InAuto = 0;
                                InHandOn = 1;
                        }
                        else {
                                if (InHandOn)
                                        InHandOn = 0;
                                else
                                        InAuto = 1;
                        }
                }
       
                if (Key_CTDown == 1 && KeyTypeVal == KEYTYPE_CTDOWN){
                        KeyTypeVal = KEYTYPE_NONE;
                        KeyCount = 0;
                        if (CriticalTempVal > VALIDTEMPERATURE_MIN) {
                                CriticalTempVal -= TEMPERATURESPET;
                                TempChangingStatusSpace = CHANGINGCOUNT;
                        }
                }
               
                if (Key_CTUp == 1 && KeyTypeVal == KEYTYPE_CTUP){
                        KeyTypeVal = KEYTYPE_NONE;
                        KeyCount = 0;
                        if (CriticalTempVal < VALIDTEMPERATURE_MAX) {
                                TempChangingStatusSpace = CHANGINGCOUNT;
                                CriticalTempVal += TEMPERATURESPET;
                        }
                }
        }
}


void ReadTemperature(void){
        unsigned int Val;
       
        Val = GetTemperature();       
       
        // 18B20有个特殊问题,第一次读取会出现 85°C
        if (InInitTemp && Val == 8500){
                CanReadTemp = 1;       
                return;
        }
       
        RealTempVal = Val;
  CanReadTemp = 0;
        InInitTemp = 0;
  //
  // 对于临界温度,需要特殊处理。
  // 防止温控在临界时频繁跳变,当在临界一侧温度超缓冲量时才允许跳转模式。
  // 当温控探头无效时优先处理
  //
        // 如果温控探头被拔出,再次插入的时候会出现 85°C的错误情况
        // 只要温度读取错误,那么就认为温控探头是被拔出状态。
        //
  if (RealTempVal == VAL_ERRTEMPERATURE){
                InInitTemp = 1;
    if (InCritical)
      ChangeCount--;
    else {
      InCritical = 1;
      ChangeCount = CRITICALCOUNTERR;
    }
  }
  else if (InWorking) {
                if (RealTempVal < CriticalTempVal){
                        if (InCritical)
                          ChangeCount--;
                        else {
                                InCritical = 1;
                                ChangeCount = CRITICALCOUNTDOWN;
                        }
    }
                else {
                        InCritical = 0;
      ChangeCount = 0;
    }
        }
        else {
                if (RealTempVal > CriticalTempVal){
                        if (InCritical)
                                ChangeCount --;
                        else {
                                InCritical = 1;
                                ChangeCount = CRITICALCOUNTUP;
                        }
                }
                else {
                        InCritical = 0;
      ChangeCount = 0;
    }
        }

}


void InitTimer(void){
        // 使用定时器1作为时间计数
        TMOD  = 0x01;
  TL0 = T1MS;
  TH0 = T1MS >> 8;
  TR0 = 1;
  ET0 = 1;
  EA = 1;  
       
        CanReadTemp = 0;
        TempTimerSpace = TEMPGETCOUNT; // 第一次温度读取
        InInitTemp = 1;                                                          // 温度处于初始状态,解决85°C问题
        TempChangingStatusSpace = 0;         // 不在调温状态
}


void UpdateStatus(void){
  //
  // 温控临界跳变, 缓冲计数为零时跳变
  //
  //
        if (InCritical && !ChangeCount){
          InCritical = 0;
          if ((RealTempVal != VAL_ERRTEMPERATURE) && (RealTempVal > CriticalTempVal))
                  InWorking = 1;
          else
                  InWorking = 0;                                                  
  }
       
        // 是否在调温状态
        if (TempChangingStatusSpace)
                InChangingTemp = 1;
        else
                InChangingTemp = 0;

  //
  // 温控状态和手工状态
  // 温控状态时根据是否工作状态判断,手动模式下通过是否强行开启判断继电器模式
  //  
  if((InAuto && InWorking) || (!InAuto && InHandOn))
          RelayVal = COOL_POWERALL;       
  else
    RelayVal = COOL_MALAISE;
  
  // 工作状态信息更新
  
  if (RelayVal > 0)
          DirectLamp = 1;
  else
    DirectLamp = 0;

        if (InAuto)
                DirectLamp |= 0x02;  
}


unsigned int GetCriticalTemperature(void){
  //todo :  这里的值需要从EEPROM中获取
        return (DEFAULTCRITICALTEMP);
}
/*
void SaveCriticalTemperature(unsigned int Val){
  //todo : 保存临界温度到EEPROM,防止停电丢失数据         
}
*/

void time0(void) interrupt 1{
  // 时钟
  TL0 = T1MS;
  TH0 = T1MS >> 8;       
        TempTimerSpace--;
        if (!TempTimerSpace){
                CanReadTemp = 1;
                TempTimerSpace = TEMPGETCOUNT;
        }
       
        if (TempChangingStatusSpace)
                TempChangingStatusSpace--;
}


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|海友网CMF ( 琼ICP备12003277号 )

GMT+8, 2026-5-7 15:55 , Processed in 0.075392 second(s), 14 queries , MemCache On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表