基于STM32设计的数显热水器

一、项目介绍

当前介绍的项目是基于 STM32F103ZET6 系列 MCU 设计的数显热水器,通过显示屏来显示热水器的温度及其工作状态,通过 PT100 传感器来检测热水器的温度变化,并通过电加热片实现加热过程,以达到控制热水器温度的目的。

image-20230618142512933

image-20230618142039119

二、设计流程

2.1 硬件选型

  • STM32F103ZET6 系列 MCU
  • OLED 显示屏
  • PT100 温度传感器
  • 电加热片
  • 继电器

2.2 软件设计

(1)显示屏

使用 OLED 显示屏来显示热水器的温度及其工作状态,通过 SPI 接口与 STM32 芯片进行通讯。设计温度值及其单位、热水器工作状态等。

(2)温度传感器

使用 PT100 温度传感器来检测热水器内部温度的变化,并将数据通过 ADC 转换后,传输给 STM32 芯片,以实现对热水器加热过程的控制。

(3)电加热片

使用电加热片模拟热水器加热过程,通过继电器控制电加热片的通断,以调节热水器的温度。

(4)控制系统

通过 STM32 芯片来实现对热水器的控制,读取温度传感器的数据。

三、代码设计

3.1 OLED显示屏

(1)SPI 接口初始化

需要对 STM32F103ZET6 的 SPI 接口进行初始化配置,设置相关的时钟和模式,使其能够与 OLED 显示屏进行通讯。

RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE); // 打开SPI3时钟
SPI_InitTypeDef spi_init_type;
spi_init_type.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
spi_init_type.SPI_Mode = SPI_Mode_Master;
spi_init_type.SPI_DataSize = SPI_DataSize_8b;
spi_init_type.SPI_CPOL = SPI_CPOL_Low;
spi_init_type.SPI_CPHA = SPI_CPHA_1Edge;
spi_init_type.SPI_NSS = SPI_NSS_Soft;
spi_init_type.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; // 设置 SPI 时钟频率为 72 MHz / 32 = 2.25MHz
spi_init_type.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_Init(SPI3, &spi_init_type);
SPI_Cmd(SPI3, ENABLE);

(2)OLED 显示屏初始化

以下是 OLED 显示屏的初始化代码:

void OLED_Init(void) {GPIO_SetBits(GPIOB, GPIO_Pin_6);   //RST SETGPIO_ResetBits(GPIOB, GPIO_Pin_6); //RST RESETGPIO_SetBits(GPIOB, GPIO_Pin_6);   //RST SETwrite_command(0xAE); // 关闭显示write_command(0xD5); // 设置时钟分频因子,震荡频率write_command(0x80); // 分频因子=1 ,震荡频率(fosc)=8MHzwrite_command(0xA8); // 设置驱动路数:MUX(复用方式)write_command(0x1F); // 1/32 duty (0x0F~0x3F)write_command(0xD3); // 设置显示偏移write_command(0x00); // 不偏移write_command(0x40); // 设置显示开始行[5:0], 对于设置了32行的液晶,// 这里的值为0表示从0行开始显示write_command(0x8D); // 对比度设置write_command(0x14); // AHB参考电压256等分 移位[3:0]100[n,1/256]write_command(0x20); // 水平方向上的寻址模式write_command(0x00); // 垂直方向上的寻址模式write_command(0xA1); // 设置段再映射write_command(0xC0); // 设置COM扫描方向write_command(0xDA); // 设置COM引脚硬件配置write_command(0x12);write_command(0x81); // 对比度设置write_command(0xBF); // 设置电荷泵电压write_command(0xD9); // 设置预充电周期write_command(0xF1);write_command(0xDB); // 设置VCOMH电压倍率write_command(0x40);write_command(0xAF); // 打开显示OLED_Clear(); // 清屏
}

(3)OLED 显示函数

接下来编写 OLED 显示函数,实现字符和数字的显示功能。

void OLED_show_string(uint8_t x, uint8_t y, char *str) {uint8_t i = 0;while (str[i] != '\0') {OLED_show_char(x, y + i * 8, str[i]);++i;}
}void OLED_show_char(uint8_t x, uint8_t y, char ch) {uint8_t c = ch - 32;if (c >= 96) return;uint8_t* buffer = (uint8_t*)oled_buffer;uint8_t cx, cy;for (cy = 0; cy < 8; cy++) {uint8_t line = font[c][cy];for (cx = 0; cx < 6; cx++) {if (line & 0x1) {buffer[(y + cy) * OLEDWIDTH + x + cx] = 1;} else {buffer[(y + cy) * OLEDWIDTH + x + cx] = 0;}line >>= 1;}}OLED_Draw_Pixel(x + 6, y, 0);OLED_Draw_Pixel(x + 6, y + 1, 0);OLED_Draw_Pixel(x + 6, y + 6, 0);OLED_Draw_Pixel(x + 6, y + 7, 0);
}

(4)结果显示

在代码中调用 OLED_show_string 函数和 OLED_show_char 函数显示数值和字符。

OLED_Init();
OLED_Clear();
OLED_show_string(0, 0, "HELLO WORLD!");
OLED_show_string(0, 16, "TEMP:20 C");

3.2 测温代码

(1)引脚配置

需要对 STM32F103ZET6 的 IO 口进行配置,将用于连接 PT100 温度传感器的引脚设置为输入模式。

这里以 PA0 引脚作为 PT100 传感器的连接口(即 PT100 三线连接中的 R3 端),代码如下:

GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入模式
GPIO_Init(GPIOA, &GPIO_InitStructure);

(2)ADC 配置

接下来需要对 STM32F103ZET6 的 ADC 进行初始化配置,使其能够读取 PT100 温度传感器输出的电压信号。

这里以 ADC1 通道5 作为读取口,代码如下:

ADC_InitTypeDef ADC_InitStructure;
RCC_ADCCLKConfig(RCC_PCLK2_Div6); // 设置 ADC 时钟为 PCLK2 的 1/6
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // 打开 ADC1 时钟
ADC_DeInit(ADC1); // 初始化 ADC1
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // 连续转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_Cmd(ADC1, ENABLE); // 开启 ADC1

(3)温度转换函数

根据 PT100 温度传感器输出电压与温度的关系,可使用线性函数计算出温度值。

转换公式如下:

Rt = (Vref - Vpt) / Ipt // Rt 为 PT100 的阻值,Vref 为基准电压,Vpt 为 PT100 输出电压,Ipt 为 PT100 驱动电流
Temp = a * Rt + b // Temp 为温度值,a 和 b 为经过拟合后的系数

其中 Rt 的计算需要使用差分运算放大器进行转换,这里不再赘述。假设已经得到 Rt 值,则温度转换函数代码如下:

float PT100_Get_Temperature(float Rt)
{float a = 3.9083e-3f, b = -5.775e-7f, R0 = 100.0f; // 根据实际数据进行拟合得到 a、b 和 R0 的值float Tem, delta;delta = pow(Rt / R0, 2) + a * (Rt / R0) + b;Tem = (delta > 0) ? (-R0*a + sqrt(delta)) / (2 * b) : 0;return Tem;
}

(4)数据采集

根据差分放大器输出的电压值得到 PT100 温度传感器的阻值,再根据阻值计算出实际温度,最后将温度值通过串口打印出来。以下是数据采集代码:

float ADC_Get_Voltage(void)
{float voltage = 0;uint16_t adc_val = 0;ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_239Cycles5); // 配置 ADC 通道5ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 使能软件触发 ADC 转换while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); // 等待转换结束adc_val = ADC_GetConversionValue(ADC1); // 读取 ADC 转换结果voltage = (float)adc_val * 3.3f / 4096; // 计算基准电压return voltage;
}float PT100_Get_Rt(float Vpt)
{float Rsource = 10e3f, Rpt = 100.0f; // Rsource 为差分放大器输出电阻,Rpt 为 PT100 阻值float Ipt = (3.3f - Vpt) / Rsource; // 计算 PT100 驱动电流float Rt = (3.3f - Vpt) / Ipt; // 根据欧姆定律计算出 PT100 阻值return Rt;
}void USART1_Send_Float(float f)
{char buf[32];sprintf(buf, "%.1f\r\n", f); // 转换为字符串while (*buf){USART_SendData(USART1, *buf);while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);buf++;}
}int main(void)
{...while (1){float Vpt = ADC_Get_Voltage(); // 获取差分放大器输出电压float Rt = PT100_Get_Rt(Vpt); // 计算 PT100 阻值float Temp = PT100_Get_Temperature(Rt); // 根据阻值计算温度USART1_Send_Float(Temp); // 将温度值打印到串口delay_ms(500);}...
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/19456.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

结构思考力-有效提升你的工作效率20倍以上

结构思考力是一种帮助人们察觉并改善自身思考结构的思考艺术&#xff0c;它将人们的思维表达以一种逻辑结构的形式来表示&#xff0c;从而简化人与人之间的沟通成本&#xff0c;提高工作效率。每个人思考问题的方式不同&#xff0c;不同的思考结构使人们的注意力的方向也不同&a…

机房环境、动力、网络、安防,帮您提高运维效率,确保机房安全

机房作为单位的核心部门&#xff0c;由计算机、服务器、网络设备、存储设备等关键设备组成&#xff0c;智能化计算机机房这个概念在各个领域中&#xff0c;已经占据了很重要的地位&#xff0c;伴随着国家大力倡导的&#xff0c;东数西算&#xff0c;数字经济、云计算、5G大数据…

IPC进程间通信探索——管道的原理与特点

&#x1f923; 爆笑教程 &#x1f449; 《看表情包学Linux》 &#x1f525; CSDN 累计订阅量破千的火爆 C/C 教程的 2023 重制版&#xff0c;C 语言入门到实践的精品级趣味教程。了解更多&#xff1a; &#x1f449; "不太正经" 的专栏介绍 ← 试读第一章订阅链接&am…

深度学习之tensorboard可视化工具

(1)什么是tensorboard tensorboard是TensorFlow 的一个可视化工具包&#xff0c;提供机器学习实验所需的可视化和工具&#xff0c;该工具的功能如下&#xff1a; 跟踪和可视化指标&#xff0c;例如损失和精度可视化模型图&#xff08;操作和层&#xff09;查看权重、偏差或其…

【动态规划】子序列系列

文章目录 动态规划&#xff08;子序列系列&#xff09;1. 最长递增子序列2. 摆动序列3. 最长递增子序列的个数4. 最长数对链5. 最长定差子序列6. 最长的斐波那契子序列的长度7. 最长等差数列8. 等差数列划分 || - 子序列 动态规划&#xff08;子序列系列&#xff09; 1. 最长递…

mac电脑访问windows共享文件夹连接不上(设置445端口)

前提&#xff1a;首先需要保证mac和windows都在同一局域网内&#xff0c;如果不在肯定是连不上的&#xff0c;就不用往下看了。 事情是这样的&#xff0c;公司入职发了mac电脑&#xff0c;但是我是window重度用户&#xff0c;在折腾mac的过程中&#xff0c;有许多文件需要从wi…

Arcgis 分区统计majority参数统计问题

利用Arcgis 进行分区统计时&#xff0c;需要统计不同矢量区域中栅格数据的众数&#xff08;majority&#xff09;&#xff0c;出现无法统计majority参数问题解决 解决&#xff1a;利用copy raster工具&#xff0c;将原始栅格数据 64bit转为16bit

kotlin 编写一个简单的天气预报app(三)broadcast换成eventbus

使用eventbus替换broadcast 将从Broadcast切换到EventBus有以下几个好处&#xff1a; 解耦性&#xff1a;通过使用EventBus&#xff0c;您可以实现组件之间的解耦。传统的Broadcast机制需要发送方和接收方明确知道对方的存在&#xff0c;并且需要在代码中设置Intent过滤器和广…

springboot项目如何自动重启(使用Devtools检测修改并自动重启springboot)

1. 问题&#xff1a; 我们在项目开发阶段&#xff0c;可能经常会修改代码&#xff0c;修改完后就要重启Spring Boot。经常手动停止再启动&#xff0c;比较麻烦。 所以我们引入一个Spring Boot提供的开发工具&#xff1b; 只要源码或配置文件发生修改&#xff0c;Spring Boot应用…

4年测试工程师,常用功能测试点总结,“我“不再走弯路...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 输入框测试 1、字…

如何把几个视频合并在一起?视频合并方法分享

当我们需要制作一个比较长的视频时&#xff0c;将多个视频进行合并可以使得整个过程更加高效。此外&#xff0c;合并视频还可以避免出现“剪辑断层”的情况&#xff0c;使得视频内容更加连贯&#xff0c;更加容易被观众理解和接受。再有&#xff0c;合并视频还可以减少视频文件…

原型链污染,nodejs逃逸例子

文章目录 原型链污染原型链污染原理原型链污染小例子 原型链污染题目解析第一题第二题 Nodejs沙箱逃逸方法一方法二 原型链污染 原型链污染原理 原型链 function test(){this.a test; } b new test;可以看到b在实例化为test对象以后&#xff0c;就可以输出test类中的属性a…

“数智新应用”不再是口号,看汽车、医药、制造企业如何突出重围?

近日&#xff0c;以“释放数智生产力”为主题的 Kyligence 用户大会在上海前滩香格里拉大酒店成功举行。大会包含上午的主论坛和下午的 4 场平行论坛&#xff0c;并举办了闭门会议、Open Day 等活动。来自金融、零售、制造、医药等行业的客户及合作伙伴带来了超过 23 场主题演讲…

记录--一个好用的轮子 turn.js 实现仿真翻书的效果

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 国际惯例&#xff0c;官网链接 官网传送门 Github地址 github上有几个demos例子&#xff0c;介绍了基础用法。 我参考官网的例子&#xff0c;写了一个demo示例 安装 turn.js 依赖 jquery 库&#xff0…

Redis Cluster 在Spring中遇到的问题

Redis集群配置可能会在运行时更改。可以添加新节点&#xff0c;可以更改特定插槽的主节点。还有可能因为master宕机或网络抖动等原因&#xff0c;引起了主从切换。 无法感知集群槽位变化 SpringBoot2.x 开始默认使用的 Redis 客户端由 Jedis 变成了 Lettuce&#xff0c;但是当…

2023.7月最新ORACLE考试通过|微思-ORACLE官方授权中心

微思-ORACLE官方授权培训中心 2022 ORACLE OCP考试战报https://blog.csdn.net/XMWS_IT/article/details/125866726?ops_request_misc%257B%2522request%255Fid%2522%253A%2522169089281916800182194373%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&r…

深度学习:BatchNorm、LayerNorm、InstanceNorm、GroupNorm和SwitchableNorm的理解

深度学习&#xff1a;BatchNorm、LayerNorm、InstanceNorm、GroupNorm和SwitchableNorm的理解 深度学习中的NormBatchNormLayerNormInstanceNormGroupNormSwitchableNorm 附录 深度学习中的Norm 在深度学习中会经常遇到BatchNorm、LayerNorm、InstanceNorm和GroupNorm&#xf…

振弦采集仪完整链条的岩土工程隧道安全监测

振弦采集仪完整链条的岩土工程隧道安全监测 隧道工程是一种特殊的地下工程&#xff0c;其建设过程及运行期间&#xff0c;都受到各种内外力的作用&#xff0c;如水压、地震、地质变形、交通荷载等&#xff0c;这些因素都会对隧道的安全性产生影响。因此&#xff0c;对隧道的安…

SpringBoot项目使用MyBatisX+Apifox IDEA 插件快速开发

今天跟大家介绍两个快速开发项目的插件。能大大提高开发效率。希望能帮助到大家。 1、MyBatisX 插件 MyBatis-Plus为我们提供了强大的mapper和service模板&#xff0c;能够大大的提高开发效率。但是在真正开发过程中&#xff0c;MyBatis-Plus并不能为我们解决所有问题&#xf…

AR开发平台 | 探索AR技术在建筑设计中的创新应用与挑战

随着AR技术的不断发展和普及&#xff0c;越来越多的建筑师开始探索AR技术在建筑设计中的应用。AR(增强现实)技术可以通过将虚拟信息叠加到现实场景中&#xff0c;为设计师提供更加直观、真实的建筑可视化效果&#xff0c;同时也可以为用户带来更加沉浸式的体验。 AR开发平台广…