<strong id="ctjbx"></strong>

  1. <strong id="ctjbx"></strong>
    <ruby id="ctjbx"></ruby>

    基于STM32設計的數顯熱水器

    來(lái)源:DS小龍哥-嵌入式技術(shù)時(shí)間:2023-06-25 10:19:32
    一、項目介紹

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

    二、設計流程2.1 硬件選型STM32F103ZET6 系列 MCUOLED顯示屏PT100 溫度傳感器電加熱片繼電器2.2 軟件設計

    (1)顯示屏


    (資料圖片僅供參考)

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

    (2)溫度傳感器

    使用 PT100 溫度傳感器來(lái)檢測熱水器內部溫度的變化,并將數據通過(guò) ADC轉換后,傳輸給 STM32 芯片,以實(shí)現對熱水器加熱過(guò)程的控制。

    (3)電加熱片

    使用電加熱片模擬熱水器加熱過(guò)程,通過(guò)繼電器控制電加熱片的通斷,以調節熱水器的溫度。

    (4)控制系統

    通過(guò) STM32 芯片來(lái)實(shí)現對熱水器的控制,讀取溫度傳感器的數據。

    三、代碼設計3.1 OLED顯示屏(1)SPI 接口初始化

    需要對 STM32F103ZET6 的 SPI 接口進(jìn)行初始化配置,設置相關(guān)的時(shí)鐘和模式,使其能夠與 OLED 顯示屏進(jìn)行通訊。

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE); // 打開(kāi)SPI3時(shí)鐘 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 時(shí)鐘頻率為 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); // 設置驅動(dòng)路數:MUX(復用方式)     write_command(0x1F); // 1/32 duty (0x0F~0x3F)     write_command(0xD3); // 設置顯示偏移     write_command(0x00); // 不偏移     write_command(0x40); // 設置顯示開(kāi)始行[5:0], 對于設置了32行的液晶,     // 這里的值為0表示從0行開(kāi)始顯示     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); // 打開(kāi)顯示 ?     OLED_Clear(); // 清屏 }
    (3)OLED 顯示函數

    接下來(lái)編寫(xiě) OLED 顯示函數,實(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)結果顯示

    在代碼中調用 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 口進(jìn)行配置,將用于連接 PT100 溫度傳感器的引腳設置為輸入模式。

    這里以 PA0 引腳作為 PT100 傳感器的連接口(即 PT100 三線(xiàn)連接中的 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 配置

    接下來(lái)需要對 STM32F103ZET6 的 ADC 進(jìn)行初始化配置,使其能夠讀取 PT100 溫度傳感器輸出的電壓信號。

    這里以 ADC1 通道5 作為讀取口,代碼如下:

    ADC_InitTypeDef ADC_InitStructure; RCC_ADCCLKConfig(RCC_PCLK2_Div6); // 設置 ADC 時(shí)鐘為 PCLK2 的 1/6 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // 打開(kāi) ADC1 時(shí)鐘 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); // 開(kāi)啟 ADC1
    (3)溫度轉換函數

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

    轉換公式如下:

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

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

    float PT100_Get_Temperature(float Rt) {     float a = 3.9083e-3f, b = -5.775e-7f, R0 = 100.0f; // 根據實(shí)際數據進(jìn)行擬合得到 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 溫度傳感器的阻值,再根據阻值計算出實(shí)際溫度,最后將溫度值通過(guò)串口打印出來(lái)。以下是數據采集代碼:

    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 轉換    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 驅動(dòng)電流    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);    }    ...}

    審核編輯 黃宇

    標簽:

    責任編輯:FD31
    上一篇:Win10正式版怎么永久激活? win10預覽版和正式版的區別是什么?
    下一篇:最后一頁(yè)

    精彩圖集(熱圖)

    熱點(diǎn)圖集

    最近更新

    信用中國

    • 信用信息
    • 行政許可和行政處罰
    • 網(wǎng)站文章

    久爱免费观看在线精品_亚洲综合一区二区三区_最新国产国模无码视频在线_中文字幕无码精品亚洲资源网久久

      <strong id="ctjbx"></strong>

    1. <strong id="ctjbx"></strong>
      <ruby id="ctjbx"></ruby>