从 PIC18 的 I2C 从协议中的变量写入 SSPBUF

Writing SSPBUF from variable in I2C slave protocol in PIC18

我正在为 PIC18F25K80 编写一个 I2C 从例程,但遇到了一个奇怪的问题。

这是我的例程:

void interrupt interruption_handler() {
PIE1bits.SSPIE = 0; // Disable Master Synchronous Serial Port Interrupt

if (PIR1bits.SSPIF != 1) {
    //This is not I2C interruption;
    PIE1bits.SSPIE = 1; // Enable Master Synchronous Serial Port Interrupt
    return;
}

//Treat overflow
if ((SSPCON1bits.SSPOV) || (SSPCON1bits.WCOL)) {
    dummy = SSPBUF; // Read the previous value to clear the buffer
    SSPCON1bits.SSPOV = 0; // Clear the overflow flag
    SSPCON1bits.WCOL = 0; // Clear the collision bit
    SSPCON1bits.CKP = 1;
    board_state = BOARD_STATE_ERROR;
} else {
    if (!SSPSTATbits.D_NOT_A) {
        //Slave address
        debug(0, ON);
        //Read address 
        address = SSPBUF; //Clear BF
        while(BF); //Wait until completion
        if (SSPSTATbits.R_NOT_W) {
            SSPCON1bits.WCOL = 0;
            unsigned char a = 0x01;
            SSPBUF = a;//0x01 works //Deliver first byte
            asm("nop");
        }
    } else {
        if (SSPSTATbits.BF) {
            dummy = SSPBUF; // Clear BF (just in case)
            while(BF);
        }
        if (SSPSTATbits.R_NOT_W) {
            //Multi-byte read
            debug(1, ON);
            SSPCON1bits.WCOL = 0;
            SSPBUF = 0x02; //Deliver second byte
            asm("nop");
        } else {
            //WRITE
            debug(2, ON);
        }
    }
    transmitted = TRUE;
    SSPCON1bits.CKP = 1;
    PIR1bits.SSPIF = 0;

    PIE1bits.SSPIE = 1; // Enable Master Synchronous Serial Port Interrupt
}
}

如果我在 SSPBUF 上设置常数值,它就像一个魅力。例如,如果您这样做:

SSPBUF = 0x01;
(...)
SSPBUF = 0x02;

我得到master上的两个字节。我什至可以在示波器上看到正在传输的字节的波形。很好玩!

但是当我尝试使用如下变量设置 SSPBUF 时:

unsigned char a = 0x01;
SSPBUF = a;

我对主人的评价为零。

快把我逼疯了。

我放弃的一些假设:

  1. 看门狗定时器在协议中间中断:不是。它被禁用并且问题发生在两个 SSPBUF 分配
  2. 我需要等到 BF 变低才能继续:我没有。 AFAIK,您设置 SSPBUF,清除 SSPIF,设置 CKP 和 return 中断以照顾 4Mhz 的生命,而硬件以几 Khz 发送数据。当它完成时它会再次打扰你。

这对我来说毫无意义。如果不能使用变量定义任意值,那该有多好?

请各位高手赐教,给可怜的程序员指教。

提前致谢。

这与编译器如何生成代码以及一些 undocumented/unknown SSPBUF 的 PIC 限制有关(无论如何它是一个特殊的寄存器)。

我发现它在编译器使用 movwf 时有效,而在编译器使用 movff 时无效。

我把问题移到了另一个论坛,因为我发现那里的观众更充足。

您可以在此处找到更多详细信息: https://electronics.stackexchange.com/questions/251763/writing-sspbuf-from-variable-in-i2c-slave-protocol-in-pic18/251771#251771

  1. 尝试移动声明:"unsigned char a = 0x01;" 到函数的开头或尝试将其定义为 volatile 全局变量。
  2. 考虑到 SSPBUF 既可读又可写buffer.check是否存在可能导致 I2C 模块复位此缓冲区的情况。