Skip to main content

STM32 教學系列 第 8 節:I2C 通訊 + DMA

STM32 教學系列 第 8 節:I2C 通訊 + DMA

🎯 學習目標

  1. 理解 I2C 協定 - 掌握時序與尋址方式
  2. I2C 從設備通訊 - 實現感測器讀寫
  3. I2C + DMA - 高效率資料轉移

🎓 I2C 基礎

I2C 特性

  • 序列通訊協定:採用時鐘線 (SCL) 和資料線 (SDA)
  • 開路集電極輸出:需上拉電阻
  • 多主多從:支援多設備連接
  • 速度:標準 100 kHz、快速 400 kHz

I2C 信號線

訊號 GPIO 功能
SCL PB6 時鐘線(串列時脈)
SDA PB7 資料線(序列資料)

I2C 尋址

I2C 使用 7 位或 10 位地址識別設備。常見感測器地址示例:

  • MPU6050:0x68(加速度計+陀螺儀)
  • BMP280:0x77(氣壓計)
  • EEPROM:0x50~0x57

🛠️ 硬體連接

組件 接腳 連接
SCL PB6 I2C1_SCL(4.7kΩ 上拉至 3.3V)
SDA PB7 I2C1_SDA(4.7kΩ 上拉至 3.3V)
VCC 3.3V 電源
GND GND 地線

⚙️ CubeMX 配置

步驟 1:啟用 I2C1

  1. ConnectivityI2C1
  2. 模式設為 I2C

步驟 2:配置 I2C 參數

  • Speed Mode:Fast (400 kHz)
  • Addressing Mode:7-bit

步驟 3:啟用中斷

NVIC Settings 中勾選 I2C1 event interruptI2C1 error interrupt


💻 完整程式碼

/* STM32 Lesson 08 - I2C Communication */

#include "main.h"
#include "i2c.h"
#include "usart.h"

I2C_HandleTypeDef hi2c1;
UART_HandleTypeDef huart1;

/* I2C 寫入函數 */
HAL_StatusTypeDef I2C_Write(uint8_t addr, uint8_t reg, uint8_t data)
{
  uint8_t buffer[2] = {reg, data};
  return HAL_I2C_Master_Transmit(&hi2c1, addr << 1, buffer, 2, 1000);
}

/* I2C 讀取函數 */
HAL_StatusTypeDef I2C_Read(uint8_t addr, uint8_t reg, uint8_t *data, uint16_t size)
{
  HAL_I2C_Master_Transmit(&hi2c1, addr << 1, &reg, 1, 1000);
  return HAL_I2C_Master_Receive(&hi2c1, addr << 1, data, size, 1000);
}

void UART_Print(const char *format, ...);

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_I2C1_Init();
  MX_USART1_UART_Init();

  UART_Print("\r\n=== I2C Test ===\r\n");

  /* 掃描 I2C 上的設備 */
  for (uint8_t addr = 0x08; addr < 0x78; addr++)
  {
    if (HAL_I2C_IsDeviceReady(&hi2c1, addr << 1, 1, 100) == HAL_OK)
    {
      UART_Print("Device found at 0x%X\r\n", addr);
    }
  }

  while (1)
  {
    /* I2C 讀寫操作 */
  }
}

✨ I2C 通訊完成!🚀