热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【毕业设计】物联网智能温控风扇设计与实现stm32单片机嵌入式

文章目录1简介2绪论2.1课题背景3系统设计3.1系统架构3.2硬件部分3.2.1DS18B20简介3.2.2LCD1602液晶屏简介3.3软件部分3.3.1整体软件流程3.3.2


文章目录

  • 1 简介
  • 2 绪论
    • 2.1 课题背景
  • 3 系统设计
    • 3.1 系统架构
    • 3.2 硬件部分
      • 3.2.1 DS18B20 简介
      • 3.2.2 LCD1602 液晶屏简介
    • 3.3 软件部分
      • 3.3.1 整体软件流程
      • 3.3.2 初始化
      • 3.3.3 温度采集与显示
    • 3.4 实现效果
    • 3.5 部分相关代码




1 简介

🔥 Hi,大家好,这里是丹成学长的毕设系列文章!

🔥 对毕设有任何疑问都可以问学长哦!

这两年开始,各个学校对毕设的要求越来越高,难度也越来越大… 毕业设计耗费时间,耗费精力,甚至有些题目即使是专业的老师或者硕士生也需要很长时间,所以一旦发现问题,一定要提前准备,避免到后面措手不及,草草了事。

为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的新项目是

🚩 基于stm32的智能温控风扇设计与实现

🥇学长这里给一个题目综合评分(每项满分5分)


  • 难度系数:4分
  • 工作量:4分
  • 创新点:3分

🧿 选题指导, 项目分享:

https://blog.csdn.net/molodi/article/details/125933857




2 绪论


2.1 课题背景

随着科技的日新月异,智能家居逐渐走入普通家庭,风扇作为基本的家用电器也将成为智能家居的一部分。这里介绍的是以STM32单片机为控制单元并结合嵌入式技术设计的一款具有温控调速、液晶显示温度等信息的智能电风扇。经过前期设计、制作和最终的测试得出,该风扇电源稳定性好,操作方便,运行可靠,功能强大,价格低廉,节约能耗,能够满足用户多元化的需求。该风扇具有的人性化设计和低廉的价格很适合普通用户家庭使用。


3 系统设计


3.1 系统架构

设计采用STM32单片机做主控芯片,通过DS18B20采集温度,将温度显示在LCD1602上。根据温度的不同,利用STM32对风扇进行调速,总体硬件设计如下图所示
在这里插入图片描述


3.2 硬件部分


3.2.1 DS18B20 简介

DS18B20 是美国 DALLAS 半导体公司继 DS1820 之后最新推出的一种改进型智能温度传感器。 与传统的热敏电阻相比, 它能够直接读出被测温度并且可根据实际要求通过简单的编程实现 9~12 位的数字值读数方式。

在这里插入图片描述


3.2.2 LCD1602 液晶屏简介

1602 液晶也叫 1602 字符型液晶, 它是一种专门用来显示字母、 数字、 符号等的点阵型液晶模块。 它由若干个 5X7 或者 5X11 等点阵字符位组成, 每个点阵字符位都可以显示一个字符, 每位之间有一个点距的间隔, 每行之间也有间隔, 起到了字符间距和行间距的作用, 正因为如此所以它不能很好地显示图形

在这里插入图片描述


3.3 软件部分


3.3.1 整体软件流程

控制系统软件使用 C 语言编程。

使用模块化设计, 除主程序外, 还有各功能子程序, 分别执行直流电机驱动调速及温度采集、 显示等功能, 编辑环境采用集成开发环环境 Keil。

程序总体运行流程图如下:

在这里插入图片描述


3.3.2 初始化

系统初始化包括 STM32 系统定时器初始化, GPIO 口初始化以及 LCD1602 初始化等。

在这里插入图片描述


3.3.3 温度采集与显示

DS18B20 温度传感器进行温度采集时, 要依次进行初始化, ROM 操作指令, 存储器操作指令, 数据传输等操作

在这里插入图片描述


3.4 实现效果

在这里插入图片描述

在这里插入图片描述


3.5 部分相关代码


/************************************************作者:丹成学长,Q746876041
************************************************/

1.主函数
#include "stm32f10x.h"
#include "bsp_SysTick.h"
#include
#include "bsp_ds18b20.h"
int main()
{ int PWM,low,zhouqi;
float wendu;int wendu1;zhouqi=500;low=zhouqi-PWM;SysTick_Init();init1602();
lcdpos(1,0);
writestring("TEM: 00.0");GPIO_SetBits(GPIOB,GPIO_Pin_0);
while( DS18B20_Init()) {
lcdpos(0,0);writestring(" no ds18b20 exit");
}lcdpos(0,0);writestring("ds18b20 exit");for(;;){
DS18B20_Get_Temp(wendu);if (wendu<0){ lcdpos(1,4);writestring("-");
}wendu1&#61;wendu*100;lcdpos(1,5);write_dat(wendu1/10000&#43;0x30);
lcdpos(1,6);write_dat(wendu1%10000/1000&#43;0x30);lcdpos(1,7);write_dat(wendu1%1000/100&#43;0x30);lcdpos(1,9);write_dat(wendu1%100/10&#43;0x30);lcdpos(1,10);
write_dat(wendu1%10&#43;0x30);Delay_ms(2000);if(wendu1>30){ low&#61;500;GPIO_SetBits(GPIOB,GPIO_Pin_0);
Delay_ms(PWM);
} if(wendu1<15){ low&#61;0;GPIO_SetBits(GPIOB,GPIO_Pin_0);Delay_ms(PWM);
}if(wendu1>&#61;15&wendu1<20){ low&#61;100;
GPIO_SetBits(GPIOB,GPIO_Pin_0);Delay_ms(PWM);GPIO_ResetBits(GPIOB,GPIO_Pin_0);Delay_ms(low);
} if(wendu1>&#61;20&wendu1<25){
low&#61;200;GPIO_SetBits(GPIOB,GPIO_Pin_0);Delay_ms(PWM);GPIO_ResetBits(GPIOB,GPIO_Pin_0);Delay_ms(low);}if(wendu1>&#61;25&wendu1<30){ low&#61;300;
GPIO_SetBits(GPIOB,GPIO_Pin_0);Delay_ms(PWM);GPIO_ResetBits(GPIOB,GPIO_Pin_0);Delay_ms(low);
}}
}
2.DS18B20 子程序
#include "bsp_ds18b20.h"
/*
* 函数名&#xff1a; DS18B20_GPIO_Config
* 描述 &#xff1a; 配置 DS18B20 用到的 I/O 口
* 输入 &#xff1a; 无
* 输出 &#xff1a; 无
*/

static void DS18B20_GPIO_Config(void)
{
/*定义一个 GPIO_InitTypeDef类型的结构体*/
GPIO_InitTypeDef GPIO_InitStructure;
/*开启 DS18B20_PORT 的外设时钟*/
RCC_APB2PeriphClockCmd(DS18B20_CLK, ENABLE);
/*选择要控制的 DS18B20_PORT 引脚*/
GPIO_InitStructure.GPIO_Pin &#61; DS18B20_PIN;
/*设置引脚模式为通用推挽输出*/
GPIO_InitStructure.GPIO_Mode &#61; GPIO_Mode_Out_PP;
/*设置引脚速率为 50MHz */
GPIO_InitStructure.GPIO_Speed &#61; GPIO_Speed_50MHz;
/*调用库函数&#xff0c; 初始化 DS18B20_PORT*/
GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);
GPIO_SetBits(DS18B20_PORT, DS18B20_PIN);
}
/*
* 函数名&#xff1a; DS18B20_Mode_IPU
* 描述 &#xff1a; 使 DS18B20-DATA 引脚变为输入模式
* 输入 &#xff1a; 无
* 输出 &#xff1a; 无
*/

static void DS18B20_Mode_IPU(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*选择要控制的 DS18B20_PORT 引脚*/
GPIO_InitStructure.GPIO_Pin &#61; DS18B20_PIN;
/*设置引脚模式为浮空输入模式*/
GPIO_InitStructure.GPIO_Mode &#61; GPIO_Mode_IPU;
/*调用库函数&#xff0c; 初始化 DS18B20_PORT*/
GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);
}
/*
* 函数名&#xff1a; DS18B20_Mode_Out_PP
* 描述 &#xff1a; 使 DS18B20-DATA 引脚变为输出模式
* 输入 &#xff1a; 无
* 输出 &#xff1a; 无
*/

static void DS18B20_Mode_Out_PP(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*选择要控制的 DS18B20_PORT 引脚*/
GPIO_InitStructure.GPIO_Pin &#61; DS18B20_PIN;
/*设置引脚模式为通用推挽输出*/
GPIO_InitStructure.GPIO_Mode &#61; GPIO_Mode_Out_PP;
/*设置引脚速率为 50MHz */
GPIO_InitStructure.GPIO_Speed &#61; GPIO_Speed_50MHz;
/*调用库函数&#xff0c; 初始化 DS18B20_PORT*/
GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);
}
/*
*主机给从机发送复位脉冲
*/

static void DS18B20_Rst(void)
{
/* 主机设置为推挽输出 */
DS18B20_Mode_Out_PP();
DS18B20_DATA_OUT(LOW);
/* 主机至少产生 480us 的低电平复位信号 */
Delay_us(750);
/* 主机在产生复位信号后&#xff0c; 需将总线拉高 */
DS18B20_DATA_OUT(HIGH);
Delay_us(15);
}
/*
* 检测从机给主机返回的存在脉冲
* 0&#xff1a; 成功
* 1&#xff1a; 失败
*/

static uint8_t DS18B20_Presence(void)
{
uint8_t pulse_time &#61; 0;
/* 主机设置为上拉输入 */
DS18B20_Mode_IPU();
while( DS18B20_DATA_IN() && pulse_time<100 )
{
pulse_time&#43;&#43;;
Delay_us(1);
}
/ * 经过 100us 后&#xff0c; 存在脉冲都还没有到来*/
if( pulse_time >&#61;100 )
return 1;
else
pulse_time &#61; 0;/* 存在脉冲到来&#xff0c; 且存在的时间不能超过 240us */
while( !DS18B20_DATA_IN() && pulse_time<240 )
{
pulse_time&#43;&#43;;
Delay_us(1);
}
if( pulse_time >&#61;240 )
return 1;
else
return 0;
}
/*
* 从 DS18B20 读取一个 bit
*/

static uint8_t DS18B20_Read_Bit(void)
{
uint8_t dat; /* 读 0 和读 1 的时间至少要大于 60us */
DS18B20_Mode_Out_PP();
/* 读时间的起始&#xff1a; 必须由主机产生 >1us <15us 的低电平信号 */
DS18B20_DATA_OUT(LOW);
Delay_us(10);
/ * 设置成输入&#xff0c; 释放总线&#xff0c; 由外部上拉电阻将总线拉高 */
DS18B20_Mode_IPU();
//Delay_us(2);
if( DS18B20_DATA_IN() &#61;&#61; SET )
dat &#61; 1;
else
dat &#61; 0;
/* 这个延时参数请参考时序图 */
Delay_us(45);
return dat;
}
/*
* 从 DS18B20 读一个字节&#xff0c; 低位先行
*/

uint8_t DS18B20_Read_Byte(void)
{
uint8_t i, j, dat &#61; 0;
for(i&#61;0; i<8; i&#43;&#43;)
{
j &#61; DS18B20_Read_Bit();
dat &#61; (dat) | (j<<i);
}
return dat;
}
/*
* 写一个字节到 DS18B20&#xff0c; 低位先行
*/

void DS18B20_Write_Byte(uint8_t dat)
{
uint8_t i, testb;
DS18B20_Mode_Out_PP();
for( i&#61;0; i<8; i&#43;&#43; )
{
testb &#61; dat&0x01;
dat &#61; dat>>1;
/* 写 0 和写 1 的时间至少要大于 60us */
if (testb)
{
DS18B20_DATA_OUT(LOW);
/* 1us <这个延时 <15us */
Delay_us(8);
DS18B20_DATA_OUT(HIGH);
Delay_us(58);
}
else
{
DS18B20_DATA_OUT(LOW);
/* 60us
Delay_us(70);
DS18B20_DATA_OUT(HIGH);
/* 1us
Delay_us(2);
}
}
}
void DS18B20_Start(void)
{
DS18B20_Rst();
DS18B20_Presence();
DS18B20_Write_Byte(0XCC); /* 跳过 ROM */
DS18B20_Write_Byte(0X44); /* 开始转换 */
}
uint8_t DS18B20_Init(void)
{
DS18B20_GPIO_Config();
DS18B20_Rst();
return DS18B20_Presence();
}
float DS18B20_Get_Temp(float f_tem)
{
uint8_t tpmsb, tplsb;
short s_tem;
DS18B20_Rst();
DS18B20_Presence();
DS18B20_Write_Byte(0XCC); /* 跳过 ROM */
DS18B20_Write_Byte(0X44); /* 开始转换 */
DS18B20_Rst();
DS18B20_Presence();
DS18B20_Write_Byte(0XCC); /* 跳过 ROM */
DS18B20_Write_Byte(0XBE); /* 读温度值 */
tplsb &#61; DS18B20_Read_Byte();
tpmsb &#61; DS18B20_Read_Byte();
s_tem &#61; tpmsb<<8;
s_tem &#61; s_tem | tplsb;
I f( s_tem < 0 ) /* 负温度 */
f_tem &#61; (~s_tem&#43;1) * 0.0625;
else
f_tem &#61; s_tem * 0.0625;
return f_tem;
}


&#x1f9ff; 选题指导, 项目分享&#xff1a;

https://blog.csdn.net/molodi/article/details/125933857


推荐阅读
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了在Spring 3.1中,数据源未能自动连接到@Configuration类的错误原因,并提供了解决方法。作者发现了错误的原因,并在代码中手动定义了PersistenceAnnotationBeanPostProcessor。作者删除了该定义后,问题得到解决。此外,作者还指出了默认的PersistenceAnnotationBeanPostProcessor的注册方式,并提供了自定义该bean定义的方法。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 本文介绍了指针的概念以及在函数调用时使用指针作为参数的情况。指针存放的是变量的地址,通过指针可以修改指针所指的变量的值。然而,如果想要修改指针的指向,就需要使用指针的引用。文章还通过一个简单的示例代码解释了指针的引用的使用方法,并思考了在修改指针的指向后,取指针的输出结果。 ... [详细]
  • C++中的三角函数计算及其应用
    本文介绍了C++中的三角函数的计算方法和应用,包括计算余弦、正弦、正切值以及反三角函数求对应的弧度制角度的示例代码。代码中使用了C++的数学库和命名空间,通过赋值和输出语句实现了三角函数的计算和结果显示。通过学习本文,读者可以了解到C++中三角函数的基本用法和应用场景。 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 成功安装Sabayon Linux在thinkpad X60上的经验分享
    本文分享了作者在国庆期间在thinkpad X60上成功安装Sabayon Linux的经验。通过修改CHOST和执行emerge命令,作者顺利完成了安装过程。Sabayon Linux是一个基于Gentoo Linux的发行版,可以将电脑快速转变为一个功能强大的系统。除了作为一个live DVD使用外,Sabayon Linux还可以被安装在硬盘上,方便用户使用。 ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
author-avatar
手机用户2502892557
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有