You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ATtiny402进行24C32A EEPROM写入操作失败,求排查指导

ATtiny402 驱动24C32A EEPROM I2C写入故障排查

我基于ATtiny402编写了I2C驱动代码以实现24C32A EEPROM的写入操作,但该功能无法正常运行。正在使用Proteus软件进行仿真调试,运行时I2C调试工具始终显示问号,恳请帮助排查问题。

现有驱动代码

#define sda_on PORTA_DIRSET = PIN1_bm ; PORTA_OUTSET = PIN1_bm ;
#define sda_read PORTA_DIRCLR = PIN1_bm ;while(PORTA_IN & (PIN1_bm));PORTA_DIRSET = PIN1_bm ;
#define sda_off PORTA_DIRSET = PIN1_bm ;PORTA_OUTCLR = PIN1_bm ;
#define scl_on PORTA_DIRSET = PIN2_bm ;PORTA_OUTSET = PIN2_bm ;
#define scl_off PORTA_DIRSET = PIN2_bm ;PORTA_OUTCLR = PIN2_bm ;
#include <xc.h>
#include <util/delay.h>
void i2c_start(void)
{
    sda_on;
    scl_on;
    _delay_ms(10);
    sda_off;
    _delay_ms(10);
    scl_off;
}
void i2c_stop(void)
{
    sda_off;
    scl_off;
    _delay_ms(10);
    scl_on;
    _delay_ms(10);
    sda_on;
}
void i2c_data_write(unsigned char data)
{
    for(int i=0;i<8;i++)
    {
        if(data & 0x80) 
        {
            sda_on;
        }
        else sda_off;
        _delay_ms(10);
        scl_on;
        _delay_ms(10);
        scl_off;
        data = data << 1;
    }
    scl_on;
    sda_on;
    _delay_ms(10);
    sda_read;
    _delay_ms(10);   
    scl_off;
    _delay_ms(10);
}

问题排查与修正建议

1. ACK读取逻辑致命错误

sda_read宏中的while(PORTA_IN & (PIN1_bm));是死等SDA拉低,一旦从机未响应ACK,程序会直接卡死,仿真中就会出现无有效信号的问号状态。同时ACK读取的时序顺序错误:正确流程是先释放SDA为输入,再拉高SCL读取状态,而非先拉SCL高再切换SDA方向。

修正后的ACK读取逻辑:

// 替换原有sda_read宏,改为仅切换输入方向
#define sda_release PORTA_DIRCLR = PIN1_bm;

void i2c_data_write(unsigned char data)
{
    for(int i=0;i<8;i++)
    {
        if(data & 0x80) 
        {
            sda_on;
        }
        else sda_off;
        _delay_us(10); // 改用微秒延时,符合I2C标准速率
        scl_on;
        _delay_us(10);
        scl_off;
        data = data << 1;
    }
    // 正确读取ACK流程
    sda_release; // 释放SDA,让从机控制电平
    _delay_us(10);
    scl_on;
    _delay_us(10);
    // 读取ACK状态(可选:判断是否收到响应)
    unsigned char ack = !(PORTA_IN & PIN1_bm);
    scl_off;
    _delay_us(10);
    sda_on; // 恢复SDA为输出高
}

2. 时序延时过长

原代码使用_delay_ms(10),相当于I2C速率仅100Hz,远低于标准的100kHz/400kHz,过长的延时会导致仿真工具无法识别有效I2C信号,建议改用_delay_us(10)级别的延时,匹配标准时序。

3. 缺少完整的EEPROM写入流程

24C32A的写入需要完整的I2C帧:起始信号→设备地址→2字节内存地址→写入数据→停止信号,现有代码仅实现底层操作,没有组装完整的写入流程。补充写入函数:

void eeprom_write(unsigned int addr, unsigned char data)
{
    i2c_start();
    i2c_data_write(0xA0); // 24C32A默认设备地址,需根据硬件A0-A2引脚调整
    i2c_data_write(addr >> 8); // 内存地址高字节
    i2c_data_write(addr & 0xFF); // 内存地址低字节
    i2c_data_write(data);
    i2c_stop();
    _delay_ms(5); // 等待EEPROM完成写入周期
}

并在主函数中调用测试,例如eeprom_write(0x0000, 0xAA);。

4. Proteus仿真硬件检查

  • 确认ATtiny402的SDA(PIN1)、SCL(PIN2)与24C32A的对应引脚(SDA=5脚,SCL=6脚)正确连接
  • 检查24C32A的A0-A2引脚配置,对应设备地址的最低三位,需与代码中0xA0匹配
  • 确认24C32A已正确接入VCC和GND,电压范围2.5V~5.5V
  • 检查I2C调试工具是否正确绑定SDA/SCL引脚,速率设置为100kHz

内容的提问来源于stack exchange,提问作者user21170594

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 08:56:06