STM32 單片機開發 - I2C 總線

一、IIC(I2C) 線的作用

               UART總線
PC端(CPU)    <---------->    開發板(STM32U575RIT6)
                            IIC總線
主控芯片(STM32U575RIT6)    <--------->    傳感器驅動芯片(SHT20/SI7006空氣溫濕度傳感器)

二、I2C 總線的概念

圖 1 I2C 總線示意圖
圖 2 多主機多從機模式示意圖

? ? ? ? I2C 總線也稱為 IIC 總線,中文名:集成電路總線

? ? ? ? I2C 總線由飛利浦公司設計,是 串行、同步、半雙工總線

? ? ? ? I2C 總線硬件連接為:2 根線I2C_SCL 時鐘線I2C_SDA 數據線,都為雙向,如圖 1 所示,SCL 時鐘線和 SDA 數據線都會 外接一個上拉電阻

? ? ? ? I2C 總線的通信速率:

? ? ? ? ? ? ? ? 低速:100 kbps? ? ? ?

????????????????中速:400 kbps? ? ? ?

????????????????高速:3.4 Mbps

? ? ? ? I2C 總線的應用場景:傳感器、OLED 屏……

? ? ? ? I2C 總線支持 主從機模式 (Master / Slaver),支持多主機多從機的模式,一般使用單主機多從機

? ? ? ? ? ? ? ? 發送器:用于發送數據的設備

? ? ? ? ? ? ? ? 接收器:用于接收數據的設備

? ? ? ? ? ? ? ??主機:主動發起數據通信 或者 主動結束數據通信的設備

? ? ? ? ? ? ? ? 從機:被動發起數據通信 或者 被動結束數據通信的設備

? ? ? ??每個掛載在 I2C 總線上的設備,都有一個自己唯一的 7 位設備地址7 位從機地址


三、I2C 總線的硬件連接

3.1 硬件連接

圖 3 I2C 總線硬件連接示意圖

I2C 總線有 2 根線? ?--->? ?I2C_SCL 時鐘線I2C_SDA 數據線

  1. SCL 時鐘線:用于將掛載在 I2C 總線上的設備的時鐘進行同步
  2. SDA 數據線:用于掛載在 I2C 總線上的設備進行數據傳輸

I2C 總線的 SCL 時鐘線和 SDA 數據線都外接一個上拉電阻

作用:

  1. I2C 總線在沒用進行數據通信,即 I2C 總線處于空閑的狀態時,SCL 時鐘線和 SDA 數據線處于高電平狀態
  2. 外接上拉電阻后,可以一定程度上穩定電路減少 I2C 總線傳輸數據的損耗

3.2 單主機多從機的模式

主機:STM32U575RIT6


從機 1:E2PROM????????---????????0x10

從機 2:A / D 模數轉換器? ? ? ? ---? ? ? ? 0x20

從機 3:時鐘日歷? ? ? ? ---? ? ? ? 0x30

從機 4:空氣溫濕度傳感器SHT20? ? ? ? ---? ? ? ? 0x40

1)問題

? ? ? ? 主機想要獲取從機 4 的數據(主機和從機 4 進行數據通信),由于存在 4 個從機設備,主機如何找到從機 4 空氣溫濕度傳感器?

2)解釋

  1. 每個掛載在 I2C 總線上的設備,都有自己的一個唯一的 7 位設備地址(7 位從機地址)
  2. 主機會向掛載在 I2C 總線上的每個從機設備發送想要通信的從機的設備地址
  3. 每個從機都獲取到主機發送的從機地址,和自己的從機地址作比較,如果相等就進行通信,不相等就不通信
  4. 7 位從機地址不是理論上的內存地址(不占用內存空間),只是一個標識符(數字、ID 號)

3.3 多主機多從機的模式

主機 1:STM32U575RIT6? ? ? ? ---????????0x01

主機 2:STM32MP157AAA? ? ? ? ---????????0x02


從機 1:E2PROM? ? ? ? ---????????0x10

從機 2:A/D模數轉換器? ? ? ? ---????????0x20

從機 3:時鐘日歷? ? ? ? ---????????0x30

從機 4:空氣溫濕度傳感器SHT20? ? ? ? ---????????0x40

1)舉例

????????直接編程控制 U5,U5 先給 MP157A 發送數據(命令:讓 MP157A 回復數據),當 MP157A 收到命令后,又會回復數據給 U5

主機:STM32U575RIT6

從機:STM32MP157AAA

  1. STM32U575RIT6 -> STM32MP157AAA (U5 是發送器,MP157A 是接收器)
  2. STM32MP157AAA -> STM32U575RIT6 (MP157A 是發送器,U5 是接收器)

主機和從機都可以擔任發送器和接收器的角色,只是區別在于一個是主動一個是被動

3.3 空氣溫濕度實驗

直接編程控制 -> STM32U575RIT6

獲取空氣溫濕度數據 -> SHT20 / SI7006

                通過IIC總線發送命令
STM32U575RIT6 ---------------------> SHT20/SI7006
                通過IIC總線發送空氣溫濕度數值                    UART總線
SHT20/SI7006  ------------------------------> STM32U575RIT6 -------------> PC端的串口工具

四、I2C 總線的時序圖

時序圖:隨著時鐘線的變化順序,數據線也產生對應變化 / 操作的圖

4.1 起時信號與終止信號的時序圖

圖 4?起時信號與終止信號時序圖

如圖所示:

起始信號(S):當 SCL 時鐘信號處于高電平期間,SDA 數據線從高電平變為低電平 -> 產生一個下降沿信號時,標志著一次 IIC 總線通信的開始;

終止信號(P):當 SCL 時鐘信號處于高電平期間,SDA 數據線從低電平變為高電平 -> 產生一個上升沿信號時,標志著一次 IIC 總線通信的結束。

注意:

  1. 當產生一個起時信號后,IIC 總線處于占用狀態,此時,IIC 總線的 SLC 時鐘線處于低電平狀態
  2. 當產生一個終止信號后,IIC 總線處于空閑狀態,此時,IIC 總線的 SLC 時鐘線處于高電平狀態
  3. 起時信號和終止信號只能由主機產生

4.2 數據傳輸信號的時序圖

圖 5 數據傳輸信號時序圖

如上圖所示,為數據傳輸信號時序圖:

  1. 數據接收信號:當 SCL 時鐘線處于高電平狀態時,SDA 數據線上的數據要求穩定,不允許發生變化,此時接收器從 IIC 總線上讀取數據;
  2. 數據發送信號:當 SCL 時鐘線處于低電平狀態時,SDA 數據線上的數據允許發生變化,此時發送器可以向 IIC 總線上發送數據。

IIC 總線傳輸數據時,數據的最小單位為字節8 位

時鐘周期:一個高電平 + 一個低電平組成的時鐘信號的時間

想要完成一次最小單位的數據收發需要 8 個時鐘周期

4.3 應答信號 / 非應答信號的時序圖

圖 6 應答信號時序圖

如圖所示:

????????主機每 1 個時鐘周期向 I2C 總線上傳輸 1 bit 的數據,I2C 總線的最小傳輸單位為字節(8 bit)

????????I2C 總線每完成一次最小單位的數據傳輸(需要 8 個時鐘周期),接收器在第 9 個時鐘周期需要向發送器回復一個應答 / 非應答信號

  • 應答信號(1 bit)0
  • 非應答信號(1 bit)1

存在 2 種情況:

1. 主機發,從機收
主機:發送器

? ? ? ? 從機:接收器

當主機發送完 1 個字節(8 位)的數據后:

? ? ? ? 主機:接收器

? ? ? ? 從機:發送器

????????從機回復應答信號


2. 主機收,從機發

? ? ? ? 主機:接收器

? ? ? ? 從機:發送器

當從機發送完?1 個字節(8 位)的數據后:
主機:發送器

? ? ? ? 從機:接收器

? ? ? ? 主機回復應答信號

4.4 尋址信號(一種特殊的數據傳輸信號

圖 7 尋址信號數據位

尋址信號:主機發送的用于尋找需要通信的從機的地址信號

  1. 尋址信號一定由主機發送,必須跟在起時信號后
  2. 從機地址是 7 位,而 I2C 總線最小傳輸單位為 8 位,需要添加 1 位,才可以發送
  3. 添加的 1 位是 R / W 位:

????????????????W(0):寫標志位,代表主機向 IIC 總線上寫入數據

????????????????R(1):讀標志位,代表主機要從 IIC 總線上讀取數據

主機想要找到0x40的從機 -----> 主機想要IIC總線上的SDA數據線發送0x40 -------> 尋址信號最低位需要為W(0)

從機的設備地址為:0x40

? ? ? ? 主機發,從機收:尋址信號 -> (0x40 << 1) | 0

? ? ? ? 主機收,從機發:尋址信號 -> (0x40 << 1) | 1

五、IIC 總線的協議格式

IIC 總線協議的組成:起時信號、終止信號、尋址信號、數據傳輸信號、應答 / 非應答信號

5.1 主機向從機發送 1 個字節數據的協議格式

圖 8 主機向從機發送 1 個字節數據協議格式

? ? ? ? 首先主機發送一個起時信號后,緊接著發送一個 7 位從機地址和 1 個 W(0)組合的 8 位尋址信號,收到 1 bit 對應從機的 ACK 信號,再接著發送一個 8 位的寄存器地址尋問從機是否有對應地址寄存器,若有,則從機發送一個 ACK 信號,接著主機再發送 8 位的實際數據,從機接收到后發送一個 ACK 信號,接著由主機發送一個上升沿終止信號結束此次 I2C 通信。

5.2 主機向從機發送多個字節數據的協議格式

1)寄存器地址連續

圖 9?主機向從機發送多個字節數據協議格式(寄存器地址連續)

? ? ? ? 與發送單個數據不同的是,在發送完第 1 個 8 位實際數據后,在收到從機的 ACK 后,主機會繼續發送下一個 8 位數據,數據自動存入 REG + 1 的寄存器中,數據全部發送完畢后,主機發送一個上升沿終止信號結束此次 I2C 通信。

2)寄存器地址不連續

圖 10 主機向從機發送多個字節數據協議格式(寄存器地址不連續)

? ? ? ? 當寄存器地址不連續時,由于要存的新的 8 位寄存器地址是特殊的數據,跟在尋址信號后,而尋址信號必須在起時信號后,所以要存入新寄存器的話,必須先發送終止信號,隨后重新發送起始信號、尋址信號以及新的 8 位寄存器地址。

5.3?主機從從機讀取一個字節數據的協議格式

圖 11?主機從從機讀取一個字節數據協議格式

主機從從機讀取數據時,為什么要讀寫轉換,即先寫后讀,不能直接讀?

  1. 首先主機要先找到從機,向每個從機發送 7 位從機地址,既是發送,就是要先寫;
  2. 主機找到從機后,要詢問從機是否有可用的寄存器地址空間,把?8 位寄存器地址發送給從機,從機判斷;
  3. 只有找到了從機,并且確認寄存器地址存在,才開始從從機中讀取數據。

使用 IIC 總線讀取數據時,為什么主機結束通信前要給從機發送一個 NACK 非應答信號?

? ? ? ? 這是由主機和從機的特性決定

  • 主機主動發起數據通信或者主動結束數據通信的設備,具備主動性
  • 從機被動接收數據通信或者被動結束數據通信的設備,具備被動性

????????如果從機開始給主機發送數據,不讓從機停止發送,他會一直發送,就需要主機給從機發送一個NACK信號,告訴從機結束發送。

5.4?主機從從機讀取多個字節數據的協議格式

圖 12?主機從從機讀取多個字節數據協議格式

六、分析電路圖

6.1 查找引腳

1)找到空氣溫濕度傳感器 SHT20 / SI7006?芯片進行 IIC 總線通信的引腳?

圖 13

I2C1_SCL? ? ? ? --->? ? ? ? PB6

I2C1_SDA? ? ? ? --->? ? ? ? PB7


七、分析芯片手冊(SHT20 / SI7006)

7.1 查找手冊的目的

1)查找信息

  1. SHT20 / SI7006 從機的從機地址
  2. 存儲空氣溫度數據和空氣濕度數值的寄存器地址
  3. 知道當前空氣溫濕度傳感器支持的檢測精度
  4. 將空氣溫濕度模擬量和空氣溫濕度數字量轉換的公式
  5. 空氣溫濕度傳感器的工作環境范圍

7.2 框圖分析

1)總體框圖

圖 14 總體框圖

2)使用 IIC 外設控制器框圖

圖 15?使用 IIC 外設控制器框圖

3)GPIO引腳直接模擬IIC總線協議的時序

圖 16?GPIO 引腳直接模擬 IIC 總線協議時序框圖

7.3 手冊分析

圖 17 SHT20 溫濕度傳感器特性
圖 18?SHT20 溫濕度傳感器誤差
圖 19?SHT20 溫濕度傳感器電器規格

1)7 位設備地址和讀寫標志位

圖 20 設備地址
圖 21?SHT20 溫濕度傳感器協議格式

2)8 位寄存器地址

圖 22?SHT20 溫濕度傳感器 8 位寄存器地址

hold master:保持主機占用模式(單主機模式)
no hold master:不保持主機占用模式(多主機模式)

存儲空氣溫度數字量的寄存器? ? ? ? ---? ? ? ? 0xE3
存儲空氣濕度數字量的寄存器? ? ? ? ---? ? ? ? 0xE5

3)測量精度設置

圖 23 SHT20 溫濕度傳感器測量精度的設置

向用戶寄存器中的第 7 和第 0 位寫入 0b00
指定空氣濕度的測量結果為 12 位的數據
指定空氣溫度的測量結果為 14 位的數據

4)溫濕度測量并轉化需要的時間

圖 24?SHT20 溫濕度傳感器測量時間

5)溫濕度數字量和模擬量轉換公式

圖 25 濕度數字量和模擬量轉換公式

圖 26?溫度數字量和模擬量轉換公式


八、CubeMX 工程配置

圖 27 選擇芯片 STMU575RIT6
打開 STM32CubeMX,點擊創建新工程,如上圖所示,找到 STM32U575RIT6 芯片,雙擊或者點擊右上角的按鈕開始工程。
圖 28 配置引腳 PB6、PB7
單擊 PB6 和 PB7 引腳,分別配置為 I2C1_SCL 和 I2C1_SDA 模式,左側找到 I2C,選擇為 I2C ,下方設置表示:標準速率模式100 kHz 速率使用 7 位從機地址
圖 29 配置引腳 PA9、PA10
為了將獲取到的溫濕度數據顯示出來,需要同過 UART 總線顯示到串口終端上,需要配置 PA9 和 PA10 分別為 USART1_TX 和 USART1_RX 模式,左側找到 USART1,選擇模式為 Asynchronous,可選擇設置速率為 9600 Bit / s 以及數據位個數和是否有校驗位,一般設置為 8N1 格式。
圖 30 打開串行燒錄模式

? ? ? ? 左側找到 DEBUG,選擇 Serial Wire,即打開串行燒錄模式。

????????點擊,設置時鐘頻率:

圖 31 設置工程路徑

? ? ? ? 如圖所示設置工程名字和選擇編輯器 MDK-ARM。

圖 32 生成工程代碼
如圖所示選擇和勾選相關選項后,點擊??直接生成代碼。

九、Keil 工程

9.1 API 接口

圖 33 函數接口

1)主機發送函數 HAL_I2C_Master_Transmit

HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,uint16_t Size, uint32_t Timeout)
功能:

? ? ? ? HAL 庫提供的用于主機向 I2C 總線上發送數據的函數(主機向從機發送數據)

參數:

? ? ? ? hi2c:i2c1 外設控制器的句柄對象

? ? ? ? DevAddress寫權限尋址信號7 位從機地址 + W

? ? ? ? pData:要發送的數據

? ? ? ? Size:要發送的數據的大小,單位位字節

? ? ? ? Timeout:超時檢測時間,當前函數最大支持的阻塞時間,單位為?ms

返回值:

? ? ? ? 執行成功,返回 HAL_OK ( 0?)

? ? ? ? 執行失敗,返回錯誤碼

????????返回值 HAL_StatusTypeDef 枚舉類型如下:

typedef enum
{HAL_OK       = 0x00,HAL_ERROR    = 0x01,HAL_BUSY     = 0x02,HAL_TIMEOUT  = 0x03
} HAL_StatusTypeDef;

2)主機接收函數?HAL_I2C_Master_Receive

HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size,uint32_t Timeout)
功能:

? ? ? ? HAL 提供的用于主機從 I2C 總線上讀取數據的函數(主機從從機讀取數據)

參數:

? ? ? ? hi2c:i2c 外設控制器的句柄對象

? ? ? ? DevAddress讀權限尋址信號7 位從機地址 + R

? ? ? ? pData:要讀取的數據(被讀取的數據所在的存儲器地址)

? ? ? ? Size:要讀取的數據大小(被讀取的數據所在寄存器的容器大小)

? ? ? ? Timeout:超時檢測時間,當前函數執行的最大阻塞時間,單位是?ms

返回值:

????????執行成功,返回 HAL_OK ( 0 )

? ? ? ? 執行失敗,返回錯誤碼

9.2 添加 sht20.c 和 sht20.h 文件

????????我們需要去封裝函數去完成 找到從機溫濕度傳感器并從中獲取溫濕度數據?和 將溫濕度數據的模擬量轉換為模擬量并在串口終端顯示

? ? ? ??在當前工程目錄下創建一個新的文件夾,比如 BSP_SHT20,便于后續管理自己的代碼文件,在 BSP_SHT20 目錄下創建 sht20.c 和 sht.h 文件。

圖 34

? ? ? ? 點擊如圖所示位置,打開如下添加新文件夾到工程的窗口:

圖 35 添加文件夾

? ? ? ? 按如圖方式點擊并輸入和我們所創文件夾名字相同的名字,點擊 Add Files 將 .c 和 .h 文件加入進來。

圖 36

????????在 sht.c 文件中包含 sht.h 文件,并編譯一遍,就可以在左側展開 sht.c 看到 sht.h 文件打開并編輯。

? ? ? ? 注意:

? ? ? ? 如果main.c 文件包含 sht.h 文件時找不到文件,需要添加設置編譯器包含路徑:

? ? ? ??點擊,選擇 C / C++,按下圖設置

圖 37 設置編譯器包含路徑

9.3 代碼

1)sht20.h

#ifndef __SHT20_H
#define __SHT20_H#include "stdint.h"
#include "i2c.h"//STH20從機7位地址
#define SHT20_ADDRESS 0x40
//寫權限尋址信號
#define SHT20_ADDRESS_W	((SHT20_ADDRESS << 1)|0)
//讀權限尋址信號
#define SHT20_ADDRESS_R	((SHT20_ADDRESS << 1)|1)//溫度數據寄存器地址
#define TEMP_CMD 0xE3//濕度數據寄存器地址
#define HUM_CMD 0xE5  //溫濕度數據獲取函數
uint32_t SHT20_Get_Data(uint8_t register_t);//串口顯示函數
void SHT20_Digital_to_Analog(uint16_t temp_digital,uint16_t hum_digital);#endif

2)sht20.c

#include "sht20.h"
#include "main.h"/**函數:SHT20_Get_Data*功能:獲取SHT20空氣溫濕度傳感器采集到的數據(數字量)*參數:空氣溫度數據寄存器的地址/空氣濕度數據寄存器的地址*返回值:獲取到的SHT20傳感器的值*/
uint32_t SHT20_Get_Data(uint8_t register_t)
{uint16_t data;uint8_t buf[2]={0x00, 0x00};//主機發送寫權限尋址信號+8位寄存器地址HAL_I2C_Master_Transmit(&hi2c1, SHT20_ADDRESS_W, &register_t, 1, 5);//主機發送寫權限尋址信號和8位寄存器地址后,開始讀取數據HAL_I2C_Master_Receive(&hi2c1, SHT20_ADDRESS_R, buf, 2, 100);data=(buf[0]<<8 | buf[1]);return data;
}/** 函數:SHT20_Digiatl_To_Analog* 功能:將溫濕度數字量轉換為模擬量并串口顯示* 參數:tem_digital:溫度數字量    hum_digital:濕度數字量* 返回值:無*/
void SHT20_Digital_to_Analog(uint16_t temp_digital,uint16_t hum_digital)
{float tem_analog, hum_analog;tem_analog = temp_digital * 175.72 /65536 - 46.85;hum_analog = hum_digital *125 / 65536 - 6;printf("TEM=%.2f, HUM=%.2f",tem_analog,hum_analog);if(tem_analog>=30){HAL_GPIO_WritePin(GPIOC,GPIO_PIN_7,GPIO_PIN_SET);}else if(tem_analog<30){HAL_GPIO_WritePin(GPIOC,GPIO_PIN_7,GPIO_PIN_RESET);}if(hum_analog>=70){HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);}else if(hum_analog<70){HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);}
}

3)main.h

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.h* @brief          : Header for main.c file.*                   This file contains the common defines of the application.******************************************************************************* @attention** Copyright (c) 2025 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header *//* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H#ifdef __cplusplus
extern "C" {
#endif/* Includes ------------------------------------------------------------------*/
#include "stm32u5xx_hal.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes *//* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET *//* USER CODE END ET *//* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC *//* USER CODE END EC *//* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM *//* USER CODE END EM *//* Exported functions prototypes ---------------------------------------------*/
void Error_Handler(void);/* USER CODE BEGIN EFP *//* USER CODE END EFP *//* Private defines -----------------------------------------------------------*//* USER CODE BEGIN Private defines *//* USER CODE END Private defines */#ifdef __cplusplus
}
#endif#endif /* __MAIN_H */

4)main.c

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2025 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "i2c.h"
#include "usart.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "sht20.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV */
int fputc(int ch, FILE* stream)
{HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 5);return ch;
}
/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void SystemPower_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* Configure the System Power */SystemPower_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_I2C1_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */uint16_t temp,hum;/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){temp=SHT20_Get_Data(TEMP_CMD);hum=SHT20_Get_Data(HUM_CMD);SHT20_Digital_to_Analog(temp,hum);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Configure the main internal regulator output voltage*/if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;RCC_OscInitStruct.MSIState = RCC_MSI_ON;RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_0;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;RCC_OscInitStruct.PLL.PLLMBOOST = RCC_PLLMBOOST_DIV4;RCC_OscInitStruct.PLL.PLLM = 3;RCC_OscInitStruct.PLL.PLLN = 10;RCC_OscInitStruct.PLL.PLLP = 2;RCC_OscInitStruct.PLL.PLLQ = 2;RCC_OscInitStruct.PLL.PLLR = 1;RCC_OscInitStruct.PLL.PLLRGE = RCC_PLLVCIRANGE_1;RCC_OscInitStruct.PLL.PLLFRACN = 0;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2|RCC_CLOCKTYPE_PCLK3;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK){Error_Handler();}
}/*** @brief Power Configuration* @retval None*/
static void SystemPower_Config(void)
{/** Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral*/HAL_PWREx_DisableUCPDDeadBattery();
/* USER CODE BEGIN PWR */
/* USER CODE END PWR */
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/100316.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/100316.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/100316.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Redis 數據結構源碼剖析(SDS、Dict、Skiplist、Quicklist、Ziplist)

Redis 數據結構源碼剖析&#xff08;SDS、Dict、Skiplist、Quicklist、Ziplist&#xff09;1. 前言 Redis 的高性能與豐富數據結構密切相關。 核心數據結構包括&#xff1a; SDS&#xff08;Simple Dynamic String&#xff09;&#xff1a;字符串底層實現。Dict&#xff08;哈希…

無人機圖傳系統的功能解析和技術實現原理

無人機圖傳系統要將機載攝像頭捕捉到的畫面以盡可能低的時延、盡可能高的清晰度、穩定可靠地送達地面操作員或指揮中心&#xff0c;進而驅動現場行動。為此&#xff0c;核心功能可以從四個維度來解構&#xff1a;實時性、畫質與穩定性、覆蓋與冗余、以及安全協同。實時性要求在…

微服務網關的bug

從你提供的Eureka控制臺信息來看&#xff0c;SPRINGCLOUD-PRODUCT已成功注冊到Eureka&#xff0c;且狀態為UP&#xff08;實例地址localhost:springcloud-product:8082&#xff09;&#xff0c;排除了“服務未注冊”“實例離線”的基礎問題。但仍報“負載均衡無可用服務”&…

LeetCode:2.字母異位詞分組

目錄 1.字母異位詞分組 1.字母異位詞分組 對于這道題來說&#xff0c;關鍵的地方在于字母異位詞他們排序后的字符串完全相等&#xff0c;所以我們可以通過哈希表來建設一個字符串和其排序相同的字符串數組的映射關系 class Solution { public:vector<vector<string>…

SwiftData3 一劍封喉:WWDC25 的“數據劍譜”精講,讓 Core Data 老俠原地退休

文章目錄每日一句正能量一、開場白&#xff1a;老兵的隱痛二、SwiftData3 新劍譜總覽三、亮劍&#xff1a;30 行代碼搭一個「跨端秒級同步」的收藏夾1. 鑄劍&#xff1a;聲明模型2. 開鋒&#xff1a;初始化容器3. 出招&#xff1a;SwiftUI7 直接綁四、進階劍氣&#xff1a;Char…

微服務-nacos服務中心

單體與微服務 單體架構&#xff1a;項目所有功能都在一個 war 包 /jar 包里&#xff0c;像商城的訂單、庫存、會員、支付等服務&#xff0c;都打包在一起&#xff0c;部署在 Tomcat 服務器&#xff0c;數據存在 MySQL。 優點&#xff1a;開發簡單&#xff0c;易于理解和維護&am…

嵌入式硬件——IMX6ULL 裸機LED點亮實驗

一. 實驗準備 基于正點原子 IMX6ULL-Mini 開發板&#xff0c;實現 LED 周期性閃爍功能&#xff0c;需完成環境搭建與硬件原理確認兩大核心準備工作。 1.1 開發環境搭建 需在Windows和Ubuntu中安裝工具&#xff0c;確保文件傳輸、交叉編譯、代碼編輯功能正常。1.1.1 跨系統文件傳…

深度學習之PyTorch基本使用(一)

一、PyTorch簡介與安裝1.核心概念PyTorch 是一款 Python 深度學習框架&#xff0c;其核心是張量&#xff08;Tensor&#xff09; —— 元素為同一種數據類型的多維矩陣&#xff0c;以 “類” 的形式封裝&#xff0c;內置了張量運算、處理等方法&#xff0c;是深度學習中數據存儲…

SQLAlchemy -> Base.metadata.create_all(engine )詳解

目錄 一、核心作用 二、是否每次運行項目都會執行&#xff1f; 1. ??典型場景??&#xff08;推薦&#xff09; 2. ??需要避免的情況?? 三、最佳實踐建議 1. ??生產環境?? 2. ??開發/測試環境?? 四、常見問題解答 Q1: 如果表結構改了&#xff0c;creat…

C++異步任務處理與消息可靠性保障指南:從基礎到實戰

在當今多核處理器普及的時代&#xff0c;程序性能和響應能力的提升成為開發者面臨的核心課題。無論是高頻交易系統的毫秒級響應需求、實時游戲引擎的流暢交互體驗&#xff0c;還是網絡服務器的高并發處理能力&#xff0c;異步編程都已成為突破性能瓶頸的關鍵技術[1]。作為高性能…

LazyForEach性能優化:解決長列表卡頓問題

本文將深入解析HarmonyOS中LazyForEach的工作原理、性能優勢、實戰優化技巧及常見問題解決方案&#xff0c;幫助你構建流暢的長列表體驗。 1. LazyForEach 核心優勢與原理 LazyForEach 是鴻蒙ArkUI框架中為高性能列表渲染設計的核心組件&#xff0c;其核心設計思想基于動態加載…

Spring Boot 全棧優化:服務器、數據、緩存、日志的場景應用!

Spring Boot以其“開箱即用”聞名&#xff0c;但默認配置往往在高并發場景下成為瓶頸&#xff1a;Tomcat線程堵塞、數據庫連接耗盡、緩存命中率低下、日志洪水般淹沒磁盤。想象一個電商微服務&#xff0c;峰值流量下響應遲鈍&#xff0c;用戶流失——這不是宿命&#xff0c;而是…

Leetcode sql 50 ~5

select product_idfrom Productswhere low_fats Y and recyclable Y;SQL 規定&#xff1a;null 的比較必須用 is null 或 is not null&#xff0c;不能用普通的等號&#xff08;&#xff09;。# Write your MySQL query statement below select name from Customer where ref…

C#高并發與并行理解處理

目錄 1.什么是IO密集型任務/CPU密集型任務 2.高并發概念和技術實現 2.并行&#xff08;Parallelist&#xff09;概念和技術實現 4.核心區別對比 1.什么是IO密集型任務/CPU密集型任務 1.IO密集型任務&#xff1a; 定義&#xff1a;任務核心邏輯不依賴CPU計算&#xff0c;而是…

正點原子STM32F407 U盤升級程序(IAP)OTA Bootloader APP USB升級+FATFS+USB Host

正點原子STM32F407 U盤升級程序&#xff08;IAP&#xff09;OTA Bootloader APP USB升級FATFSUSB HostChapter0 解決STM32 Bootloader跳轉APP失敗問題問題背景問題描述問題解決原APP跳轉的函數為&#xff1a;修改APP程序main入口處Chapter1 MDK如何生成*.bin格式的文件Chapter2…

MySQL 8.0 在 Ubuntu 22.04 中如何將啟用方式改為mysql_native_password(密碼認證)

MySQL 8.0 在 Ubuntu 22.04 中默認啟用了 auth_socket 認證方式(而非密碼認證),導致 mysql_secure_installation 跳過了 root 密碼設置。這會直接影響后續用 Navicat 連接 MySQL(因為 Navicat 需要密碼登錄),必須手動調整 root 用戶的認證方式并設置密碼。 核心問題:au…

七層網絡協議-面試

七層網絡協議概述七層網絡協議&#xff0c;即OSI&#xff08;Open Systems Interconnection&#xff09;模型&#xff0c;是由國際標準化組織&#xff08;ISO&#xff09;提出的網絡通信框架。它將網絡通信過程劃分為七個層次&#xff0c;每一層負責特定的功能&#xff0c;并通…

【Blender】二次元人物制作【二】:五官的制作

一、制作眼睛 選中眼眶內部的一圈線。shiftD復制出來調整成圓形&#xff0c;然后F快捷鍵填充將眼睛放在眼框內合適的位置&#xff0c;并用i鍵進行幾次內插&#xff0c;做出瞳孔&#xff0c;并且將內部的眼瞳做得稍微向內凹陷一點。二、制作睫毛 選中眼眶上半部分的面&#xff0…

Deepin 25 系統安裝 Docker:完整教程 + 常見問題解決

Deepin 25 系統安裝 Docker&#xff1a;完整教程 常見問題解決 作為基于 Debian 的 Linux 發行版&#xff0c;Deepin 25 因系統目錄&#xff08;如/usr&#xff09;默認只讀的特性&#xff0c;安裝 Docker 時需特殊處理 GPG 公鑰存儲路徑。本文結合社區實踐&#xff0c;整理出…

Redis MySQL小結

問題1&#xff1a;Redis為什么高效&#xff1f;答&#xff1a;基于內存&#xff0c;reactor&#xff0c;value的數據組織&#xff08;五種數據結構&#xff09;&#xff0c;KV的數據組織方式&#xff08;漸進hash&#xff09;問題2&#xff1a;跳表是什么&#xff1f;和紅黑樹的…