文章目录

  • 0 简介
  • 1 项目介绍
  • 2 系统设计
  • 3 恒温控制实现
    • 3.1 功能描述
    • 3.2 PID算法原理
      • 3.2.1 P:比例
      • 3.2.2 I:积分
      • 3.2.3 D:微分
    • 3.3 温控代码实现
  • 4 实现效果
  • 5 最后

0 简介

Hi,大家好,学长今天向大家介绍一个 单片机项目

基于stm32的智能水杯 - 恒温控制

大家可用于 课程设计 或 毕业设计

1 项目介绍

今天向大家介绍学长设计的一个毕设项目,基于STM32单片机控制的智能水杯,可利用插口式电源或无线充电底座为加热器提供能量,并在达到某种饮品所需温度时进行保温。 水杯内置充电电池,可选用 USB 接口或无线充电。 在水杯内部设置无线模块,用户利用上位机与水杯进行匹配进行加热操作,加热完后水杯会通过上位机和液晶显示屏实时反馈液体温度,通过指示灯显示电量情况等,给用户进行提醒。

2 系统设计

该智能水杯控制系统是由 STM32 单片机作为主要控制芯片,接受和发送信号给温度传感器,进行温度检测;温度检测是由温度传感器来执行,实时采集水杯内液体温度并利用 LCD 屏显示; 电池检测由电池电压指示电路进行操控, 实时检测电池电量, 并通过 LED 灯进行提示;内置充电电池充电可提供无线和 USB接口充电方式;控温及发热系统由 PTC 发热体构成, 并利用闭环控制使水杯液体温度恒温;利用无线模块,接收来自手机App所发出的指令, 通过手机App与水杯进行匹配进行加热操作,并反馈水杯的使用状态

系统设计

3 恒温控制实现

智能水杯的核心功能是水温的恒温控制,为了实现这一点,学长选用了以下元器件

stm32f103核心板、L298N模块(当然用MOS管更好)、led一个、NPN三极管一个、蜂鸣器一个、DHT11一个、LCD1602一个、电阻200欧两个、可调电阻10K一个、加热丝一个

3.1 功能描述

用DHT11检测当前环境温湿度,并将数据显示在LCD1602上,在用设定温度与当前温度相减,通过PID算法计算出当前输出脉宽,并将其加在L298N模块中,使加热丝发热,形成一个闭环,经过一段时间温度稳定在设定值。

3.2 PID算法原理

3.2.1 P:比例

成比例地反映控制系统的偏差信号e(t),偏差一旦产生,控制器立即产生控制作用,以减小偏差。当仅有比例控制时系统输出存在稳态误差(Steady-state error)。
P参数越小比例作用越强,动态响应越快,消除误差的能力越强。通常将P参数由大向小调,以能达到最快响应又无超调(或无大的超调)为最佳参数。

3.2.2 I:积分

为消除静差,提高系统的无差度。积分作用的强弱取决于积分时间常数T,T越大,积分作用越弱,反之则越强。

3.2.3 D:微分

反映偏差信号的变化趋势,并能在偏差信号变得太大之前,在系统中引入一个有效的早期修正信号,从而加快系统的动作速度,减少调节时间。在微分控制中,控制器的输出与输入误差信号的微分(即误差的变化率)成正比关系。
D越大,微分作用越强,D越小,微分作用越弱。系统调试时通常把D从小往大调,具体参数由试验决定。

3.3 温控代码实现

LedAndBeep.h

#ifndef _LEDANDBEEP_H
#define _LEDANDBEEP_H#include "sys.h"
#include "DHT11.h"#define led_1 GPIO_SetBits(GPIOB,GPIO_Pin_0)
#define led_0 GPIO_ResetBits(GPIOB,GPIO_Pin_0)#define beep_1 GPIO_SetBits(GPIOB,GPIO_Pin_1)
#define beep_0 GPIO_ResetBits(GPIOB,GPIO_Pin_1)void GPIO_init_Alert(void);
void Delay_ms(int k);
void Alert(void);#endif

LedAndBeep.c

#include "LedAndBeep.h"
#include "PID.h"void GPIO_init_Alert()
{GPIO_InitTypeDef Alert_GPIO;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);Alert_GPIO.GPIO_Mode = GPIO_Mode_Out_PP;Alert_GPIO.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;Alert_GPIO.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &Alert_GPIO);led_0;beep_0;
}void Alert()
{if((DHT_Data[0]>70)||(DHT_Data[0]==70)||(DHT_Data[0]<45)||(DHT_Data[0]==45))//湿度不在45~70之间就报警{led_1;if(pid.C10ms<(pid.T/2))//pid.C10ms在中断函数中,蜂鸣器响的时间小于250msbeep_1;elsebeep_0;}else{led_0;beep_0;}
}

DHT11.h

#ifndef __DHT11_H
#define __DHT11_H
#include "sys.h"   extern char DHT_Data[5];//IO方向设置
#define DHT11_IO_IN()  {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=8<<12;}
#define DHT11_IO_OUT() {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=3<<12;}
IO操作函数
#define DHT11_DQ_OUT PBout(11) //数据端口   PB11输出
#define DHT11_DQ_IN  PBin(11)  //数据端口   PB11输入u8 DHT11_Init(void);//初始化DHT11
u8 DHT11_Read_Data(void);//读取温湿度
u8 DHT11_Read_Byte(void);//读出一个字节
u8 DHT11_Read_Bit(void);//读出一个位
u8 DHT11_Check(void);//检测是否存在DHT11
void DHT11_Rst(void);//复位DHT11
#endif

LCD1602.h

#ifndef LCD1602_H
#define LCD1602_H#include "sys.h"#define RS GPIO_Pin_8    //设置PB8为RS
#define RW GPIO_Pin_6   //PB6为RW
#define EN GPIO_Pin_7   //PB7为EN使能void ReadBusy(void);
void LCD_WRITE_CMD( char CMD );
void LCD_WRITE_StrDATA( char *StrData, char row, char col );
void LCD_WRITE_ByteDATA( char ByteData );
void LCD_INIT(void);
void GPIO_INIT(void);#endif

LCD1602.c

#include "LCD1602.h"
#include "delay.h"void GPIO_INIT(void)
{       //GPIO初始化GPIO_InitTypeDef GPIO;GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); //禁用jtagRCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE );GPIO.GPIO_Pin = EN|RW|RS;GPIO.GPIO_Mode = GPIO_Mode_Out_PP;GPIO.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO);GPIO.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;GPIO.GPIO_Mode = GPIO_Mode_Out_PP;GPIO.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO);}void LCD_INIT(void)
{   //初始化GPIO_INIT();       GPIO_Write(GPIOA, 0x0000);      GPIO_Write(GPIOB, 0x0000);delay_us(500);    LCD_WRITE_CMD(0x38);LCD_WRITE_CMD(0x0d);    //开启光标和闪烁LCD_WRITE_CMD(0x06);LCD_WRITE_CMD(0x01);
}void LCD_WRITE_CMD(char CMD)
{//写入命令函数ReadBusy();GPIO_ResetBits(GPIOB, RS);GPIO_ResetBits(GPIOB, RW);GPIO_ResetBits(GPIOB, EN);GPIO_Write(GPIOA, CMD);       //GPIO_SetBits(GPIOB, EN);GPIO_ResetBits(GPIOB, EN);
}void LCD_WRITE_ByteDATA(char ByteData )
{   //写入单个Byte函数ReadBusy();GPIO_SetBits(GPIOB, RS);GPIO_ResetBits(GPIOB, RW);GPIO_ResetBits(GPIOB, EN);GPIO_Write(GPIOA, ByteData);GPIO_SetBits(GPIOB, EN);GPIO_ResetBits(GPIOB, EN);
}void LCD_WRITE_StrDATA(char *StrData,char row, char col)
{//写入字符串char baseAddr = 0x00;          //定义256位地址if (row){baseAddr = 0xc0;}else{baseAddr = 0x80;                                                                                }    baseAddr += col;while (*StrData != '\0'){LCD_WRITE_CMD( baseAddr );LCD_WRITE_ByteDATA( *StrData);  baseAddr++;             StrData++;}
}void ReadBusy(void)
{       //读忙函数,读忙之前记得更改引脚的工作方式!!!因为STM32的IO不是准双向IOGPIO_InitTypeDef GPIO;GPIO_Write(GPIOA, 0x00ff);  GPIO.GPIO_Pin = GPIO_Pin_7;        //选定GPIOA的第七PinGPIO.GPIO_Mode = GPIO_Mode_IN_FLOATING; //第七Pin的工作方式为浮空输入模式,用于检测LCD1602的忙状态GPIO.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO);GPIO_ResetBits(GPIOB, RS);//RS拉低GPIO_SetBits(GPIOB, RW);//RW拉高GPIO_SetBits(GPIOB, EN);    //使能开while( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_7 )); //读第七Pin状态,如果一直为1则循环等待GPIO_ResetBits(GPIOB, EN);//使能关GPIO.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;       //使GPIOA的状态还原成推挽模式GPIO.GPIO_Mode = GPIO_Mode_Out_PP;GPIO.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO);
}

PID.h

#ifndef PID_H_
#define PID_H_typedef struct Pid
{float Sv;//用户设定值float Pv;float Kp;int T;  //PID计算周期--采样周期float Ti;float Td; float Ek;  //本次偏差float Ek_1;//上次偏差float SEk; //历史偏差之和float Iout;float Pout;float Dout;float OUT0;float OUT;int C1ms;int pwmcycle;//pwm周期int times;
}PID;extern PID pid;void PID_Init(void);
void PID_Calc(void);#endif

PID.c

#include "PID.h"PID pid;void PID_Init()
{pid.Sv=38;//用户设定温度pid.Kp=30;pid.T=400;//PID计算周期pid.Ti=4000000;//积分时间pid.Td=1000;//微分时间pid.pwmcycle=200;//pwm周期200pid.OUT0=1;pid.C1ms=0;
}void PID_Calc()  //pid计算
{float DelEk;float ti,ki;float td;float kd;float out;if(pid.C1ms<(pid.T))  //计算周期未到{return ;}pid.Ek=pid.Sv-pid.Pv;   //得到当前的偏差值pid.Pout=pid.Kp*pid.Ek;      //比例输出pid.SEk+=pid.Ek;        //历史偏差总和DelEk=pid.Ek-pid.Ek_1;  //最近两次偏差之差ti=pid.T/pid.Ti;ki=ti*pid.Kp;pid.Iout=ki*pid.SEk;  //积分输出td=pid.Td/pid.T;kd=pid.Kp*td;pid.Dout=kd*DelEk;    //微分输出out= pid.Pout+ pid.Iout+ pid.Dout;if(out>pid.pwmcycle){pid.OUT=pid.pwmcycle;}else if(out<=0){pid.OUT=pid.OUT0; }else {pid.OUT=out;}pid.Ek_1=pid.Ek;  //更新偏差pid.C1ms=0;
}

main.c

#include "LCD1602.h"
#include "DHT11.h"
#include "LedAndBeep.h"
#include "PID.h"
#include "PWMOUT.h"
#include "delay.h"
#include <string.h>
#include <stdio.h>#define PERIOD    400
#define PRESCALER 36000
void Situation()
{char hum[5]={0},temp[5]={0},PWM[10]={0},arr[5]={0x20,0x20,0x20,0x20,0x20};sprintf(hum,"%d.%d",DHT_Data[0],DHT_Data[1]);sprintf(temp,"%d.%d",DHT_Data[2],DHT_Data[3]);//显示湿度LCD_WRITE_StrDATA( hum,0,5 );   LCD_WRITE_StrDATA("%",0,9 ); //显示温度LCD_WRITE_StrDATA( temp,0,11); LCD_WRITE_StrDATA("C",0,15 );//显示pid.outLCD_WRITE_StrDATA("pid.out:",1,0);  sprintf(PWM,"%f",pid.OUT);PWM[6]='\0';LCD_WRITE_StrDATA(PWM,1,9);
}int main()
{unsigned int num=0;GPIO_init_Alert();Time_init();DHT11_Init();PID_Init();LCD_INIT();  LCD_WRITE_CMD( 0x80 );              LCD_WRITE_CMD(0x0C);    LCD_WRITE_StrDATA( "situ:",0,0 ); TimePwm_init(PERIOD-1,PRESCALER);while(1){while(DHT11_Read_Data());PID_Calc();num=(((pid.OUT*PERIOD)/pid.pwmcycle)-1);TIM_SetCompare2(TIM3,num);Situation();                                                                                                                                                                                   }
}

4 实现效果

5 最后

毕业设计 stm32智能恒温水杯 - 单片机 物联网 嵌入式相关推荐

  1. 毕业设计 Stm32智能感应行李箱 - 单片机 物联网

    本次设计的是基于STM32F103C8T6单片机设计的一款智能行李箱 系统内使用HX711压力传感器模块采集行李箱内的重量数据,使用ULN2003电机驱动模块来驱动两个步进电机 以此来模拟行李箱的移动 ...

  2. 【毕业设计】 stm32智能运动计步系统 - 物联网 嵌入式 单片机

    文章目录 0 前言 1 简介 2 主要器件 3 实现效果 4 设计原理 4.1 MAX30102模块 4.2 GSM模块 4.3 ADXL345加速度传感器 5 部分核心代码 5 最后 0 前言

  3. 毕业设计 stm32智能扫地机器人 - 单片机 嵌入式

    文章目录 0 简介 1 课题背景 2 硬件系统总体框架 2.1 电机驱动 2.2 红外线传感器 2.3 超声波传感器 2.4 MPU6050 2.5 ATK-ESP8266 WI FI 模块 2.6 ...

  4. 毕业设计 STM32老人防摔倒报警系统 - 物联网 嵌入式 单片机

    文章目录 0 前言 1 整体设计 2 硬件电路 3 软件设计 4 跌倒检测算法 5 关键代码 6 最后 0 前言

  5. 毕业设计 STM32智能WiFi天气助手 - 物联网 单片机

    文章目录 0 前言 1 设计内容 2 软件设计 3 关键代码 4 最后 0 前言

  6. 【毕业设计】RFID智能门禁系统 - 单片机 物联网 嵌入式

    文章目录 0 前言 1 简介 2 绪论 2.1 课题背景与目的 3 射频识别 3.1 射频识别技术 3.2 射频识别模块 3.2.1 RFID模块 3.2.2 RFID模块组成 4 系统设计 4.1 ...

  7. 毕业设计 stm32智能语音垃圾分类系统(项目开源)

    文章目录 1 简介 2 绪论 2.1 课题背景与目的 3 系统设计 3.1 系统架构 3.2 硬件部分 3.2.1 传感器模块 3.2.2 语音模块 3.2.3 电机及其驱动模块 3.2.4 稳压模块 ...

  8. 【毕业设计】基于超声波智能跟随小车 - 单片机 物联网 stm32 c51

    文章目录 1 项目简介 2 课题背景 3 硬件说明 3.1 小车硬件设计 3.2 小车底座 3.3 无线收发器 3.4 超声波模块 3.5 直流电机和电源 3.6 目标携带装置 3.7 整体电路图 4 ...

  9. 毕业设计 基于stm32智能火灾监控灭火系统 - 物联网

    基于stm32智能火灾监控灭火系统 本次设计的是基于STM32F103C8T6单片机设计的一款智能灭火器报警系统 通过RC522刷卡可以进行灭火器的加1和减1 通过GPS模块可以检测灭火器的位置 如果 ...

最新文章

  1. xp计算机管理窗口,我的xp系统在“打开”窗口中没有“我的电脑”一项,只有界面、我的文档和界面,怎办?...
  2. Spring Cache 缺陷,我好像有解决方案了
  3. Indesign CS6怎么添加框线_InDesign小小知识库
  4. 面试ASP.NET程序员的笔试题和机试题(转,有点意思,答案不是很标准)
  5. Windows下快速删除上万个文件和子目录
  6. list循环赋值_Python基础 | 0xd 条件判断与循环
  7. android开机动画多长时间_Android系统开机动画的一生
  8. 【转】 基于C#.NET的高端智能化网络爬虫 2
  9. android上传图片失败问题
  10. 【转】HEIF图片存储格式探秘
  11. 安徽大学线性代数习题册(第三章详细解答)
  12. 老码识途——1.1反汇编机器码入门
  13. Landsat 数据其中 Collection 1/2 、Level 1/2、Tier 1/2的区别
  14. 10句话快速提高项目经理的领导力
  15. WebSocket握手总结
  16. 功率放大器驱动容性负载、感性负载,有哪些注意事项?
  17. 【智慧社区】智能路灯系统,打造技术与应用领先的社区路灯
  18. Ant Design of Vue表格中slot-scope=“text, record”
  19. sizeof c语言是什么表达式,C 语言 sizeof() 运算符
  20. Xposed模块深度美化Android

热门文章

  1. (转)List的Stream流操作
  2. 2022最新版中科院SCI期刊分区表-计算机科学大类
  3. AMI主板设置上电自启
  4. 【Unity 3D 学习】 《Unity 3D 游戏开发》(第二版 宣雨凇著) 书中一些名字注解
  5. java注释的三种形式讲解1.2
  6. 卡车图像分离车头、车厢、车轮
  7. 移动机器人多模态自主导航详解
  8. ARKit 1.0☀️ 二、生成首个IOS App
  9. Positive Technologies 公司与摩洛哥商讨成立网络安全合资企业事宜
  10. springboot访问jsp页面