功能介绍:
0.本系统采用STM32F103C8T6作为单片机
1.采用DS1302时钟芯片可实时显示时间,通过四个功能按键可设置投喂等操作定时时间
2.具有WiFi模块可以与手机进行数据传输通信
3.采用防水型的DS18B20传感器可以测量水温
4.采用DC002作为电源接口可直接输入5V给整个系统供电
5.水位传感器可以测量水位的实时情况
6.具备水泵控制电路,根据水位传感器数据判断是否加水;具备加热和投食控制电路。
原理图:
PCB:
主程序:
#define __MIAN_C
#include "main.h"
// 局部变量,用于保存转换计算后的电压值
CreatByte volatile Flag;
enum _MODE_DF_ dispMode;
char dis[16];
volatile u8 setIndex = 0;
volatile u8 feedTime[2] = {18, 0}; //投喂时间18:00
volatile u16 totalFeedTime[3] = {0, 0}; //投喂时间18:00
volatile u8 feedLevel = 1; //投喂量等级
volatile u16 amountOfFeed = 0;
volatile u16 feedDelay = 0; //喂食延迟
uint16_t tempBuf = 0;
float f_temp = 0.0;
volatile uint16_t tempMin = 25; //最低温度
volatile uint16_t tempMax = 40; //最高温度
uint16_t waterLevel = 0;
volatile uint16_t waterLevelLow = 25; //最低水位
volatile uint16_t waterLevelHigh = 35; //最高水位
char command = NULL;
int main(void)
{
// 使用HSI,SYSCLK = 4M * RCC_PLLMul_x, x:[2,3,...16],最高是64MH
HSI_SetSysClock(RCC_PLLMul_2); //使用内部8MHz晶振,并设置PLL输出为8MHz
// 端口初始化
GENERAL_TIM_Init();
GPIO_Config();
DS1302_Init();
USART_Config();
ADCx_Init();
DelayMs(1000);
printf("AT+CIPMUX=1\r\n"); //打开多连接
DelayMs(1000);
printf("AT+CIPSERVER=1,8080\r\n"); //建立服务 端口号为8080
DelayMs(1000);
Key_GPIO_Config();
DelayMs(200);
LCD_GPIO_Init();
LCD_Init();
LCD_DispStr(0, 0, " Welcome! ");
DelayMs(200);
DelayMs(200);
DelayMs(200);
LCD_Clear();
DelayMs(200);
while (1)
{
if (sendFlag == 1)
{
sendFlag = 0;
SendData();
}
if (refreshFlag == 1)
{
refreshFlag = 0;
if (dispMode == NORMAL)
{
DispNormal();
}
if (waterLevel <= waterLevelLow) //水位低于最低水位值,启动水泵继电器
{
RELAY_WATER_ON;
}
else if (waterLevel >= waterLevelHigh) //水位高于最高水位值,关闭水泵继电器
{
RELAY_WATER_OFF;
}
if (f_temp <= tempMin) //温度低于最低温度值,启动加热继电器
{
RELAY_HEAT_ON;
}
else if (f_temp >= tempMax) //温度高于最高温度值,关闭加热继电器
{
RELAY_HEAT_OFF;
}
if (timeBufDec[4] == feedTime[0] && timeBufDec[5] == feedTime[1] && timeBufDec[6] == 0) //到达喂食时间
{
feedDelay = feedLevel * 5; //feedLevel * 1s * 5
}
if (feedDelay > 0) //启动喂食
{
feedDelay--;
amountOfFeed = amountOfFeed + 5; //喂食总量加5g
totalFeedTime[2]++; //秒钟加
if (totalFeedTime[2] == 60)
{
totalFeedTime[2] = 0;
totalFeedTime[1]++;
if (totalFeedTime[1] == 60)
{
totalFeedTime[1] = 0;
totalFeedTime[0]++;
}
}
RELAY_FOOD_ON;
}
else
{
RELAY_FOOD_OFF;
}
}
KeyProcess();
}
}
void DispNormal(void)
{
TIM_ITConfig(GENERAL_TIM2, TIM_IT_Update, DISABLE);
DS1302_ReadTime();
TIM_ITConfig(GENERAL_TIM2, TIM_IT_Update, ENABLE);
sprintf(dis, "%02d/%02d/%02d", (int)timeBufDec[1], (int)timeBufDec[2], (int)timeBufDec[3]);
// sprintf(dis, "%02d/%02d/%02d", timeBufDec[1], timeBufDec[2], timeBufDec[3]);
LCD_DispStr(0, 0, dis);
switch (timeBufDec[7])
{
case 0: LCD_DispStr(10, 0, " Sun."); break;
case 1: LCD_DispStr(10, 0, " Sun."); break;
case 2: LCD_DispStr(10, 0, " Mon."); break;
case 3: LCD_DispStr(10, 0, " Tue."); break;
case 4: LCD_DispStr(10, 0, " Wed."); break;
case 5: LCD_DispStr(10, 0, "Thur."); break;
case 6: LCD_DispStr(10, 0, " Fri."); break;
case 7: LCD_DispStr(10, 0, " Sat."); break;
default: break;
}
TIM_ITConfig(GENERAL_TIM2, TIM_IT_Update, DISABLE);
DS18B20_GetTemp(&tempBuf); //采集温度
f_temp = tempBuf * 0.0625; //温度转换
TIM_ITConfig(GENERAL_TIM2, TIM_IT_Update, ENABLE);
waterLevel = ADC_ConvertedValue; //检测水位值
waterLevel = waterLevel * 100 / 4096;
// sprintf(dis, "%02d:%02d %5.1f", (int)timeBufDec[4], (int)timeBufDec[5], f_temp);
sprintf(dis, "%02d:%02d:%02d %4.1f", (int)timeBufDec[4], (int)timeBufDec[5], (int)timeBufDec[6], f_temp);
LCD_DispStr(0, 1, dis);
// LCD_DispOneChar(11, 1, 0xdf); //摄氏度右上角的°
// LCD_DispOneChar(12, 1, 'C'); //摄氏度右上角的°
sprintf(dis, " %02d", waterLevel);
LCD_DispStr(13, 1, dis);
}
void DispSetRealTime(u8 setIndex)
{
sprintf(dis, "%02d/%02d/%02d", (unsigned int)timeBufDec[1], (unsigned int)timeBufDec[2], (unsigned int)timeBufDec[3]);
LCD_DispStr(0, 0, dis);
switch (timeBufDec[7])
{
case 1: LCD_DispStr(10, 0, " Sun."); break;
case 2: LCD_DispStr(10, 0, " Mon."); break;
case 3: LCD_DispStr(10, 0, " Tue."); break;
case 4: LCD_DispStr(10, 0, " Wed."); break;
case 5: LCD_DispStr(10, 0, "Thur."); break;
case 6: LCD_DispStr(10, 0, " Fri."); break;
case 7: LCD_DispStr(10, 0, " Sat."); break;
default: break;
}
sprintf(dis, " %02d:%02d:%02d ", (unsigned int)timeBufDec[4], (unsigned int)timeBufDec[5], (unsigned int)timeBufDec[6]);
LCD_DispStr(0, 1, dis);
switch (setIndex)
{
case 1: LCD_SetCursor(1, 0, 1); break;
case 2: LCD_SetCursor(4, 0, 1); break;
case 3: LCD_SetCursor(7, 0, 1); break;
case 4: LCD_SetCursor(14, 0, 1); break;
case 5: LCD_SetCursor(5, 1, 1); break;
case 6: LCD_SetCursor(8, 1, 1); break;
case 7: LCD_SetCursor(11, 1, 1); break;
default:break;
}
}
void DispSetWaterLevel(u8 setIndex)
{
LCD_DispStr(0, 0, " Set WaterLevel ");
sprintf(dis, " H:%2d%% L:%2d%% ", waterLevelHigh, waterLevelLow);
LCD_DispStr(0, 1, dis);
switch (setIndex)
{
case 1: LCD_SetCursor(6, 1, 1); break;
case 2: LCD_SetCursor(12, 1, 1); break;
default:;
}
}
void DispSetTemp(u8 setIndex)
{
LCD_DispStr(0, 0, "Set Temperature ");
sprintf(dis, " H:%3d L:%3d ", tempMax, tempMin);
LCD_DispStr(0, 1, dis);
switch (setIndex)
{
case 1: LCD_SetCursor(7, 1, 1); break;
case 2: LCD_SetCursor(13, 1, 1); break;
default:;
}
}
void DispSetFeed(u8 setIndex)
{
sprintf(dis, "FeedTime: %02d:%02d ", (unsigned int)feedTime[0], (unsigned int)feedTime[1]);
LCD_DispStr(0, 0, dis);
sprintf(dis, "FeedLevel: %2d ", (unsigned int)feedLevel);
LCD_DispStr(0, 1, dis);
switch (setIndex)
{
case 1: LCD_SetCursor(11, 0, 1); break;
case 2: LCD_SetCursor(14, 0, 1); break;
case 3: LCD_SetCursor(12, 1, 1); break;
default:break;
}
}
void DispSetTotalFeed(u8 setIndex)
{
sprintf(dis, "Total: %02d:%02d:%02d", (unsigned int)totalFeedTime[0], (unsigned int)totalFeedTime[1], (unsigned int)totalFeedTime[2]);
LCD_DispStr(0, 0, dis);
sprintf(dis, "TotalFeed: %4dg", (unsigned int)amountOfFeed);
LCD_DispStr(0, 1, dis);
switch (setIndex)
{
case 1: LCD_SetCursor(15, 0, 1); break;
case 2: LCD_SetCursor(14, 1, 1); break;
default: break;
}
}
void SendData(void)
{
printf("AT+CIPSEND=0,29\r\n"); //发送29位数据
DelayMs(100);
printf("Water Level:%2d%% Temp:%5.1f'C\r\n", waterLevel, f_temp); //串口发送
DelayMs(100);
}
/*********************************************END OF FILE**********************/