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
    +关注

    关注

    118

    文章

    5986

    浏览量

    221444
  • STM32
    +关注

    关注

    2239

    文章

    10671

    浏览量

    348743
  • 热水器
    +关注

    关注

    5

    文章

    204

    浏览量

    26514
  • Pt100
    +关注

    关注

    9

    文章

    166

    浏览量

    68386
  • STM32F103ZET6
    +关注

    关注

    9

    文章

    67

    浏览量

    20771
收藏 人收藏

    评论

    相关推荐

    如何选购一台称心如意的热水器

    如何选购一台称心如意的热水器 时代的发展,科技的进步,信息产业的快速发展,人们的许多生活节奏是越来越快,经过一天劳累工作,回家享受一个热水浴,在物质文明不断提高的今天已不是一种奢望,热水器已进入
    发表于 12-22 14:37

    热水器的保养和清洁

    热水器的保养和清洁1 内胆每半年清洗一次,清洁方法是首先切断电源,关闭进水阀,然后开启出水阀,将安全阀上的排水开关逆时针旋转90度,自然排净热水器内的水和沉淀物。然后再用自来水
    发表于 02-21 14:44

    热水器加装进水阀门的作用

    1、如果长期不用热水器时,可以关闭进水管路,排空内胆中的水,而不需要在进水管路上想另外的办法加以控制。2、如果热水器需要维修或者清洗内胆,也需要关闭进水管路。方便维修和清洗工作。3、偶尔可能会有水压过高的现象,那么就可以关闭进水阀,避免高压对
    发表于 01-25 16:16

    燃气热水器的自检方法

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

    改进热水器微动开关设计

    `微动开关的动作是有寿命的,生产时,一定是要做MTBF实验的。  为什么不把常闭和常开开关触点反过来用?使热水器启动时,让机械臂按压微动开关弹性触点,这样不是使微动开关里的弹性构件长期处于释放状态
    发表于 01-05 10:37

    热水器的小问题

    家里的热水器打火时,只有滴滴答答的声音,但是没有火,要启动很多次才能打上火,是什么原因?
    发表于 03-18 15:48

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

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

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

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

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

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

    热水器控制

    求单片机的热水器控制设计资料,哪位大神会做热水器控制的仿真啊?求好人分享
    发表于 04-12 18:52

    热水器问题

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

    怎么设计一个热水器的电路呢?

      设计一个热水器的电路需要考虑以下几个因素:  电源电路:热水器需要使用220V交流电源,因此需要选择合适的电源电路,如整流桥、变压等。同时,需要考虑电源电路的保护措施,如过压、过流、过热等
    发表于 04-20 11:40

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

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

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

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

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

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