目录
一、前言
项目成品图片:
哔哩哔哩视频链接:
STM32智能饮水机/水杯
(资料分享见文末)
二、项目简介
1.功能详解
基于STM32智能饮水机/水杯
功能如下:
- 使用STM32F103C8T6最小系统板作为主控单元
- 防水式DS18B20监测水温,温度小于设置最小值,进行自动加热,直到加热到最大值时停止;
- 液位传感器检测水位,如果水位低于最低的,则启动水泵加水,直到加到高水位触发模块
- 按键设置温度上下限
- OLED显示屏显示测量值
- 手机APP,通过蓝牙接收温度数据以及手动控制加热和加水操作
2.主要器件
- STM32F103C8T6单片机
- OLED 屏幕
- DS18B20温度传感器
- 无接触式液位传感器
- 加热片
- 水泵
- 继电器
- 有源蜂鸣器
- LED灯
- BT04A蓝牙模块
三、原理图设计
四、PCB硬件设计
PCB图
五、程序设计
#include "sys.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "math.h"
#include "delay.h"
#include "gpio.h"
#include "key.h"
#include "oled.h"
#include "usart.h"
#include "ds18b20.h"
/**********************************
变量定义
**********************************/
uint8_t key_num = 0; //按键扫描标志位
uint8_t flag_display = 0; //显示界面标志位
uint32_t time_num = 0; //10ms计时
short temp_value = 0; //温度值
u16 temp_max = 40; //温度最大值
u16 temp_min = 25; //温度最小值
extern uint8_t usart1_buf[256]; //串口1接收数组
char display_buf[32]; //显示缓存区
u8 flag_mode = 0; //模式标志位
/**********************************
函数声明
**********************************/
void Key_function(void); //按键函数
void Monitor_function(void); //监测函数
void Display_function(void); //显示函数
void Manage_function(void); //处理函数
/****
******* 主函数
*****/
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置中断优先分组
Delay_Init(); //延时初始化
Gpio_Init(); //IO初始化
Key_Init(); //按键初始化
Oled_Init(); //OLED初始化
Oled_Clear_All(); //清屏
Usart1_Init(9600); //串口1初始化
while(1)
{
key_num = Chiclet_Keyboard_Scan(0); //按键扫描
if(key_num != 0) //有按键按下
{
switch(key_num)
{
case 1: //按键1,切换设置界面
flag_display++;
if(flag_display >= 3)
flag_display = 0;
Oled_Clear_All(); //清屏
break;
case 2: //按键2
switch(flag_display)
{
case 0: //界面0:
break;
case 1: //界面1:
if(temp_max < 99)
temp_max++;
break;
case 2: //界面2:
if(temp_min < temp_max)
temp_min++;
break;
default:
break;
}
break;
case 3: //按键3
switch(flag_display)
{
case 0: //界面0:
break;
case 1: //界面1:
if(temp_max > temp_min+1)
temp_max --;
break;
case 2: //界面2:
if(temp_min > 0)
temp_min --;
break;
default:
break;
}
break;
default:
break;
}
}
if(flag_display == 0) //测量界面
{
if(time_num % 10 == 0) //获取数据
{
temp_value = DS18B20_Get_Temp();
}
if(time_num % 50 == 0) //发送数据
{
UsartPrintf(USART1,"温度:%d.%dC \r\n",temp_value/10,temp_value%10);
}
if(USART1_WaitRecive() == 0) //如果接收到蓝牙数据
{
switch(usart1_buf[0])
{
case('A'): //A:切换自动模式
flag_mode = 0;
break;
case('B'): //B:
flag_mode = 1;
JS = ~JS;
break;
case('C'): //C:
flag_mode = 1;
JR = ~JR;
break;
default:
break;
}
USART1_Clear();
}
}
switch(flag_display) //根据不同的显示模式标志位,显示不同的界面
{
case 0: //界面0:
Oled_ShowCHinese(1, 0, "温度:");
sprintf(display_buf,"%d.%dC ",temp_value/10,temp_value%10); //显示温度的值
Oled_ShowString(1, 6, display_buf);
break;
case 1: //界面0:
Oled_ShowCHinese(1,0,"设置温度最大值");
if(time_num % 5 == 0)
{
sprintf(display_buf,"%d ",temp_max);
Oled_ShowString(2, 7, display_buf);
}
if(time_num % 10 == 0)
{
Oled_ShowString(2, 7, " ");
}
break;
case 2: //界面1:
Oled_ShowCHinese(1,0,"设置温度最小值");
if(time_num % 5 == 0)
{
sprintf(display_buf,"%d ",temp_min);
Oled_ShowString(2, 7, display_buf);
}
if(time_num % 10 == 0)
{
Oled_ShowString(2, 7, " ");
}
break;
default:
break;
}
if(flag_display == 0) //测量界面
{
if(flag_mode == 0) //自动模式
{
if(temp_value < temp_min*10)
{
JR = 1;
}
else if(temp_value > temp_max*10)
{
JR = 0;
}
if(YW1 == 1)
{
JS = 1;
}
if(YW2 ==0)
{
JS = 0;
}
}
}
else //设置界面
{
JS = 0;
JR = 0;
}
time_num++; //计时变量+1
Delay_ms(10);
if(time_num %10 == 0)
LED_SYS = ~LED_SYS;
if(time_num >= 5000)
{
time_num = 0;
}
}
}
六、实验效果
七、资料内容