MyCollege1999 2025-09-08 08:48 采纳率: 59.2%
浏览 4
已结题

Attiny84A通过mdio读88q2112时,读管脚值失效

Attiny84A通过mdio读88q2112时,读管脚值失效。MDC管脚用PB0,MDIO用PB1.
MDIO_READ的定义如下。现在在mdio线都是高的情况下,MDIO_READ只读到一个1,不知道原因

// 定义ATtiny84A的引脚 - 使用PORTB
#define MDIO_DIR_REG DDRB
#define MDIO_OUT_REG PORTB
#define MDIO_IN_REG PINB
#define MDIO_PIN PB1

#define MDC_DIR_REG DDRB
#define MDC_OUT_REG PORTB
#define MDC_PIN PB0

// MDIO线方向控制宏
#define MDIO_AS_OUTPUT() (MDIO_DIR_REG |= (1 << MDIO_PIN))
#define MDIO_AS_INPUT() (MDIO_DIR_REG &= ~(1 << MDIO_PIN))
#define MDIO_HIGH() (MDIO_OUT_REG |= (1 << MDIO_PIN))
#define MDIO_LOW() (MDIO_OUT_REG &= ~(1 << MDIO_PIN))
#define MDIO_READ() (MDIO_IN_REG & (1 << MDIO_PIN))

#define MDC_HIGH() (MDC_OUT_REG |= (1 << MDC_PIN))
#define MDC_LOW() (MDC_OUT_REG &= ~(1 << MDC_PIN))

  • 写回答

5条回答 默认 最新

  • 檀越@新空间 2025-09-08 08:49
    关注

    上午好☀️☀️☀️️
    本答案参考通义千问

    你提到的问题是:在使用ATtiny84A通过MDIO接口读取88Q2112时,MDIO_READ()只读到一个1,而不是预期的高电平(即0x02),导致读取失败。

    这可能涉及以下几个关键问题:


    一、问题分析

    1. MDIO引脚方向配置错误

    • MDIO_AS_INPUT() 是将PB1设置为输入模式,但需要确认是否成功执行。
    • 如果未正确设置为输入模式,那么MDIO_IN_REG读取的是输出状态而非实际引脚状态。

    2. MDIO线未正确拉高或驱动

    • 在读操作前,必须确保MDIO线处于高阻态(即未被驱动),否则可能读取不到正确的信号。
    • 如果MDIO线未被外部拉高,或者被其他设备驱动,可能导致读取异常。

    3. MDIO读取逻辑有误

    • MDIO_READ() 返回的是 (MDIO_IN_REG & (1 << MDIO_PIN)),这个表达式返回的是布尔值(0或非零),而不是实际的位值。
    • 例如,如果PB1为高电平,则(1 << PB1)为0x02,若该位被置位,则返回0x02;否则为0。

    4. MDC和MDIO时序不匹配

    • MDIO通信依赖于MDC时钟同步,如果MDC时钟频率过快或与MDIO信号不同步,可能导致读取错误。

    二、解决方案

    1. 确认MDIO引脚方向设置正确

    // 设置MDIO为输入模式
    MDIO_AS_INPUT();
    

    重点:确保此代码在每次读取前都被调用,防止引脚处于输出状态导致读取错误。


    2. 确保MDIO线未被驱动

    在读取之前,应确保MDIO线处于高阻态(未被驱动):

    // 设置MDIO为输出并拉低(释放总线)
    MDIO_AS_OUTPUT();
    MDIO_LOW();
    
    // 延迟一段时间,让总线稳定
    _delay_us(1);
    
    // 设置MDIO为输入
    MDIO_AS_INPUT();
    

    重点:在读取前必须将MDIO设为输出并拉低,以释放总线,避免冲突。


    3. 修正MDIO_READ()函数返回值

    当前的MDIO_READ()返回的是布尔值(0或非零),建议改为直接返回位值:

    #define MDIO_READ() ((MDIO_IN_REG >> MDIO_PIN) & 0x01)
    

    重点:这样可以确保读取到的是0或1,而不是0或非零值。


    4. 检查MDC时序

    确保MDC时钟频率合适,且与MDIO信号同步。通常建议使用较低频率(如1MHz以下)以保证稳定性。

    // MDC控制宏
    #define MDC_HIGH() (MDC_OUT_REG |= (1 << MDC_PIN))
    #define MDC_LOW() (MDC_OUT_REG &= ~(1 << MDC_PIN))
    
    // 示例:发送一个MDC脉冲
    MDC_HIGH();
    _delay_us(1);
    MDC_LOW();
    _delay_us(1);
    

    重点:MDC脉冲必须与MDIO信号同步,否则可能导致读取错误。


    三、完整示例代码(修改后)

    #include <avr/io.h>
    #include <util/delay.h>
    
    // 定义ATtiny84A的引脚 - 使用PORTB
    #define MDIO_DIR_REG DDRB
    #define MDIO_OUT_REG PORTB
    #define MDIO_IN_REG PINB
    #define MDIO_PIN PB1
    
    #define MDC_DIR_REG DDRB
    #define MDC_OUT_REG PORTB
    #define MDC_PIN PB0
    
    // MDIO线方向控制宏
    #define MDIO_AS_OUTPUT() (MDIO_DIR_REG |= (1 << MDIO_PIN))
    #define MDIO_AS_INPUT() (MDIO_DIR_REG &= ~(1 << MDIO_PIN))
    #define MDIO_HIGH() (MDIO_OUT_REG |= (1 << MDIO_PIN))
    #define MDIO_LOW() (MDIO_OUT_REG &= ~(1 << MDIO_PIN))
    #define MDIO_READ() ((MDIO_IN_REG >> MDIO_PIN) & 0x01)
    
    #define MDC_HIGH() (MDC_OUT_REG |= (1 << MDC_PIN))
    #define MDC_LOW() (MDC_OUT_REG &= ~(1 << MDC_PIN))
    
    // 示例:读取MDIO引脚
    uint8_t read_mdio(void) {
        // 设置MDIO为输出并拉低(释放总线)
        MDIO_AS_OUTPUT();
        MDIO_LOW();
        _delay_us(1);  // 等待总线稳定
    
        // 设置MDIO为输入
        MDIO_AS_INPUT();
    
        // 读取MDIO值
        return MDIO_READ();
    }
    
    int main(void) {
        // 初始化MDIO和MDC引脚
        MDIO_DIR_REG &= ~(1 << MDIO_PIN);   // 设置为输入
        MDC_DIR_REG |= (1 << MDC_PIN);      // 设置为输出
    
        while (1) {
            uint8_t value = read_mdio();
            // 处理读取结果
            if (value == 1) {
                // 读取到高电平
            } else {
                // 读取到低电平
            }
            _delay_ms(100);
        }
    
        return 0;
    }
    

    四、常见调试建议

    | 问题 | 解决方案 | |------|----------| | MDIO_READ()始终返回0 | 检查MDIO引脚是否被正确设置为输入 | | 读取结果不一致 | 检查MDC时序是否正确,增加延时 | | MDIO线被驱动 | 在读取前将MDIO设为输出并拉低 |


    五、总结

    • MDIO引脚方向必须为输入,否则无法读取真实电平;
    • MDIO线必须释放(拉低)后再读取,防止冲突;
    • MDIO_READ()应返回0或1,而不是布尔值;
    • MDC时序必须严格符合IEEE 802.3标准

    如果你能提供更详细的代码或硬件连接图,我可以进一步帮助你定位问题。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

问题事件

  • 系统已结题 9月18日
  • 已采纳回答 9月10日
  • 创建了问题 9月8日