在嵌入式系统开发中,I2C总线因其简单易用、节省引脚的特点,广泛应用于各种传感器和设备的通信。STM32F103作为ST公司的经典MCU系列,具备多个I2C接口,非常适合用于实现I2C通信。在本文中,我们将以STM32F103C8T6为例,展示如何通过STM32的I2C外设与EEPROM芯片进行数据读写。
应用场景在这篇文章中,我们将模拟一个简单的应用场景:通过STM32F103与一颗24C02 EEPROM进行通信。我们将实现以下功能:
- 通过I2C接口写入数据到EEPROM。
- 读取EEPROM中的数据并通过串口输出。
- 实现基本的读写错误检测。
硬件设计硬件连接方面,STM32F103C8T6的I2C1接口使用PB6作为SCL,PB7作为SDA。24C02的SCL和SDA分别连接到STM32的对应引脚,另外需要在I2C总线上拉两个4.7kΩ电阻。
代码实现接下来展示STM32F103使用I2C通信的代码,包括初始化、读写EEPROM数据等。代码采用HAL库进行开发,简化了底层操作。
#include "stm32f1xx_hal.h"
#include "usart.h"
#include "i2c.h"
#define EEPROM_ADDRESS 0xA0 // 24C02的器件地址
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void EEPROM_Write(uint8_t data, uint16_t memAddress);
static uint8_t EEPROM_Read(uint16_t memAddress);
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_I2C1_Init();
// 向EEPROM写入数据
EEPROM_Write(0x55, 0x0001);
HAL_Delay(10);
// 从EEPROM读取数据
uint8_t readData = EEPROM_Read(0x0001);
// 通过串口发送读取到的数据
char msg[50];
sprintf(msg, "Read data: 0x%02X\r\n", readData);
HAL_UART_Transmit(&huart1, (uint8_t *)msg, strlen(msg), HAL_MAX_DELAY);
while (1) {
}
}
// 写数据到EEPROM
static void EEPROM_Write(uint8_t data, uint16_t memAddress) {
uint8_t buffer[2];
buffer[0] = (memAddress >> 8) & 0xFF; // 高地址
buffer[1] = memAddress & 0xFF; // 低地址
HAL_I2C_Mem_Write(&hi2c1, EEPROM_ADDRESS, memAddress, I2C_MEMADD_SIZE_16BIT, &data, 1, HAL_MAX_DELAY);
}
// 从EEPROM读取数据
static uint8_t EEPROM_Read(uint16_t memAddress) {
uint8_t data = 0;
HAL_I2C_Mem_Read(&hi2c1, EEPROM_ADDRESS, memAddress, I2C_MEMADD_SIZE_16BIT, &data, 1, HAL_MAX_DELAY);
return data;
}
// 系统时钟配置函数
void SystemClock_Config(void) {
// 此处省略系统时钟配置代码
}
// GPIO初始化
static void MX_GPIO_Init(void) {
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
代码解析- I2C初始化:我们使用STM32的HAL库提供的I2C初始化函数MX_I2C1_Init()来设置I2C接口为主机模式,频率设置为100kHz。
- EEPROM写入操作:通过HAL_I2C_Mem_Write()函数将数据写入指定的EEPROM地址。该函数封装了I2C协议中的起始条件、地址传输、数据传输及停止条件。
- EEPROM读取操作:使用HAL_I2C_Mem_Read()函数从指定的EEPROM地址读取数据。
- 串口通信:通过HAL_UART_Transmit()函数将读取到的数据发送到上位机,方便调试与验证。
代码运行结果程序在运行后会将从EEPROM读取到的数据通过串口输出。我们通过串口调试助手可以看到类似以下输出内容:
表示已经成功从EEPROM地址0x0001处读取到了之前写入的0x55。
总结本文展示了STM32F103 MCU与24C02 EEPROM的I2C通信应用。通过STM32的HAL库,I2C通信的实现变得更加简洁易用。实际应用中,这种方法可以广泛用于各种需要数据存储的场合,如配置参数保存、日志记录等。
|