文章目錄
- 1 簡介
- 1 課題背景意義
- 2 課題研究方法
- 3 智能魚缸系統功能要求
- 4 系統結構
- 5 硬體模塊
- 5.1 單片機最小系統
- 5.2 溫度檢測模塊
- 5.3 繼電器模塊
- 5.4 顯示模塊
- 6 實作效果
- 7 關鍵代碼
- 8 最后
1 簡介
Hi,大家好,這里是丹成學長,今天向大家介紹一個 單片機專案
基于單片機的智能魚缸系統設計與實作
大家可用于 課程設計 或 畢業設計
技術解答、畢設幫助、開題指導
print("Q 746876041")
1 課題背景意義
近年以來,隨著我國綜合實力飛速飆升,人們對物質和精神生活質量的要求也不斷提升,各式各樣的智能家居不斷問世并得到消費者的喜愛,因而各樣的智能魚缸作為裝飾品和智能家居的合體應景入駐家庭、辦公室、商場等場所,它不僅可以作為裝飾品給我們帶來視覺享受,緩解精神疲勞,而且將中國傳統水文化引入日常生活,極大的豐富了人們的生活,但目前市面上各式魚缸魚龍混雜,格式各異,大多為非智能,需要手動操作實作溫控,換水,充氧,投食等,這將造成諸多不便,浪費使用者的大量時間精力,且影響魚缸的美觀性,但現代社會生活節奏較快,人們沒有足夠的時間動手照顧魚缸,導致魚缸生物成活率低,因而,現階段智能魚缸具有一定的市場需求,
本課題設計的目的為實作魚缸溫控、換水、充氧、投食的一體化和智能化, 該設計具有科研和實用兩重價值,
2 課題研究方法
本課題設計主要是利用單片機為主控芯片,結合嵌入式技術、傳感器技術、C語言編程等技術設計出滿足功能的智能魚缸系統,總體上,我們首先要根據智能魚缸的使用場合和作業環境明確我們所設計系統所需的總體功能,其次,我們構思出系統的總體框架,繪出硬體和軟體流程框圖,然后根據流程圖著手設計,硬體方面考慮到市場現有的芯片、元器件種類繁多,我們需要斟酌選用滿足系統功能且穩定實惠的元器件,系統軟體編程我們采用模塊化程式設計,先根據系統功能要求構思出出程式框圖,再利用C語言對各個模塊進行編程設計,最后利用KeiluVision5對源程式進行除錯、查錯和修改,最后匯入硬體設備,總體運行系統,確保系統滿足功能要求且能穩定的運行,
3 智能魚缸系統功能要求
該智能魚缸系統的設計是以日常生活中魚缸的養護為背景, 根據當前市場上的需求, 智能魚缸系統需要自動實作自動溫控、 換水、 充氧、 投食等功能,
系統需要穩定運行盡可能避免發生故障, 且需要盡可能的降低成本, 具有實用價值,系統需要對魚缸內部環境進行檢測, 并保持環境引數保持在適宜魚類生存的范圍內, 首先是溫度, 根據了解, 魚類的適宜的生存環境一般都在 22~28℃, 當溫度傳感器檢測到水溫低于 22℃時, 系統啟動加熱器加熱, 當溫度達到 28℃時系統停止加熱, 使溫度在適宜魚類生存的范圍內波動,
其次是充氧, 目前生活中人們無法對充氧做到很好的把控, 長時間不充氧容易導致魚類缺氧死亡, 而一直開啟氧泵無疑是對資源的浪費, 因而, 利用定時控制氧泵開關,保證水中的一定的溶氧量將一定程度上解決上述問題,
魚類的投食頻率一般是 12 小時或者 24 小時, 最佳時間一般在中午這個時間段, 因而可以利用系統的時鐘模塊定時控制投食器,
水回圈主要是為了除去水中的雜質, 改良水質, 可以利用利用系統定時模塊定時開關水泵, 將水通過活性炭海綿等過濾完成凈化, 為魚類提供適宜生存的環境,
4 系統結構
魚類生存的環境要素包含很多, 如光照、 水的溫度、 營養物、雜質含量、 溶氧量、 PH 等等, 在此設計中, 我們主要考慮到魚類生存的四大環境要素:水溫、 水溶氧量、 水雜質含量、 營養物, 而各個要素對應的系統處理功能如下表所示

學長設計的智能魚缸控制系統主要實作自動加熱、 自動水回圈、 自動充氧、 自動投食四個功能, 選用 STC89C52 單片機作為系統核心芯片, 控制溫控模塊、 時鐘模塊和其他一些模塊, 溫度控制模塊中 DS18B20 溫度傳感器負責采集溫度引數傳送至主控芯片,利用繼電器控制加熱器以實作恒溫, 時鐘模塊通過繼電器控制氧泵、 水泵的開關, 實作定時充氧、 定時水回圈, 而自動投食功能利用時鐘模塊控制步進電機來模擬, 系統結構框圖如下圖所示,

5 硬體模塊
5.1 單片機最小系統
本設計采用的是STC89C52單片機芯片,…單片機最小系統電路如圖所示,

(1)復位電路:復位電路的作用就是在程…,
(2)晶振電路:晶振電路為單片…
5.2 溫度檢測模塊
此溫度模塊為DS18B20,主要組成部分由一個…,
該芯片通過引腳2同單片機P1.7口進行對接,…溫度檢測模塊如圖3-3所示,

5.3 繼電器模塊
在排水或者進行投食時均要啟用電機裝置,…繼電器模塊如圖

繼電器一共有6個引腳,…引腳功能如下

5.4 顯示模塊
電路中采用了LCD1602顯示幕,…LCD1602顯示幕如圖所示,

6 實作效果
將各個硬體部分組裝后得到最終實物圖

其中, 1 是 USB 電源介面, 為系統提供 5V 的電源, 2 是按鈕控制開關, 是系統的主開關, 3 是 LCD1602 顯示幕, 用于顯示相關資料, 4 是 DS1302 時鐘芯片, 5 是 24C02存盤芯片, 6 是四個控制按鍵, 用于設定系統引數, 7 是 DS18B20 溫度傳感器, 與用于采集實時溫度值, 8、 9、 10 依次是控制加熱、 充氧、 水回圈的三個繼電器, 11 為用于模擬投食的步進電機, 12 為步進電機電源輸入介面,
自動溫控

學長在演示中用手握住溫度傳感器來模擬加熱器作業水溫上升, 溫度上升超過上限值 31℃時, 繼電器 1 燈滅, 表示模擬加熱器斷電, 加熱結束, 如圖所示, 加熱結束后溫度逐漸降低, 直至溫度再次低于下限溫度值時, 繼電器再次通電, 啟動加熱, 以維持魚缸溫度在一定范圍內波動,

自動投食
根據系統的需求, 投食頻率大致為 24 小時一次, 通過定時開啟投食器來實作, 但為了方便演示, 我們通過按鍵將 Feed Time 設定為系統時間的下一分鐘, 當系統時間達到設定時間, 步進電機轉動, 用于模擬投食,

自動充氧
自動充氧與投食相似, 我們可以設定固定的時間, 為了演示方便, 我們也可以設定在系統時間的下一分鐘, 當系統時間達到設定時間后, 繼電器 2 亮燈開啟, 進行模擬充氧,

7 關鍵代碼
#include"reg52.h"
#include "delay.h"
#include "typedef.h"
#include "1602.h"
#include "key.h"
#include "set.h"
#include "18b20.h"
#include "24c02.h"
#include "ds1302.h"
uchar PageNum=0; //0顯示溫濕度 1顯示溫度和報警數值2顯示濕度和報警數值
float Temp_Data=0;
uchar AlarmTemp[]={32,20}; //高低溫度
unsigned char FeedTime[3]={0}; //喂食時間
unsigned char O2Time[3]={0}; //充氧氣時間
unsigned char LoopTime[3]={0}; //水回圈時間
sbit RELAY1 = P2^2; //加水繼電器
sbit RELAY2 = P2^1; //加熱繼電器
sbit RELAY3 = P2^0; //放水繼電器
sbit ENA=P3^2;
sbit ENB=P3^3;
void TimerInit(void);
void GetTemp(void);
void PageInit(void);
void PageDisplay(void);
void DataLoad(void); //資料加載
void TempInit(void); //
void HeatControl(void); //加熱自動控制
void Timer1_Init(void); //50毫秒@11.0592MHz
void IncO2Control(void);
void FeedControl(void);
void LoopControl(void);
unsigned char FeedSecond=0;
unsigned char O2Second=0;
unsigned int LoopSecond=0;
unsigned char CountTime[3]={0}; //水回圈時間計時
void main(void)
{
Delay_1ms(100);
LCD_Init();
TimerInit();
PageInit();
DataLoad();
TempInit();
Timer1_Init();
while(1)
{
GetTemp();
DS1302_Read();
FeedControl();
HeatControl();
IncO2Control();
PageDisplay();
LoopControl();
Delay_1ms(50);
}
}
void Timer0_Serve(void) interrupt 1
{
TH0 = (65535-20000)/256; //20MS定時
TL0 = (65535-20000)%256;
LCD_Refresh(); //LCD重繪
KEY_Scan();
}
void Timer1_Serve(void) interrupt 3 //50ms定時
{
static unsigned char T50MS=0;
TL1 = 0x00; //設定定時初值
TH1 = 0x4C; //設定定時初值
T50MS++;
if(T50MS>=20)
{
T50MS=0;
CountTime[2]++;
if(CountTime[2]>=60)
{
CountTime[2]=0;
CountTime[1]++;
if(CountTime[1]>=60)
{
CountTime[1]=0;
CountTime[0]++;
if(CountTime[0]>23)
CountTime[0]=0;
}
}
if(FeedSecond>0)
FeedSecond--;
if(O2Second>0)
O2Second--;
if(LoopSecond>0)
{
LoopSecond--;
}
}
}
void HeatControl(void) //加熱控制
{
/*------------------低于下限開始加熱---------------------*/
if(Temp_Data<AlarmTemp[1])
{
RELAY1=0;
}
/*------------------高于上限停止加熱---------------------*/
if(Temp_Data>AlarmTemp[0])
{
RELAY1=1;
}
}
void TimerInit(void)
{
TMOD &= 0xF0;
TMOD |= 0X01; //T1作業在定時模式, T0 作業在8位自動多載計數
TL0 = (65535-20000) % 256; //T0作業在定時模式 50ms定時
TH0 = (65535-20000) / 256;
ET0 = 1;
TR0 = 1;
EA = 1;
}
void PageDisplay(void)
{
/*---------------------------------------------------------*/
if(KeyVal=='E')
{
KeyVal=0;
PageNum++;
if(PageNum>4)
{
PageNum=0;
}
PageInit();
}
/*-------------------------------------------------------*/
switch(PageNum)
{
/*-------------------------------------------------------*/
case 0: //顯示和設定實時時間
{
LCD_DisplayDate(0,Date);
LCD_DisplayTime(16,Time);
if(KeyVal=='S')
{
KeyVal = 0;
SetRTC();
}
}break;
/*-------------------------------------------------------*/
case 1: //顯示實時溫度和上下限值
{
TempDisplay(5,Temp_Data);
DisplayU8(18,AlarmTemp[0]); //
DisplayU8(26,AlarmTemp[1]); //
if(KeyVal=='S')
{
KeyVal=0;
SetTempHigLow(AlarmTemp);
WrToROM(AlarmTemp,5,2); //溫度存盤地址0
}
}break;
/*-------------------------------------------------------*/
case 2:
{
LCD_DisplayTime(16,FeedTime);
if(KeyVal=='S')
{
KeyVal=0;
SetClockTime(FeedTime);
WrToROM(FeedTime,20,3);
}
}break;
/*-------------------------------------------------------*/
case 3:
{
LCD_DisplayTime(16,O2Time);
if(KeyVal=='S')
{
KeyVal=0;
SetClockTime(O2Time);
WrToROM(O2Time,25,3);
}
}break;
/*-------------------------------------------------------*/
case 4:
{
LCD_DisplayTime(16,LoopTime);
if(KeyVal=='S')
{
KeyVal=0;
SetClockTime(LoopTime);
WrToROM(LoopTime,30,3);
}
}break;
default: { PageNum=0; PageInit(); }break;
}
/*-------------------------------------------------------*/
}
void IncO2Control(void)
{
if(1==CompareClock(O2Time,Time))
{
O2Second=60;
}
if(O2Second>0)
RELAY2=0;
else
RELAY2=1;
}
void FeedControl(void)
{
if(1==CompareClock(FeedTime,Time))
{
FeedSecond=10;
}
if(FeedSecond>0)
{
ENA=0;
ENB=1;
}
else
{
ENA=1;
ENB=1;
}
}
void LoopControl(void)
{
if(1==CompareClock(LoopTime,CountTime))
{
CountTime[0]=CountTime[1]=CountTime[2]=0;
LoopSecond=60;
}
if(LoopSecond>0)
{
RELAY3=0;
}
else
{
RELAY3=1;
}
}
8 最后
技術解答、畢設幫助、開題指導
print("Q 746876041")

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/384416.html
標籤:其他
上一篇:“未來工廠”——數字化車間
