0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于STM32設(shè)計的數(shù)顯熱水器

DS小龍哥-嵌入式技術(shù) ? 來源:DS小龍哥-嵌入式技術(shù) ? 作者:DS小龍哥-嵌入式技 ? 2023-06-25 09:29 ? 次閱讀

一、項目介紹

當前介紹的項目是基于 STM32F103ZET6 系列 MCU 設(shè)計的數(shù)顯熱水器,通過顯示屏來顯示熱水器的溫度及其工作狀態(tài),通過 PT100 傳感器檢測熱水器的溫度變化,并通過電加熱片實現(xiàn)加熱過程,以達到控制熱水器溫度的目的。

二、設(shè)計流程

2.1 硬件選型

2.2 軟件設(shè)計

(1)顯示屏

使用 OLED 顯示屏來顯示熱水器的溫度及其工作狀態(tài),通過 SPI 接口與 STM32 芯片進行通訊。設(shè)計溫度值及其單位、熱水器工作狀態(tài)等。

(2)溫度傳感器

使用 PT100 溫度傳感器來檢測熱水器內(nèi)部溫度的變化,并將數(shù)據(jù)通過 ADC 轉(zhuǎn)換后,傳輸給 STM32 芯片,以實現(xiàn)對熱水器加熱過程的控制。

(3)電加熱片

使用電加熱片模擬熱水器加熱過程,通過繼電器控制電加熱片的通斷,以調(diào)節(jié)熱水器的溫度。

(4)控制系統(tǒng)

通過 STM32 芯片來實現(xiàn)對熱水器的控制,讀取溫度傳感器的數(shù)據(jù)。

三、代碼設(shè)計

3.1 OLED顯示屏

(1)SPI 接口初始化

需要對 STM32F103ZET6 的 SPI 接口進行初始化配置,設(shè)置相關(guān)的時鐘和模式,使其能夠與 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; // 設(shè)置 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); // 關(guān)閉顯示
     write_command(0xD5); // 設(shè)置時鐘分頻因子,震蕩頻率
     write_command(0x80); // 分頻因子=1 ,震蕩頻率(fosc)=8MHz
     write_command(0xA8); // 設(shè)置驅(qū)動路數(shù):MUX(復用方式)
     write_command(0x1F); // 1/32 duty (0x0F~0x3F)
     write_command(0xD3); // 設(shè)置顯示偏移
     write_command(0x00); // 不偏移
     write_command(0x40); // 設(shè)置顯示開始行[5:0], 對于設(shè)置了32行的液晶,
     // 這里的值為0表示從0行開始顯示
     write_command(0x8D); // 對比度設(shè)置
     write_command(0x14); // AHB參考電壓256等分 移位[3:0]100[n,1/256]
     write_command(0x20); // 水平方向上的尋址模式
     write_command(0x00); // 垂直方向上的尋址模式
     write_command(0xA1); // 設(shè)置段再映射
     write_command(0xC0); // 設(shè)置COM掃描方向
     write_command(0xDA); // 設(shè)置COM引腳硬件配置
     write_command(0x12);
     write_command(0x81); // 對比度設(shè)置
     write_command(0xBF); // 設(shè)置電荷泵電壓
     write_command(0xD9); // 設(shè)置預充電周期
     write_command(0xF1);
     write_command(0xDB); // 設(shè)置VCOMH電壓倍率
     write_command(0x40);
     write_command(0xAF); // 打開顯示
 ?
     OLED_Clear(); // 清屏
 }

(3)OLED 顯示函數(shù)

接下來編寫 OLED 顯示函數(shù),實現(xiàn)字符和數(shù)字的顯示功能。

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)結(jié)果顯示

在代碼中調(diào)用 OLED_show_string 函數(shù)和 OLED_show_char 函數(shù)顯示數(shù)值和字符。

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 溫度傳感器的引腳設(shè)置為輸入模式。

這里以 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); // 設(shè)置 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; // 連續(xù)轉(zhuǎn)換模式
 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)溫度轉(zhuǎn)換函數(shù)

根據(jù) PT100 溫度傳感器輸出電壓與溫度的關(guān)系,可使用線性函數(shù)計算出溫度值。

轉(zhuǎn)換公式如下:

Rt = (Vref - Vpt) / Ipt // Rt 為 PT100 的阻值,Vref 為基準電壓,Vpt 為 PT100 輸出電壓,Ipt 為 PT100 驅(qū)動電流
 Temp = a * Rt + b // Temp 為溫度值,a 和 b 為經(jīng)過擬合后的系數(shù)

其中 Rt 的計算需要使用差分運算放大器進行轉(zhuǎn)換,這里不再贅述。假設(shè)已經(jīng)得到 Rt 值,則溫度轉(zhuǎn)換函數(shù)代碼如下:

float PT100_Get_Temperature(float Rt)
 {
     float a = 3.9083e-3f, b = -5.775e-7f, R0 = 100.0f; // 根據(jù)實際數(shù)據(jù)進行擬合得到 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)數(shù)據(jù)采集

根據(jù)差分放大器輸出的電壓值得到 PT100 溫度傳感器的阻值,再根據(jù)阻值計算出實際溫度,最后將溫度值通過串口打印出來。以下是數(shù)據(jù)采集代碼:

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); // 使能軟件觸發(fā) ADC 轉(zhuǎn)換
    while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); // 等待轉(zhuǎn)換結(jié)束
    adc_val = ADC_GetConversionValue(ADC1); // 讀取 ADC 轉(zhuǎn)換結(jié)果
    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 驅(qū)動電流
    float Rt = (3.3f - Vpt) / Ipt; // 根據(jù)歐姆定律計算出 PT100 阻值
    return Rt;
}

void USART1_Send_Float(float f)
{
    char buf[32];
    sprintf(buf, "%.1f
", f); // 轉(zhuǎn)換為字符串
    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); // 根據(jù)阻值計算溫度
        USART1_Send_Float(Temp); // 將溫度值打印到串口
        delay_ms(500);
    }
    ...
}

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • OLED
    +關(guān)注

    關(guān)注

    119

    文章

    6171

    瀏覽量

    223683
  • STM32
    +關(guān)注

    關(guān)注

    2264

    文章

    10854

    瀏覽量

    354298
  • 熱水器
    +關(guān)注

    關(guān)注

    5

    文章

    213

    瀏覽量

    27041
  • Pt100
    +關(guān)注

    關(guān)注

    9

    文章

    172

    瀏覽量

    69043
  • STM32F103ZET6
    +關(guān)注

    關(guān)注

    9

    文章

    67

    瀏覽量

    21069
收藏 人收藏

    評論

    相關(guān)推薦

    基于STM32設(shè)計的太陽能熱水器

    本項目使用 STM32F103C8T6 微控制作為核心處理,結(jié)合多個傳感和執(zhí)行,實現(xiàn)了太陽能熱水
    的頭像 發(fā)表于 06-26 09:29 ?1961次閱讀
    基于<b class='flag-5'>STM32</b>設(shè)計的太陽能<b class='flag-5'>熱水器</b>

    燃氣熱水器的自檢方法

    據(jù)櫻花衛(wèi)廚的安檢技術(shù)人員介紹,使用燃氣熱水器的客戶,自行檢查非常重要,自檢方式也很簡便:燃氣熱水器打開時,看指示燈和數(shù)碼顯示屏顯示的內(nèi)容是否正常,有沒有出現(xiàn)故障帶;透過熱水器的觀察孔,觀察火苗是否為
    發(fā)表于 01-25 16:22

    太空能熱水器介紹—摘自《新型熱水器的使用與維修》

    `原書信息:新型熱水器的使用與維修978-7-111-39381-8辛長平 編著本書主要內(nèi)容有:基礎(chǔ)知識;空氣能熱水器的性能與工作原理,空氣能熱水器工作循環(huán)系統(tǒng)與主要部件,空氣能熱水器
    發(fā)表于 09-18 10:52

    熱水器出現(xiàn)水垢及處理方法

    熱水器出現(xiàn)水垢,也許很多人都要問水垢是什么呢?出現(xiàn)水垢又有什么影響?這又該怎么辦呢?比如說:家里的熱水器看上去明明是好的,但是為什么制熱效果不如從前的好呢?每次都要加熱很長的時間,并且,相同溫度的水
    發(fā)表于 06-15 16:51

    【GoKit申請】基于GoKit的智能熱水器的設(shè)計

    申請理由:家里的熱水器既不能顯示溫度,也不能遠程控制,又不能開關(guān)控制,很耗電。在物聯(lián)網(wǎng)時代,作為電子工程師,自己動手開發(fā)一個很有必要哦~·!項目描述:利用stm32與溫度傳感相連,數(shù)據(jù)采集后發(fā)送給
    發(fā)表于 11-02 10:47

    熱水器問題

    我的智能熱水器上電都是待機狀態(tài),無法使用智能插座,如何改裝或操作
    發(fā)表于 02-19 08:59

    如何避免燃氣熱水器引起的危險

    如何避免燃氣熱水器引起的危險如何才能避免燃氣熱水器引起的危險呢?專家介紹,最好的辦法是淘汰直排式熱水器和壽命到期的熱水器,同時使用時
    發(fā)表于 02-21 15:48 ?2334次閱讀

    空氣能熱水器和電熱水器哪個好?空氣能熱水器和電熱水器有什么不同

     電熱水器是指以電作為能源進行加熱的熱水器。是與燃氣熱水器、太陽能熱水器相并列的三大熱水器之一。電熱水器
    發(fā)表于 01-03 09:22 ?3601次閱讀

    空氣能熱水器跟普通熱水器有什么區(qū)別

    熱水器就是指通過各種物理原理,在一定時間內(nèi)使冷水溫度升高變成熱水的一種裝置。按照原理不同可分為電熱水器、燃氣熱水器、太陽能熱水器、磁能
    發(fā)表于 01-03 14:14 ?3861次閱讀

    熱水器漏電保護跳閘原因

    熱水器漏電保護跳閘原因。原因有很多,只有對熱水器跳閘和熱水器跳閘原因有充分的了解,才能正確判斷熱水器漏電保護
    的頭像 發(fā)表于 12-25 15:50 ?8.1w次閱讀

    熱水器安全閥的作用

    熱水器安全閥適用于電熱水器,同時具有止回閥與泄壓閥功能,能防止進入電熱水器的水倒流及防止電熱水器內(nèi)膽壓力偏高時,排泄多余的壓力,以保證內(nèi)膽壽命和避免爆膽事故發(fā)生。
    的頭像 發(fā)表于 01-06 10:42 ?4.3w次閱讀

    熱水器和燃氣熱水器哪個好

    熱水器是如今城鎮(zhèn)家庭家電必不可以少的產(chǎn)品,電熱水器看似簡單,但是非常重要,對于初次裝修的小白來說,安裝前多了解十分有必要。是安裝電熱水器好還是燃氣熱水器好呢?
    的頭像 發(fā)表于 02-28 11:42 ?3860次閱讀

    零冷水熱水器與普通熱水器的優(yōu)缺點

    前段時間,朋友家安裝的一種叫做“零冷水熱水器”引起了我的注意。據(jù)了解,這種零冷水熱水器可以實現(xiàn)普通熱水器無法實現(xiàn)的效果,在使用熱水時不需要再等待十幾秒鐘了,即開即熱,大大提升了使用體驗
    的頭像 發(fā)表于 12-05 09:56 ?8.1w次閱讀

    使用STM32熱水器控制系統(tǒng)設(shè)計

      摘要:針對熱水器在智能家居中的實際應用,設(shè)計了一種基于STM32熱水器控制系統(tǒng),用戶可以遠程實現(xiàn)熱水器的水溫控制。本設(shè)計以STM32F
    發(fā)表于 07-20 15:02 ?13次下載

    燃氣熱水器使用方法 燃氣熱水器的升數(shù)大小有什么區(qū)別

    燃氣熱水器是一種通過燃燒燃氣產(chǎn)生熱能,并將其傳遞給水的設(shè)備,用于供應熱水。它是現(xiàn)代家庭生活中常見的一種熱水供應方式。本文將介紹燃氣熱水器的使用方法以及不同升
    的頭像 發(fā)表于 02-04 16:55 ?1191次閱讀