基于STM32设计的数显热水器

发布者:LogicLeaper最新更新时间:2023-08-15 来源: elecfans关键字:STM32  传感器 手机看文章 扫描二维码
随时随地手机看文章

一、项目介绍

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


二、设计流程

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 SET

     GPIO_ResetBits(GPIOB, GPIO_Pin_6); //RST RESET

     GPIO_SetBits(GPIOB, GPIO_Pin_6);   //RST SET

 

     write_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);

    }

    ...

}


关键字:STM32  传感器 引用地址:基于STM32设计的数显热水器

上一篇:通过STM32实现PWM呼吸灯的教程
下一篇:基于STM32设计的人体健康检测仪

推荐阅读最新更新时间:2024-11-16 22:16

IAR在STM32的配置方法
1. 建立工程项目文件 新建一个文件夹来存放整个工程项目,在该项目文件夹下建立几个子文件夹存放不同类别的文件: i.将官方模板中的stm32f10x_conf.h、stm32f10x_it.c、stm32f10x_it.h和空白main.c文件复制到该项目文件夹下; ii. Obj-存放工程文件,将官方模板中的cortexm3_macro.s、lnkarm_flash.xcl、lnkarm_ram.xcl和stm32f10x_vector.c文件复制到该文件夹下。 iii.library-存放STM32 FWLib文件,将官方提供的固件库library复制到该文件夹下。 2. 在IAR中建立工程 打开IAR,在Project菜
[单片机]
IAR在<font color='red'>STM32</font>的配置方法
STM32寄存器编程思路 - 从51到stm32开发入门,真干货
本文转自 https://www.amobbs.com/thread-5462507-1-3.html 第23楼 尊重原作不做任何修改 =============以下正文=============== 本来只是路过,写详细一点。 我看楼主浮躁得不得了。现在什么都不要做了,先去看几遍《不要做浮躁的嵌入式工程师》这篇文章,想清楚了, 再动手吧。 我做了个实例,不用ST的库来点LED,解答你的问题 我的 KeilMDK 3.5 我的STM32板子奋斗版是 ,IC 是 STM32F103VET6 调试工具 JLINK V8 LED 接在 PB5 ,高电平点亮 既然楼主说一定懂C语言了,那么对于下面我的问题,不查百度,完全靠自己,懂多少?
[单片机]
STM32学习---GPIO和按键(流水灯学习)
//main的完整过程: int main(void){ LED_GPIO_CONFIG(); //定义LED灯; KEY_GPIO_CONFIG(); //定义按键; //循环判断按键的过程: while(1){ if((KEY_SCANF(GPIOC,GPIO_Pin_5)==0)){ //确定按键完全按下 if(GPIO_ReadOutputDataBit(GPIOD,GPIO_Pin_2)==0) //当灯都亮起时,GPIO_ReadOutputDataBit(GPIOD,GPIO_Pin_2)读到输出数据; GPIO_SetBits(GPIOD,GPIO_Pin_2); //
[单片机]
数据驱动革新 宝马车辆制造工艺抢先看
据外媒报道,车辆打造将生成大量数据,宝马采用智能数据分析(Smart Data Analytics)数据化群集,对数据加以挑选分析,进而强化其生产体系,智能数据分析结果将大幅提升生产及物流等各领域的品质。 智能数据分析:宝马集团借助生产数据的智能化应用,提升了生产效率及品质   宝马基于所获得的数据,对生产工艺及体系方面进行了改进,这将有助于缩短投产准备阶段的时间(前置期,lead times)并降低成本,公司利用其总部及国际生产网络,大力研发新方案。 宝马集团将利用各类创新,提升生产灵活性。该公司采用访问受保护的物品内联网(intranet-of-things)平台,将来自生产及物流环节的大量传感器及处理数据实现网络连通,速度
[嵌入式]
STM32_SPI驱动分析(SD卡)
SD卡有两个可选的通信协议:SD模式和SPI模式。为了电路和程序的简化,选用SPI模式。ZC09的SD与STM32通过SPI1连接。因为STM32内部集成了SPI控制器,所以只需简单的配置,就能实现SPI时序。 一、配置SPI1控制器 1、首先要打开SPI1的时钟,并且要打开SPI1信号线所在GPIO口的时钟。由于SPI1的信号线是在GPIOA上,所以用以下代码打开所需要时钟。这里要注意的是,打开SPI1和GPIOA 最好一起打开,因为本人试过先打开SPI1的时钟,然后再相隔了几行代码后才打开GPIOA的时钟,这样导致SD卡操作失败。 2、将GPIOA的5、6、7脚配置为复用推挽输出、50MHz 。 3、SD
[单片机]
“游览”意法半导体展位,学习创新服务汽车、工业
慕尼黑电子展是一场大型电子集会,几乎包含了电子领域内的所有相关产品和技术,分布在不同的展区,每个展区都人声鼎沸。但要说最热闹的,人数最多的还是半导体展区,在这个展区内聚集了全球芯片TOP 10的厂商,每家厂商的展位都是门庭若市,工作人员向每位感兴趣的参展者展示、讲解自家的产品。在意法半导体( ST Microelectronics,以下简称 ST )的展位,我们记者团也充当了一回游客,由 ST 相关负责人便带领我们开始了ST展位“一日游”,介绍了ST近几年在 汽车电子 和 工业 两个领域的努力。 意法半导体展位 由 汽车电子 和分立器件组成的ADG(Automotive & Discrete Group)是ST业务的重
[汽车电子]
横河产品WT5000高精度功率分析仪发布全新的电流传感器单元
屡获殊荣的横河产品WT5000高精度功率分析仪 发布其全新的电流传感器单元并升级固件 WT5000高精度功率分析仪通过使用内部供电的全新电流传感器单元和支持更快更新率的固件,性能得到进一步增强 近日,横河发布WT5000高精度功率分析仪的全新“电流传感器单元”,并对其固件进行了更新。当企业开发或评价如电动汽车(EV)相关设备或太阳能和风电系统的电子设备时,这些增强功能有助于企业提高其设备性能。 全新“电流传感器单元”使用WT5000的内部DC电源进行供电,无须使用外部电源。这样就简化了测量设置,唯一需要的是电流传感器和一根连接线缆。 有3种传感器连接线缆长度可供选择 - 3米、5米和10米。用户可根据不同的测试环
[物联网]
飞思卡尔接近传感器为便携式应用中的流行触摸控制带来创新
电容式触摸传感器提供智能方法来代替机械按钮,实现多功能界面设计 美国伊利诺斯州ROSEMONT(2007年传感器博览会)-2007年6月12日 -触摸传感器越来越流行,因为越来越多的界面采用触摸面板来可靠地对命令作出响应。作为领先的传感器器件设计和制造商,飞思卡尔半导体通过推出两种高度灵敏的触摸板控制器来满足市场对触摸感应控制的需求。 飞思卡尔的MPR081和 MPR082接近电容式触摸传感控制器旨在通过测量电容来检测触摸。触摸传感器正在成为任何带按钮的界面的必要设备。它们为设计人员提供了一种低成本的方法在各种应用(如接入控制、电器、移动电话、MP3播放器、PC外围设备和远程控制等)中代替机械开关按钮。使用触摸感应控制代替传
[新品]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

更多开源项目推荐
换一换 更多 相关热搜器件
更多往期活动

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved