文章目录[隐藏]
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")
版权声明:本文为CSDN博主「DC-STDIO」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/huawei123444/article/details/121992469
暂无评论