硬件开发_基于STM32单片机的智能鱼缸系统
一.系统概述
- 数据采集:实时监测环境光照强度、温度和水箱液位,并将数据传输至STM32处理。
- 显示:通过显示屏显示光照、温度和液位数据,方便用户获取信息。
- 阈值设置:用户可通过按钮设置温度、液位和光照强度的阈值。
- 温度控制:当温度低于设定值时,自动启动加热器提升环境温度。
- 液位控制:当液位低于设定值时,启动水泵补充水源,保持安全水位。
- 光照控制:当光照低于设定阈值时,控制LED灯亮起,增加环境光照。
- 时钟与定时投喂:集成实时时钟,用户可设定投喂时间,系统在设定时间自动控制舵机旋转进行投喂。
- 无线通信:配备无线通信模块,将实时数据上传至APP,支持用户远程查看和控制。

二.电路设计
电路图采用Altium Designer设计,主要组成如下:
- 主控单元:STM32F103C8T6单片机作为系统核心的最小系统电路。
- 阈值设定:独立按键用于设定阈值,一端接地,另一端连接至单片机GPIO口。
- 数据上传:通过ESP8266-01S模块将检测到的数据上传至APP,使用UART串口与单片机通信。
- 数据显示:0.96寸OLED12864显示屏采用IIC总线与单片机进行连接。
- 温度检测:使用DS18B20传感器进行温度测量,通过单总线与单片机通信。
- 时钟功能:通过DS1302实现时钟功能,SDA、SCK、DAT三根引脚与单片机连接。
- 水位检测:使用铜制水位感应板的电阻式传感器,模拟端与单片机的模拟输入连接。
- 光强检测:光敏电阻模块用于光照强度监测,模拟端与单片机的模拟输入相接。

三.程序设计
#include “stm32f10x.h”
#include “key.h”
#include “sys.h”
#include “delay.h”
#include “Beep_Led_Relay.h”
float pre,ye;u16 temp;
unsigned char wei = 0,shu=0;
extern u8 time_buf[8];
u16 Servor_CPWM_Set_Buffer[9]={1500,1500,1500,1500,1500,1500,1500,1500,1500};
/****************************************
按键初始化函数
****************************************/
void KEY_Init(void) //IO初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_key_GPIO_Port,ENABLE);//使能时钟
GPIO_InitStructure.GPIO_Pin = Key_GPIO_Pin_num|Key_GPIO_Pin_num1|Key_GPIO_Pin_num2|Key_GPIO_Pin_num3|Key_GPIO_Pin_num4;//KEY0-KEY2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
GPIO_Init(Key_GPIO_Port, &GPIO_InitStructure);//初始化GPIO
}
void KEY1_Init(void) //IO初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_key1_GPIO_Port,ENABLE);//使能时钟
GPIO_InitStructure.GPIO_Pin = Key1_GPIO_Pin_num|Key1_GPIO_Pin_num1|Key1_GPIO_Pin_num2|Key1_GPIO_Pin_num3;//KEY0-KEY2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
GPIO_Init(Key1_GPIO_Port, &GPIO_InitStructure);//初始化GPIO
}
/*重量去皮控制按键初始化
以下按键的初始化只针对重量传感器的去皮按键初始化
不是去皮的按键不需要以下
*************************************/
//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//0,没有任何按键按下
//1,KEY0按下
//2,KEY1按下
//3,KEY3按下
//注意此函数有响应优先级,KEY0>KEY1>KEY2!!
u8 KEY_Scan(u8 mode)
{
static u8 key_up=1;//按键按松开标志 static 为了执行该子函数的时候该变量不会每次都会被初始化
if(mode)key_up=1; //支持连按
if(key_up&&(KEY00||KEY10||KEY20))
{
delay_ms(10);//去抖动
key_up=0;
if(KEY00)return KEY0_PRES;
else if(KEY10)return KEY1_PRES;
else if(KEY20)return KEY2_PRES;
}else if(KEY01&&KEY11&&KEY2==1)key_up=1;
return 0;// 无按键按下
}
/*******设定一个参数/
void Limit_Value_Set_1(u16 *B_Ma)
{
u8 Key_Flag=0;
static u8 Parameter_Select=0;
Key_Flag=KEY_Scan(1); //支持连续按
if(Key_FlagKEY0_PRES) //完成需要设定的参数选择
{
Parameter_Select++;
if(Parameter_Select2)
{
Parameter_Select=0;
}
}
if((Parameter_Select1)&&(Key_FlagKEY1_PRES)) //选定参数后++
{
*B_Ma +=1;
}
if((Parameter_Select1)&&(Key_FlagKEY2_PRES)) //选定参数后–
{
B_Ma -=1;
}
}
/设定两个参数/
void Limit_Value_Set_2(u16 *T_Ma,u16 *H_Ma)
{
u8 Key_Flag=0;
static u8 Parameter_Select=0;
Key_Flag=KEY_Scan(1); //支持连续按
if(Key_FlagKEY0_PRES) //完成需要设定的参数选择
{
Parameter_Select++;
if(Parameter_Select3)
{
Parameter_Select=0;
}
}
if((Parameter_Select1)&&(Key_FlagKEY1_PRES)) //选定参数后++
{
*T_Ma +=1;
}
if((Parameter_Select1)&&(Key_FlagKEY2_PRES)) //选定参数后–
{
*T_Ma -=1;
}
if((Parameter_Select2)&&(Key_FlagKEY1_PRES)) //选定参数后++
{
*H_Ma +=1;
}
if((Parameter_Select2)&&(Key_FlagKEY2_PRES)) //选定参数后–
{
*H_Ma -=1;
}
}
/**************************************
判断按键是否按下 完成控制标志位的设定
需要几个按键控制 可以根据设定需要对形参数量进行修改
*****************************************/
void Key_Control_Handle(_Bool *Key_0_Press_Fla,_Bool *Key_1_Press_Fla,u8 *Key_0_Num)
{
u8 Key_Flag=0;
static u8 Key_0_Num_Count=0;
Key_Flag=KEY_Scan(0);//不支持连续按
if(Key_Flag==KEY0_PRES)
{
*Key_0_Press_Fla=1;
Key_0_Num_Count++;
*Key_0_Num=Key_0_Num_Count;
if(Key_0_Num_Count==3)
{
Key_0_Num_Count=0;
*Key_0_Num=*Key_0_Num;
}
}
if(Key_Flag==KEY1_PRES)
{
*Key_1_Press_Fla=1;
}
}
/**************************************
一个按键进行控制
*****************************************/
void One_Key_Control_Handle(_Bool *Key_0_Press_Fla)
{
u8 Key_Flag=0;
Key_Flag=KEY_Scan(0);//不支持连续按
if(Key_Flag==KEY0_PRES)
{
*Key_0_Press_Fla=1;
}
}

四.资料内容

24-32-146
更多推荐



所有评论(0)