I2C 不工作,从设备不确认。收到地址后

问题描述 投票:0回答:1

作为初学者,我尝试在两个 pic18f4550 之间发送数据,其中主机发送数据,从机接收数据并在 LED(PORTD)上打印数据位。但我不知道问题出在哪里,从机没有确认并且数据没有传输。

    //==================== Master I2C code=========================
    bit I2C_Write(unsigned char address, unsigned char \*data, unsigned char datasize) {
        SSPCON2bits.SEN = 1; //  Initiate Start condition on SDA and SCL pins. Automatically cleared by hardware
        while (!SSPIF);
        PIR1bits.SSPIF = 0;
        LED1 = 1;
        
        SSPBUF = address;
        while (!SSPIF);
        PIR1bits.SSPIF = 0;
        LED2 = 1;  /// ---------------> This turns ON 
        if (SSPCON2bits.ACKSTAT) {
            SSPCON2bits.PEN = 1;
            while (PEN);
            ACK = 1;
            return WriteSuccessful = 0;
        }             
        LED3 = 1; /// -----------------> but This remains off
        int i;
        for (i = 0; i < datasize; i++) {
            SSPBUF = *data;
            while (!SSPIF);
            PIR1bits.SSPIF = 0;
        
            if (SSPCON2bits.ACKSTAT) {
                SSPCON2bits.PEN = 1;
                while (PEN);
                ERROR = 1;
                return WriteSuccessful = 0;
            }
            LED = *data;
            data++;
        }
        LED4 = 1;
        
        PEN = 1; // I2C Stop
        while (PEN);
        PIR1bits.SSPIF = 0;
        
        return WriteSuccessful = 1;

    }

    //-----here is i2c initalization---------
    void I2C_INIT(void) {
        SDA_dir = 1;
        SCL_dir = 1;
        ADCON1bits.PCFG = 0b1111;

        SSPADD = _XTAL_FREQ / (4 * (Baud_Rate)) - 1;
        SSPSTATbits.SMP = 0; // Slew rate control disabled for Standard Speed mode (100 kHz and 1 MHz)
        SSPCON1bits.SSPEN = 1;
        SSPCON1bits.SSPM = 0b1000; //  I2C Master mode, clock = FOSC/(4 * (SSPADD + 1))(2,3)

    )

    //------- i2c master call--------
    unsigned char data\[5\] = {0xA1, 0xB1, 0xC1, 0xD1, 0xE1};
    I2C_Write(0b00111100, data, 5);

在从机中我只使用ISR来读取SSPBUF:

    //=======================Slave I2c code===========================

    void __interrupt() ISR(void) {
        if (PIR1bits.SSPIF) {
            if (SSPSTATbits.D_NOT_A) {
                // This means the received byte is data
                Read_data = SSPBUF; // Read the received data
                LED = Read_data;  //-----------------------\> these remains blank!
            } else if (!SSPSTATbits.D_NOT_A) {
                MATCH = 1;    //----------------------------\> This Turns On
            }
            PIR1bits.SSPIF = 0;
        }
    }

    //--------slave init---------------------
    void I2C_INIT(void) {
        SDA_dir = 1; //
        SCL_dir = 1; //
        ADCON1bits.PCFG = 0b1111;

        SSPADD = 0b00111100; // Writing address for slave mode
        SSPSTATbits.SMP = 1; // Slew rate control disabled for Standard Speed mode (100 kHz and 1 MHz)
        
        SSPCON1bits.SSPEN = 1; //
        // SSPCON1bits.SSPM = 0b1000; //  I2C Master mode, clock = FOSC/(4 * (SSPADD + 1))(2,3)
        SSPCON1bits.SSPM = 0b1110; //I2C Slave mode, 7-bit address with Start and Stop bit interrupts enabled(2)
        SSPCON2bits.ACKEN = 1;
    }

我尝试通过 I2C 协议在两个 pic18f4550 设备之间发送数据,但失败,即从设备未发送确认位。它会减慢地址匹配速度!

c embedded microcontroller i2c pic18
1个回答
0
投票

这个问题已经解决了

以下是已发现的问题及其解决方案:

致大师:

  1. 通过将其设置为“1”来禁用标准速度模式(100 kHz 和 1 MHz)的转换速率控制。
  2. 发送数据无需开启ACKEN。
  3. 如果未启用 RSEN(重复启动),请避免循环发送数据。从另一个函数调用像“tx_data”这样的函数是一个很好的做法。
  4. 始终仔细检查要向其发送数据的从站的地址。
  5. 如果您在地址中使用左移,请务必在寻址从站时考虑到这一点。
  6. 如果不需要,请禁用看门狗定时器 (WDT)。
  7. 如果需要,启用 LVP(低电压编程)。

对于奴隶:

  1. 验证从站中的地址,确保其与预期地址匹配。
  2. 通过将其设置为“1”来禁用标准速度模式(100 kHz 和 1 MHz)的转换速率控制。
  3. 从机代码中无需使用“ACKEN”,因为从机会自动向主机发送 ACK/NACK。
  4. 在从机代码中启用中断来处理传入的数据或事件。
  5. 在中断服务程序(ISR)中,检查是否发生 SSPOV(接收溢出)或 WCOL(写冲突)。您可以连接 LED 来指示这些情况。
  6. 在ISR中使用时钟拉伸来确保数据被正确处理,并在ISR结束时释放。
  7. 利用 ISR 中的 R_nW(读/写)和 D_NOT_A(数据/地址)位来确定正在执行的操作。

重要提示:

  1. 创建新项目:我一次又一次地清理和构建相同的项目超过 50 次,并从 MPLAB X IDE 中的项目中删除了一些文件,但当我看到该文件夹时,它仍然在那里。 然后我创建了一个新项目,它粘贴了我想要构建的唯一文件,并且它在 proteus 中工作
  2. 使用Protues Debugger进行调试

您可以在我的 GitHub 存储库中找到更新的代码 - AIZAZ588。

如果有人发现任何错误或有更多见解,请随时提供更正或建议,因为我是一名学生和初学者。您的反馈很有价值!

© www.soinside.com 2019 - 2024. All rights reserved.