0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于STM32设计的数显热水器

DS小龙哥-嵌入式技术 来源:DS小龙哥-嵌入式技术 作者:DS小龙哥-嵌入式技 2023-06-25 09:29 次阅读

一、项目介绍

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

二、设计流程

2.1 硬件选型

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 SET
     GPIO_ResetBits(GPIOB, GPIO_Pin_6); //RST RESET
     GPIO_SetBits(GPIOB, GPIO_Pin_6);   //RST SETwrite_command(0xAE); // 关闭显示
     write_command(0xD5); // 设置时钟分频因子,震荡频率
     write_command(0x80); // 分频因子=1 ,震荡频率(fosc)=8MHz
     write_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] != '') {
         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 通道5
    ADC_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
", 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);
    }
    ...
}

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • OLED
    +关注

    关注

    119

    文章

    6179

    浏览量

    223802
  • STM32
    +关注

    关注

    2265

    文章

    10870

    浏览量

    354692
  • 热水器
    +关注

    关注

    5

    文章

    214

    浏览量

    27056
  • Pt100
    +关注

    关注

    9

    文章

    172

    浏览量

    69077
  • STM32F103ZET6
    +关注

    关注

    9

    文章

    67

    浏览量

    21090
收藏 人收藏

    评论

    相关推荐

    基于STM32设计的太阳能热水器

    本项目使用 STM32F103C8T6 微控制作为核心处理,结合多个传感和执行,实现了太阳能热水
    的头像 发表于 06-26 09:29 2018次阅读
    基于<b class='flag-5'>STM32</b>设计的太阳能<b class='flag-5'>热水器</b>

    燃气热水器的自检方法

    据樱花卫厨的安检技术人员介绍,使用燃气热水器的客户,自行检查非常重要,自检方式也很简便:燃气热水器打开时,看指示灯和数码显示屏显示的内容是否正常,有没有出现故障带;透过热水器的观察孔,观察火苗是否为
    发表于 01-25 16:22

    太空能热水器介绍—摘自《新型热水器的使用与维修》

    `原书信息:新型热水器的使用与维修978-7-111-39381-8辛长平 编著本书主要内容有:基础知识;空气能热水器的性能与工作原理,空气能热水器工作循环系统与主要部件,空气能热水器
    发表于 09-18 10:52

    热水器出现水垢及处理方法

    热水器出现水垢,也许很多人都要问水垢是什么呢?出现水垢又有什么影响?这又该怎么办呢?比如说:家里的热水器看上去明明是好的,但是为什么制热效果不如从前的好呢?每次都要加热很长的时间,并且,相同温度的水
    发表于 06-15 16:51

    【GoKit申请】基于GoKit的智能热水器的设计

    申请理由:家里的热水器既不能显示温度,也不能远程控制,又不能开关控制,很耗电。在物联网时代,作为电子工程师,自己动手开发一个很有必要哦~·!项目描述:利用stm32与温度传感相连,数据采集后发送给
    发表于 11-02 10:47

    热水器问题

    我的智能热水器上电都是待机状态,无法使用智能插座,如何改装或操作
    发表于 02-19 08:59

    如何避免燃气热水器引起的危险

    如何避免燃气热水器引起的危险如何才能避免燃气热水器引起的危险呢?专家介绍,最好的办法是淘汰直排式热水器和寿命到期的热水器,同时使用时
    发表于 02-21 15:48 2343次阅读

    空气能热水器和电热水器哪个好?空气能热水器和电热水器有什么不同

     电热水器是指以电作为能源进行加热的热水器。是与燃气热水器、太阳能热水器相并列的三大热水器之一。电热水器
    发表于 01-03 09:22 3624次阅读

    空气能热水器跟普通热水器有什么区别

    热水器就是指通过各种物理原理,在一定时间内使冷水温度升高变成热水的一种装置。按照原理不同可分为电热水器、燃气热水器、太阳能热水器、磁能
    发表于 01-03 14:14 3878次阅读

    热水器漏电保护跳闸原因

    热水器漏电保护跳闸原因。原因有很多,只有对热水器跳闸和热水器跳闸原因有充分的了解,才能正确判断热水器漏电保护
    的头像 发表于 12-25 15:50 8.1w次阅读

    热水器安全阀的作用

    热水器安全阀适用于电热水器,同时具有止回阀与泄压阀功能,能防止进入电热水器的水倒流及防止电热水器内胆压力偏高时,排泄多余的压力,以保证内胆寿命和避免爆胆事故发生。
    的头像 发表于 01-06 10:42 4.3w次阅读

    热水器和燃气热水器哪个好

    热水器是如今城镇家庭家电必不可以少的产品,电热水器看似简单,但是非常重要,对于初次装修的小白来说,安装前多了解十分有必要。是安装电热水器好还是燃气热水器好呢?
    的头像 发表于 02-28 11:42 3886次阅读

    零冷水热水器与普通热水器的优缺点

    前段时间,朋友家安装的一种叫做“零冷水热水器”引起了我的注意。据了解,这种零冷水热水器可以实现普通热水器无法实现的效果,在使用热水时不需要再等待十几秒钟了,即开即热,大大提升了使用体验
    的头像 发表于 12-05 09:56 8.1w次阅读

    使用STM32热水器控制系统设计

      摘要:针对热水器在智能家居中的实际应用,设计了一种基于STM32热水器控制系统,用户可以远程实现热水器的水温控制。本设计以STM32F
    发表于 07-20 15:02 13次下载

    燃气热水器使用方法 燃气热水器的升大小有什么区别

    燃气热水器是一种通过燃烧燃气产生热能,并将其传递给水的设备,用于供应热水。它是现代家庭生活中常见的一种热水供应方式。本文将介绍燃气热水器的使用方法以及不同升
    的头像 发表于 02-04 16:55 1234次阅读