超聲波液位可控恒溫水浴系統(tǒng)
超聲波液位可控恒溫水浴系統(tǒng),超聲波,可控,恒溫,水浴,系統(tǒng)
華南理工大學(xué)第九屆
智能設(shè)計控制大賽
初級組
超聲波液位可控恒溫水浴系統(tǒng)
默默隊:謝銳勇
陳浩權(quán)
林俊彥
目錄
一、引言
1. 超聲波液位可控恒溫水浴系統(tǒng)的現(xiàn)實意義
二、系統(tǒng)整體設(shè)計
2.1 整體設(shè)計方案
2.2水浴箱外形設(shè)計
三、硬件設(shè)計方案
3.1 電源
3.2 AT89S52單片機
3.3 5位獨立鍵盤
3.4 12864液晶顯示
3.5 水體溫度采集
3.6 液位高度采集
3.7 溫度、高度調(diào)節(jié)
3.8 PC與單片機通信
四、軟件
4.1 程序總體設(shè)計方案
4.2 主程序偽代碼
五、調(diào)試
5.1 遇到的問題及解決方案
六、我們的特色
七、主要程序附錄
6.1主程序
6.2 12864液晶顯示程序
6.3獨立鍵盤掃描程序
6.4溫度、高度控制程序
6.5 Ds18b20讀取溫度程序
6.6 超聲波測液位程序
6.7 上位機及下位機程序
一、 引言
在一個水浴系統(tǒng)中,控制并保持水體溫度,高度是十分必要的。本系統(tǒng)主要應(yīng)用超聲波測液位,溫度傳感器測水體溫度。超聲波液位可控恒溫水浴系統(tǒng)在人們?nèi)粘I钌a(chǎn)中有很廣泛的應(yīng)用。如:游泳池水位、水溫的檢測及調(diào)控。
二、 系統(tǒng)總體設(shè)計
本設(shè)計基于單片機的超聲波液位可控恒溫水浴系統(tǒng)主要由單片機模塊、溫度檢測模塊、超聲波檢測模塊、LED顯示模塊、12864液晶顯示模塊、獨立鍵盤模塊、繼電器驅(qū)動模塊以及PC通信等組成。
1. 整體設(shè)計方案
本設(shè)計采用模塊化思想,以AT89S52為核心,將其他表模塊有機結(jié)合在一起,形成一個符合設(shè)計要就的系統(tǒng)。其系統(tǒng)模塊框圖如下圖:
獨立鍵盤
上位機
串口通信模塊
超聲波測量液位
LED顯示模塊
12864液晶
顯示
DS18b20
采集溫度
AT89S52
單
片
機
繼電器驅(qū)動制冷片和水泵
2. 水浴箱外形設(shè)計
考慮到水浴系統(tǒng)的實際應(yīng)用,我們在設(shè)計水箱結(jié)構(gòu)時,將加熱制冷模塊和抽水模塊放在水箱底部,并用一層板將之與上面的水浴隔開,實現(xiàn)安全設(shè)計的理念。同時,將兩個制冷片分別置于水箱兩邊,使水箱更加穩(wěn)定;還增加設(shè)計了兩個平臺,可以放置液晶顯示模塊和鍵盤操作模塊,使操作更加便利和人性化。
三、 硬件設(shè)計方案
3.1 電源
根據(jù)師兄往年參賽的經(jīng)驗,本設(shè)計所采用的電源是和制冷片配套買的,規(guī)格12V-10A,電壓和電流相對比較穩(wěn)定。在系統(tǒng)中為散熱風扇、制冷片、水泵等供電。另外,采用9V電池為單片機及其他一些模塊供電。
3.2 AT89S52單片機
本模塊主要是采用單片機最小系統(tǒng)板,外加其他附加電路。
3.3 5位獨立鍵盤
Enter鍵(確定進,出設(shè)置程序),
上移鍵 (增大各個數(shù)值),
下移鍵 (增大各個數(shù)值),
左移鍵 (左移光標),
右移鍵 右移光標)。
3.4 12864液晶顯示
本模塊是用12864液晶顯示溫度、液位高度以及當前溫度曲線和液位高度柱狀圖。
其連接電路如下圖:
關(guān)于12864液晶的具體操做方法可參考郭天祥51單片機教程164頁7.4常用12864液晶操作實例。
3.5 水體溫度采集
1. 溫度采集模塊方案比較
方案1:采用美國DALLAS公司生產(chǎn)DS18B20數(shù)字溫度傳感器,單線接口方式,與單片機進行通信只需要一個I/O口,電路簡單且比較方便。而且可以直接讀出溫度值隨后進行相應(yīng)的轉(zhuǎn)換并顯示出來。
方案2:使用正溫度系數(shù)熱敏電阻PTC或者負溫度系數(shù)熱敏電阻NTC的感溫特性,在溫度變化時,電阻會相應(yīng)地變化,從而使輸出電壓或輸出電流相應(yīng)地變化,再用AD模數(shù)轉(zhuǎn)換將電壓采集回來,通過一定的計算出當前溫度并顯示出來。
電路如上,信號的采集要加上放大器、比較器、AD模數(shù)轉(zhuǎn)換等,比較麻煩,而且占用資源比較多。
綜上,比較以上兩種方案,很容易看出,采用方案1,電路比較簡單,軟件設(shè)計容易實現(xiàn),故實際設(shè)計中擬采用方案1。
3.6 液位高度采集
由于本系統(tǒng)設(shè)計要求,所以采用超聲波測量水面液位。
1. 超聲波傳感器與應(yīng)用電路
3.7 溫度、液位高度調(diào)節(jié)
本設(shè)計采用繼電器雙向控制制冷片以及散熱風扇,水泵,從而實現(xiàn)制冷片制熱,制冷;水泵正反向抽水。
繼電器雙向控制電路如下圖:
用繼電器來進行控制,三極管放大來驅(qū)動繼電器,
一開始擬采用12V控制電壓的,但由于是單片機驅(qū)動,便選擇了SRD-05VC-SL-C,VCC端接單片機電源端即可。比較方便,而且耐得住最大不超過10A的電流,滿足要求。
3.8 PC與單片機通信
1. PC機與單片機AT89S52通信的硬件設(shè)計
通常PC機和單片機之間的通信是通過串行總線RS-232實現(xiàn)的。因此采用一種以MAX232為核心的通信接口電路。該接口電路適用于由一臺PC機與多個8051單片機串行通信的設(shè)計,其原理和方法同樣適用于PC機與其它單片機之間的串行數(shù)據(jù)通信。其原理框圖見圖1:
圖1 單片機與PC機通信原理框圖
該框圖中,起著重要作用的是RS-232C通信接口電路。它是上位機和下位機之間信息傳遞的樞紐,一切數(shù)據(jù)的傳輸必需由它完成,上位機直接利用它的RS-232串行口,為此,采用了RS-232串行通信來接收或上傳數(shù)據(jù)和指令。但RS-232信號的電平和單片機串口信號的電平不一致,必須進行二者之間的電平轉(zhuǎn)換。在此電路中,采用MAX232實現(xiàn)TTL邏輯電平和RS-232電平之間的相互轉(zhuǎn)換。
MAX232由單一的+5V電源供電,只需配接5個高精度10μF/50V的鉭電容即可完成電平轉(zhuǎn)換。因此,避免了用1488和1489時必需兩路電源的麻煩。轉(zhuǎn)換后的串行信號TXD、RXD直接與PC機的串行口連接。如此設(shè)計,既可發(fā)揮出PC機強大的計算和顯示功能,又可以體現(xiàn)出單片機靈活的控制功能,有利于對現(xiàn)場信號的實時采集、處理和監(jiān)控。
2. AT89S52與PC機之間的通信協(xié)議
在許多場合的測控系統(tǒng)中,約定PC機和AT89S52單片機的通信協(xié)議為:
Number+Command+Length+Data+Check
Number:下位機的機號,若設(shè)計中有3臺下位機,即Number 取01H,02H,03H,分別代表:#1,#2,#3號下位機;
Command:本次命令的代碼;Length:本次發(fā)送數(shù)據(jù)段的字節(jié)數(shù);
Data:要發(fā)送的數(shù)據(jù)段;
Check:1字節(jié)的校驗碼。
本設(shè)計只考慮一個單片機,故可對上述通信協(xié)議進行簡化。
四、 軟件設(shè)計
4.1 程序總體設(shè)計方案
本系統(tǒng)的軟件設(shè)計方案采用多模塊設(shè)計,既有利于分工,提高效率,又有利于實現(xiàn)程序的封裝。其整體方案如下:
獨立鍵盤調(diào)節(jié)模塊程序
串口通信模塊程序
AT89S52
單
片
機
超聲波測量液位模塊程序
DS18b20
采集溫度模塊程序
上位機模塊程序
12864液晶
顯示模塊程序
PID控制繼電器驅(qū)動制冷片和水泵模塊程序
LED顯示及蜂鳴器警報模塊程序
4.2 主程序偽代碼:
初始化
While(1)
If模式鍵沒按下
{ If溫度采樣完成
{
進入溫度PID控制
If 當前誤差在死區(qū)內(nèi)
制冷片停
Else
12864溫度刷新
將溫度傳給上位機
If 當前溫度>目標溫度
制冷片制冷
Else
制冷片加熱
PID控制制冷片工作占空比
}
If 高度采樣完成
{ 進入高度PID控制
If 當前誤差在死去內(nèi)
水泵停
Else
12864高度刷新
將高度數(shù)據(jù)傳給上位機
If 當前高度>目標高度
水泵出水
Else
水泵進水
PID控制水泵工作占空比
}
進行鍵盤掃描
}
Else (進入設(shè)置模式)
{
鍵盤掃描確定按鍵
根據(jù)相應(yīng)的按鍵進行溫度、高度的調(diào)節(jié)
}
五、 調(diào)試
5.1 遇到的問題及解決方案
1.由于時間緊迫,如果水箱交由廠家制作成型,時間會很浪費,所以最終決定自己購買塑料板回來,再自己用玻璃膠粘和成型,但由于是自己粘的,所以很長一段時間,都存在縫隙漏水問題,最后再加上其他膠水,才解決這個問題。
2.由于上位機采用VB語言編寫,但我們?nèi)硕紱]有VB基礎(chǔ),所以只能從零開始學(xué)習VB 。
3.上位機與單片機之間的串口通信線開始時連接一直出錯,后買了一條新的串口線,并從新安裝了一個驅(qū)動軟件,才實現(xiàn)功能。
4.由于電路模塊很多,如果每次都重新接導(dǎo)線,將會很麻煩,所以我們采用一個盒子將多個電路模塊封裝起來,使整體更美觀。
5.由于制冷片工作功率不怎么高,使得我們起初采集到的溫度數(shù)據(jù)的變化不明顯,通過不斷修改采樣頻率,使得在既能反應(yīng)溫度變化的前提下,又能減少DS18b20的工作頻率。
6.起初設(shè)計是想把超聲波放在水箱底部,為此還特地在設(shè)計水箱底部時,設(shè)計了超聲波模塊的結(jié)構(gòu),但在實際調(diào)試過程中,由于防水薄膜對超聲波反射產(chǎn)生能大的干擾,所以后改用將超聲波模塊放于水箱上部,并將算法進行相應(yīng)的修改即可。
7.在調(diào)試過程中,發(fā)現(xiàn)制冷片的加熱和制冷速率都有點慢,如果要較大幅度的改變溫度(如:重15度升到45度)時,會等很久,所以經(jīng)過討論,改進成先將水換成常溫下的水,再進行制冷或加熱。
六、 我們的特色
1. 考慮到制冷或加熱所需能量較多,且耗費時間更長,因此我們決定,在滿足一定條件時,直接將容器內(nèi)部的水換成外部常溫下的水,再進行相應(yīng)的制冷或加熱。
2. 水的進出位置安排在底部,液面上升和下降時較平穩(wěn),沒有太大波動。
3. 制冷裝置和溫度傳感器均安裝在底部,不占用容器主體位置,使該水浴系統(tǒng)使用范圍更廣。
4. 容器側(cè)面有兩個突出的平臺,可用于放置液晶顯示屏和操作按鍵,更具一體化,實用性更強。
七、主要程序附錄
6.1主程序
#ifndef __MAIN_H__
#define __MAIN_H__
/**************宏定義****************/
#define uchar unsigned char
#define uint unsigned int
#define ON 1
#define OFF 0
/*************位定義****************/
sbit pump_F = P2^0; //水泵正向引腳
sbit pump_B = P2^1; //水泵反向引腳
sbit cooler1_F = P2^2; //制冷片1正向引腳
sbit cooler1_B = P2^3; //制冷片1反向引腳
sbit cooler2_F = P2^4; //制冷片2正向引腳
sbit cooler2_B = P2^5; //制冷片2反向引腳
/************枚舉******************/
enum DIRECTION {FORWARD=0, BACKWARD=1};
/************聲明變量**************/
extern bit cooler_flag; //制冷片旗標 判斷是否啟動制冷片
extern bit pump_flag; //水泵旗標 判斷是否啟動水泵
extern enum DIRECTION cooler_drc_flag; //制冷片方向旗標 判斷制冷片電流方向
extern enum DIRECTION pump_drc_flag; //水泵方向旗標 判斷水泵電流方向
extern bit temper_check_flag; //溫度檢測旗標 判斷溫度是否采樣
extern bit height_check_flag; //液位檢測旗標 判斷液位是否采樣
extern int temperature; //測量得到的當前溫度值
#endif
/*************頭文件***************/
#include
#include
#include "main.h"
#include "PID.h"
#include "interrupt.h"
#include "keyboard.h"
#include "12864_bing.h"
#include "DS18B20.h"
#include "Ultrasonic.h"
/************定義變量************/
bit cooler_flag = OFF; //制冷片旗標 判斷是否啟動制冷片
bit pump_flag = OFF; //水泵旗標 判斷是否啟動水泵
enum DIRECTION cooler_drc_flag = FORWARD; //制冷片方向旗標 判斷制冷片電流方向
enum DIRECTION pump_drc_flag = FORWARD; //水泵方向旗標 判斷水泵電流方向
bit temper_check_flag = OFF; //溫度改變旗標 判斷溫度是否改變
bit height_check_flag = OFF; //液位改變旗標 判斷液位是否改變
int temperature; //測量得到的當前溫度值
/**********聲明函數(shù)**************/
void init(); //初始化函數(shù)
/***********主函數(shù)***************/
void main()
{
init(); //初始化
while(1)
{
//若enter鍵旗標表明不是進入設(shè)置模式
if (enter_flag == 0)
{
//若溫度檢測旗標表明溫度已經(jīng)采樣
if (temper_check_flag == ON)
{
PID1.error0 = temperature - PID1.target; //計算當前誤差 [當前值-目標值] (單位:*10度)
if ((PID1.error0 >= TEMPER_DDZ_L) && (PID1.error0 <= TEMPER_DDZ_H)) //若當前誤差在死區(qū)范圍內(nèi)
{
temper_check_flag = OFF; //溫度檢測旗標變?yōu)镺FF
cooler_flag = OFF; //制冷片旗標變?yōu)镺FF,表明制冷片停止工作
//溫度到達穩(wěn)定標志
}
else //否則,當前誤差不在死區(qū)范圍內(nèi)
{
//12864刷屏
//將相應(yīng)數(shù)據(jù)傳輸給上位機
//判斷誤差大于0還是小于0,從而判斷制冷片制冷還是加熱
if (PID1.error0 > 0) //誤差大于0,當前溫度高于目標值,制冷片電流方向為正向,制冷
{
cooler_drc_flag = FORWARD;
}
else //否則,誤差小于0,當前溫度低于目標值,制冷片電流方向為反向,加熱
{
cooler_drc_flag = BACKWARD;
}
PID1_control(); //溫度PID控制
pwm_cooler = (uchar)(abs(PID1.output)); //將PID輸出值賦給制冷片pwm高電平時間,從而控制制冷片功率
}
}
//若液位檢測旗標表明液位已經(jīng)采樣
if (height_check_flag == ON)
{
PID2.error0 = (int)( (distance%100000)/10 ) - PID2.target; //計算當前誤差 [當前值-目標值]
if ((PID2.error0 >= HEIGHT_DDZ_L) && (PID2.error0 <= HEIGHT_DDZ_H)) //若當前誤差在死區(qū)范圍內(nèi)
{
height_check_flag = OFF; //液位改變旗標變?yōu)镺FF,當前誤差為0
pump_flag = OFF; //水泵旗標變?yōu)镺FF,表明水泵停止工作
//液位到達穩(wěn)定標志
}
else //否則,當前誤差不在死區(qū)范圍內(nèi)
{
//更新12864上顯示的當前液位高度
height_draw = distance_char[1] * 10 + distance_char[2]; //取當前高度數(shù)值,單位為cm
DrawHeight(height_draw); //將當前高度圖像在12864上畫出
//將相應(yīng)數(shù)據(jù)傳輸給上位機
if (PID2.error0 > 0) //若誤差大于0,當前液位高于目標液位,水泵電流方向為正向,出水
{
pump_drc_flag = FORWARD;
}
else //否則,誤差小于0,當前液位低于目標液位,水泵電流方向為負方向,進水
{
pump_drc_flag = BACKWARD;
}
PID2_control(); //液位PID控制
pwm_pump = (uchar)(abs(PID2.output)); //將PID輸出值賦給水泵pwm高電平時間,從而控制水泵功率
}
}
enter_scan(); //掃描鍵盤
}
//否則,則enter鍵旗標表明進入設(shè)置模式
else
{
key = DEFAULT;
while (key == DEFAULT)
{
key_scan(); //鍵盤掃描
}
DealKey();
}
}
}
/***********初始化函數(shù)**********/
void init()
{
interrupt_init(); //中斷初始化
PID_init(); //PID參數(shù)初始化
Init_12864(); //12864初始化
Init_DS18B20(); //DS18B20初始化
}
6.2 12864液晶顯示程序
#ifndef __12864_BRING_H__
#define __12864_BRING_H__
/***********宏定義***********/
#define uchar unsigned char
#define uint unsigned int
/********* 端口定義*********/
#define LCD_data P0 //數(shù)據(jù)口
sbit LCD_RS=P3^4; //寄存器選擇輸入
sbit LCD_RW=P3^5; //液晶讀/寫控制
sbit LCD_EN=P3^6; //液晶使能控制
//psb接在正極上
/**********變量聲明**********/
extern uchar idata LastTemp; //定義最后一次的溫度,方便畫線
extern uchar idata LastTempData1; //最后一次讀取顯示的內(nèi)容,用于變換目標溫度時恢復(fù)上一個
extern uchar idata LastTempData2; //最后一次讀取顯示的內(nèi)容,用于變換目標溫度時恢復(fù)上一個
extern uchar idata LastHeight; //最后一次的高度,用于變化高度時迅速畫線,減少關(guān)閉畫圖時間
/*函數(shù)聲明*/
//extern void Delay_ms(uint x) ;
extern void CheckBusy(); //一直等待,直到不忙
extern void WriteCommand(uchar cmd); //寫指令函數(shù)
extern void WriteData(uchar dat); //寫數(shù)據(jù)函數(shù)
extern uchar ReadData(); //返回當前地址的數(shù)據(jù)
extern void Location(uchar X,uchar Y); //定位,X=1~4;Y=1~8
extern void Init_12864();
extern void DrawPicture(uchar *img); //整屏畫圖函數(shù),傳遞數(shù)組首地址
extern void DrawPoint(uchar Row ,uchar Column); //寫點函數(shù),參數(shù)是行和列Row=1~64;Column=1~128
extern void DrawTemp(uchar const temp); //畫等溫線函數(shù)(平行于X軸直線)
extern void ChangeTemp(uchar temp); //當溫度改變時調(diào)用,恢復(fù)上次畫線前的樣子,并畫新線
extern void DrawHeight(uchar const h); //畫高度函數(shù)(長方體),參數(shù)是高度
#endif
#include
#include
#include"12864_bing.h"
#include "delay_ms.h"
#define uchar unsigned char
#define uint unsigned int
uchar idata LastTemp=0;
uchar idata LastTempData1=0;
uchar idata LastTempData2=0;
uchar idata LastHeight=24;
uchar code init_char1[]={"To: 27.6cm 50.0 "};
uchar code init_char2[]={" 27.5cm 56.7cm "};
/*********************************************************/
/* */
/* 讀忙標志 */
/* */
/*********************************************************/
void CheckBusy()
{
uchar result;
do
{
LCD_EN=0;
LCD_RS=0;
LCD_RW=1;
LCD_EN=1;
result=LCD_data;
LCD_EN=0;
result=result&0x80;
}while(result==0x80);
}
/*******************************************************************/
/* */
/*寫指令數(shù)據(jù)到LCD */
/*RS=L,RW=L,E=高脈沖,D0-D7=指令碼。 */
/* */
/*******************************************************************/
void WriteCommand(uchar cmd)
{
CheckBusy();
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
LCD_data = cmd;
delay_ms(5);
LCD_EN = 1;
delay_ms(5);
LCD_EN = 0;
}
/*******************************************************************/
/* */
/*寫顯示數(shù)據(jù)到LCD */
/*RS=H,RW=L,E=高脈沖,D0-D7=數(shù)據(jù)。 */
/* */
/*******************************************************************/
void WriteData(uchar dat)
{
CheckBusy();
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
LCD_data = dat;
delay_ms(5);
LCD_EN = 1;
delay_ms(5);
LCD_EN = 0;
}
/*******************************************************************/
/* */
/* 讀數(shù)據(jù) */
/* */
/*******************************************************************/
uchar ReadData()
{
uchar dat;
LCD_data=0xff;
CheckBusy();
LCD_EN=0;
LCD_RW=1;
LCD_RS=1;
LCD_EN=1;
_nop_();
_nop_();
dat=LCD_data;
LCD_EN=0;
return dat;
}
/*********************************************************/
/* */
/* 設(shè)定顯示位置 */
/* */
/*********************************************************/
void Location(uchar X,uchar Y)
{
uchar pos;
if (X==1)
{X=0x80;}
else if (X==2)
{X=0x90;}
else if (X==3)
{X=0x88;}
else if (X==4)
{X=0x98;}
pos = X+Y-1;
WriteCommand(pos); //顯示地址
}
/*******************************************************************/
/* */
/* LCD初始化設(shè)定 */
/* */
/*******************************************************************/
void Init_12864()
{
//LCD_PSB = 1; //并口方式
WriteCommand(0x30); //基本指令操作
delay_ms(5);
WriteCommand(0x0C); //顯示開,關(guān)光標
delay_ms(5);
WriteCommand(0x01); //清除LCD的顯示內(nèi)容
delay_ms(5);
}
/*******************************************************************/
/* */
/* 整屏畫圖函數(shù) */
/* */
6.3獨立鍵盤掃描程序
#ifndef __KEY_SCAN_H__
#define __KEY_SCAN_H__
/**************位定義***************/
sbit key_enter = P2^0; //enter鍵
sbit key_left = P2^1; //左移鍵
sbit key_right = P2^2; //右移鍵
sbit key_up = P2^3; //上移鍵
sbit key_down = P2^4; //下移鍵
/*************枚舉******************/
enum KEY {DEFAULT=0, ENTER=1, LEFT=2, RIGHT=3, UP=4, DOWN=5};
/**************聲明函數(shù)*************/
extern void enter_scan(); //enter鍵掃描函數(shù)
extern void key_scan(); //鍵盤掃描函數(shù)
extern void DealKey(); //鍵盤處理函數(shù)
/**************聲明變量************/
extern bit enter_flag; //鍵盤旗標 按下enter鍵時,1表示進入設(shè)置,0表示退出設(shè)置
extern struct PID_STRUCT PID1; //溫度
extern struct PID_STRUCT PID2; //高度
extern enum KEY key; //按鍵鍵值
#endif
/*********定義變量***********/
bit enter_flag = 0; //enter鍵旗標 按下enter鍵時,1表示進入設(shè)置,0表示退出設(shè)置
bit flag_num_location;// 定義修改目標溫度位置標志位,當值為0時表明正在修改目標高度,是1時正在修改溫度
enum KEY key = DEFAULT; //按鍵鍵值 DEFAULT表明沒有按鍵按下
/*********掃描enter鍵函數(shù)*******/
void enter_scan()
{
if (key_enter == 0)
{
delay_ms(10); //去抖延時
if (key_enter == 0)
{
EA = OFF; //關(guān)總中斷
while (key_enter == 0); //等待按鍵釋放
enter_flag = ~enter_flag; //鍵盤旗標取反
//若鍵盤旗標為1,表明進入設(shè)置
if (enter_flag == 1)
{
ET1 = OFF; //關(guān)定時器1中斷
TR1 = OFF; //停止定時器1
TH1 = (65536 - 46080) / 256; //重裝初值 11.0592M晶振 50ms
TL1 = (65536 - 46080) % 256;
temper_sample_count = 0; //采樣時間計數(shù)歸零
height_sample_count = 0;
cooler_count = 0; //制冷片pwm計數(shù)歸零
pump_count = 0; //水泵pwm計數(shù)歸零
cooler1_F = OFF; //繼電器所有引腳撥到停止位置,制冷片、水泵停止工作
cooler2_F = OFF;
cooler1_B = OFF;
cooler2_B = OFF;
pump_F = OFF;
pump_B = OFF;
Location(1,3);
WriteCommand(0x0f);//開光標
flag_num_location=0;
}
//否則,鍵盤旗標為0,表明退出設(shè)置
}
}
}
/*********掃描鍵盤函數(shù)**********/
void key_scan()
{
//enter鍵被按下
if (key_enter == 0)
{
delay_ms(10); //去抖延時
if (key_enter == 0)
{
while (key_enter == 0); //等待按鍵釋放
key = ENTER;
}
}
//左移鍵被按下
if (key_left == 0)
{
delay_ms(10); //去抖延時
if (key_left == 0)
{
while (key_left == 0); //等待按鍵釋放
key = LEFT;
}
}
//右移鍵被按下
if (key_right == 0)
{
delay_ms(10); //去抖延時
if (key_right == 0)
{
while (key_right == 0); //等待按鍵釋放
key = RIGHT;
}
}
//上移鍵被按下
if (key_up == 0)
{
delay_ms(10); //去抖延時
if (key_up == 0)
{
while (key_up == 0); //等待按鍵釋放
key = UP;
}
}
//下移鍵被按下
if (key_down == 0)
{
delay_ms(10); //去抖延時
if (key_down == 0)
{
while (key_down == 0); //等待按鍵釋放
key = DOWN;
}
}
}
void DealKey()
{
uchar temp1,temp2; //用于將目標值變成兩個數(shù)字
if(key==ENTER)
{
//按下enter鍵
enter_flag = 0; //enter鍵旗標置0,表明退出設(shè)置模式
EA = ON; //開總中斷
ET1 = ON; //開定時器1中斷
TR1 = ON; //啟動定時器1
WriteCommand(0x0c);//關(guān)光標
}
else if(key==LEFT)
//按下左移鍵
{
Location(1,3);
flag_num_location=0;
}
else if(key==RIGHT)
//按下右移鍵
{
Location(1,7);
flag_num_location=1;
}
else if(key==UP)
//按下上移鍵
{
//-----------------------------------------------------
if(flag_num_location==0) //正在修改高度
{
temp1=PID2.target/100;
temp2=(PID2.target-temp1*100)/10;
if(temp2!=9) //還沒滿十
{
WriteData(0x30 + temp1);
WriteData(0x30 + temp2 + 1);
PID2.target += 10;
}
//---------------------------------------------
if(temp2==9) //滿十進1
{
WriteData(0x30 + temp1 + 1);
WriteData('0');
PID2.target += 10;
}
Location(1,3);
flag_num_location=0; //恢復(fù)光標顯示
}
//--------------------------------------------------
else if(flag_num_location==1) //正在修改溫度
{
temp1=PID1.target/100;
temp2=(PID1.target-temp1*100)/10;
if(temp2!=9) //還沒滿十
{
WriteData(0x30 + temp1);
WriteData(0x30 + temp2 + 1);
PID1.target += 10;
}
//---------------------------------------------
if(temp2==9) //滿十進1
{
WriteData(0x30 + temp1 + 1);
WriteData('0');
PID1.target += 10;
}
Location(1,7);
flag_num_location=1; //恢復(fù)光標顯示
}
}
else if(key==DOWN)
{
//按下下移鍵
//-----------------------------------------------------
if(flag_num_location==0) //正在修改高度
{
temp1=PID2.target/100;
temp2=(PID2.target-temp1*100)/10;
if(temp2!=0) //還沒滿十
{
WriteData(0x30 + temp1);
WriteData(0x30 + temp2 - 1);
PID2.target -= 10;
}
//---------------------------------------------
if(temp2==0) //滿十進1
{
WriteData(0x30 + temp1 - 1);
WriteData('9');
PID2.target -= 10;
}
Location(1,3);
flag_num_location=0; //恢復(fù)光標顯示
}
//--------------------------------------------------
else if(flag_num_location==1) //正在修改溫度
{
temp1=PID1.target/100;
temp2=(PID1.target-temp1*100)/10;
if(temp2!=0) //還沒滿十
{
WriteData(0x30 + temp1);
WriteData(0x30 + temp2 - 1);
PID1.target -= 10;
}
//---------------------------------------------
if(temp2==0) //滿十進1
{
WriteData(0x30 + temp1 - 1);
WriteData('9');
PID1.target -= 10;
}
Location(1,7);
flag_num_location=1; //恢復(fù)光標顯示
}
}
}
6.4溫度、高度控制程序
#define TEMPER_SAMPLE 100 //溫度采樣周期 [100*50=5000 ms]
#define TEMPER_P 5 //溫度比例系數(shù) [0.5]
#define TEMPER_I 50 //溫度積分時間 [5000*50=250 000 ms] (縮小100倍,相當于Ki放大100倍)
#define TEMPER_D 600 //溫度微分時間 [600*50=3000 ms]
#define TEMPER_SprH 100 //溫度積分分離上限(10度) 誤差大于該上限時采用積分分離
#define TEMPER_SprL -100 //溫度積分分離下限(-10度) 誤差小于該下限時采用積分分離
#define TEMPER_ErrSumMax 2000 //設(shè)定溫度累積誤差最大值(200度)
#define TEMPER_ErrSumMin -2000 //設(shè)定溫度累積誤差最小值(-200度)
#define HEIGHT_SAMPLE 20 //液位采樣周期 [20*50=1000 ms]
#define HEIGHT_P 4 //液位比例系數(shù) [0.1]
#define HEIGHT_I 10 //液位積分時間 [1000*50=50 000 ms] (縮小100倍,相當于Ki放大100倍)
#define HEIGHT_SprH 50 //液位積分分離上限(5cm) 誤差大于該上限時采用積分分離
#define HEIGHT_SprL -50 //液位積分分離下限(-5cm) 誤差小于該下限時采用積分分離
#define HEIGHT_ErrSumMax 300 //液位累積誤差最大值(30cm)
#define HEIGHT_ErrSumMin -300 //液位累積誤差最小值(-30cm)
#define TEMPER_DDZ_H 5 //溫度死區(qū)上限(0.5度)
#de
收藏
編號:4493579
類型:共享資源
大?。?span id="2ge8ewa" class="font-tahoma">7.99MB
格式:ZIP
上傳時間:2020-01-07
35
積分
- 關(guān) 鍵 詞:
-
超聲波
可控
恒溫
水浴
系統(tǒng)
- 資源描述:
-
超聲波液位可控恒溫水浴系統(tǒng),超聲波,可控,恒溫,水浴,系統(tǒng)
展開閱讀全文
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
裝配圖網(wǎng)所有資源均是用戶自行上傳分享,僅供網(wǎng)友學(xué)習交流,未經(jīng)上傳用戶書面授權(quán),請勿作他用。