首页 > 原创资讯

基于STM32设计的数显热水器

来源:DS小龙哥-嵌入式技术 时间:2023-06-25 11:55:32

一、项目介绍

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

二、设计流程2.1 硬件选型STM32F103ZET6 系列 MCUOLED显示屏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设计的数显热水器

世界速讯:甘肃省通报表扬一季度“开门红”企业 兰州新区5家企业上榜

全球最大水光互补电站在川投产_世界动态

“618网购节”福品闽货热销近600亿元-当前快播

美国一手造成全球“去美元化”

股价连续20交易日低于1元 A股8家房企锁定退市 还有12家走到退市边缘|全球观焦点

快资讯:美国一火车在桥梁坍塌后落入河中 载有硫磺等危险化学品

中国石油天然气集团有限公司原党组副书记、副总经理徐文荣接受审查调查 环球热讯

广西55万受灾用户恢复供电_通讯

芹菜炒什么比较好吃? 世界观点

《狂飙》赵立冬的手段有多高明?难怪孟德海斗不过人家,还被架空 环球新视野

黑景和的复仇之路刚开启,麻雀即将领取盒饭,还和英寿爆发冲突?

“千万工程”调研行丨浙江丽水:美丽乡村入画来 当前热闻

热点评!安徽多地启动新一轮促消费活动

双鸭山市开展燃气安全大检查_焦点资讯

ITU通过6G框架和总体目标建议书 每日速递

天天播报:张雪峰因过度劳累住院:没说过将近80%的人会失业 今年已捐款150万元

天天资讯:经济日报携手京东发布数据——从企业采购看实体经济活力

全球热点评!蔚来手撕代码题:三个线程循环打印ABC

大逆转!街拍不是随意的,而是小姐姐设下的游戏,董,胡总被骗了

中国农业发展银行总行专家委员会副主任委员赵富洲接受审查调查

她越裹越紧,在座各位都有责任 环球新视野

2023年吉林一级消防工程师报名网站入口及报考流程 环球热点评

多彩民俗点亮即墨古城|全球新动态

聚焦:特斯拉FSD暗藏彩蛋 “埃隆模式”

宜春学院2023年研究生一志愿复试时间安排

至少涨价1500元?iPhone 15备货量曝光:苹果出手近亿台

广东高考今日放榜 深圳中考明日开考

普里戈任接受白俄缓和局势建议 其刑事立案将获撤销 全球聚焦

印尼防疫放出狠招(澎湃新闻:印尼解除所有新冠防疫措施) 焦点观察