STM32CubeMX 模拟IIC AT24C64
时间: 2025-05-09 19:58:45 浏览: 28
### STM32CubeMX 配置 STM32 模拟 IIC 实现与 AT24C64 的读写操作
为了实现 STM32 使用 STM32CubeMX 模拟 IIC 协议与 AT24C64 EEPROM 进行通信,可以按照以下方法完成配置和代码编写。
#### 1. 工程初始化
在 STM32CubeMX 中创建一个新的项目并选择目标芯片(如 STM32F103C8T6),然后进入 Pinout & Configuration 页面进行必要的外设配置。
#### 2. GPIO 配置
由于是模拟 IIC,因此需要手动控制 SCL 和 SDA 引脚的状态来生成 IIC 波形。具体步骤如下:
- 将两个通用 IO 口分配给 SCL 和 SDA 功能。
- 设置这两个引脚为推挽输出模式(Push-Pull Output Mode)以便能够主动拉低信号线[^2]。
```c
// 定义 SCL 和 SDA 引脚
#define SCL_PIN GPIO_Pin_5 // 假设 PA5 作为 SCL
#define SDA_PIN GPIO_Pin_6 // 假设 PA6 作为 SDA
#define GPIO_PORT GPIOA // 假设使用端口 A
```
#### 3. 编写延时函数
IIC 总线有严格的时序要求,因此需要精确的延时函数支持。可以通过 HAL 库中的 `HAL_Delay()` 或者自定义微秒级延迟函数实现。
```c
void delay_us(uint32_t us) {
__HAL_TIM_SET_COUNTER(&htim2, 0); // 清零定时器计数值 (假设 TIM2 初始化完毕)
while (__HAL_TIM_GET_COUNTER(&htim2) < us);
}
```
#### 4. IIC 函数实现
以下是几个核心功能模块的具体实现细节:
##### (1)启动条件
当 SDA 线由高变低而此时 SCL 维持高位,则表示一次新的传输开始。
```c
void I2C_Start(void){
GPIO_SetBits(GPIO_PORT, SDA_PIN | SCL_PIN); // 确保两条线都处于 HIGH
delay_us(5);
GPIO_ResetBits(GPIO_PORT, SDA_PIN); // 下拉 SDA
delay_us(5);
GPIO_ResetBits(GPIO_PORT, SCL_PIN); // 下拉 SCL
delay_us(5);
}
```
##### (2)停止条件
当 SCL 处于 HIGH 期间,SDA 从 LOW 到 HIGH 表明结束当前事务处理过程。
```c
void I2C_Stop(void){
GPIO_SetBits(GPIO_PORT, SDA_PIN); // 提升 SDA 至 HIGH
delay_us(5);
GPIO_SetBits(GPIO_PORT, SCL_PIN); // 提升 SCL 至 HIGH
delay_us(5);
}
```
##### (3)等待应答位 ACK/NACK
主机发送完地址或者数据之后会释放总线让从机回应是否准备好接收下一个字节。
```c
uint8_t I2C_Wait_Ack(void){
uint8_t ucErrTime=0;
GPIO_SetBits(GPIO_PORT, SDA_PIN); // 设定 SDA 输入状态
delay_us(1);
while(!GPIO_ReadInputDataBit(GPIO_PORT, SDA_PIN)){
ucErrTime++;
if(ucErrTime>250){ // 如果超过最大重试次数则返回错误标志
return ERROR;
}
}
return SUCCESS; // 成功收到 Acknowledge 返回正常标记
}
```
##### (4)单字节传送
每次仅能传递一字节的数据量,在此之前需先确认前次通讯已完成无误后再继续下一步骤动作。
```c
void I2C_Send_Byte(uint8_t Byte){
uint8_t i;
for(i=0;i<8;i++){
if(Byte&0x80){
GPIO_SetBits(GPIO_PORT, SDA_PIN); // 发送 '1'
}else{
GPIO_ResetBits(GPIO_PORT, SDA_PIN); // 发送 '0'
}
delay_us(5);
GPIO_SetBits(GPIO_PORT, SCL_PIN); // Clock High
delay_us(5);
GPIO_ResetBits(GPIO_PORT, SCL_PIN); // Clock Low
Byte<<=1;
}
}
```
#### 5. 主程序逻辑结构化描述
最终主循环里调用上述封装好的各个子例程组合成完整的交互流程即可达成预期目的。
```c
int main(){
...
I2C_Start(); // 开启连接请求
I2C_Send_Byte(AT24C64_ADDRESS_WRITE); // 写入设备地址加上写命令
I2C_Send_Byte(MEMORY_ADDR >> 8); // 写入内存高位地址
I2C_Send_Byte(MEMORY_ADDR & 0xFF); // 写入内存低位地址
data_to_write = DATA_VALUE; // 待存储的实际资料值
I2C_Send_Byte(data_to_write); // 向指定位置存入新信息
I2C_Wait_Ack(); // 请求对方反馈确认消息
I2C_Stop(); // 结束整个序列活动
...
}
```
以上就是利用 STM32CubeMX 来构建基于软体仿真的 I²C 接口并与外部元件 AT24C64 EEPROM 展开双向沟通的主要思路和技术要点[^4]。
---
阅读全文
相关推荐


















