从 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;
我对主人的评价为零。
快把我逼疯了。
我放弃的一些假设:
- 看门狗定时器在协议中间中断:不是。它被禁用并且问题发生在两个 SSPBUF 分配
- 我需要等到 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
- 尝试移动声明:"unsigned char a = 0x01;"
到函数的开头或尝试将其定义为 volatile 全局变量。
- 考虑到 SSPBUF 既可读又可写buffer.check是否存在可能导致 I2C 模块复位此缓冲区的情况。
我正在为 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;
我对主人的评价为零。
快把我逼疯了。
我放弃的一些假设:
- 看门狗定时器在协议中间中断:不是。它被禁用并且问题发生在两个 SSPBUF 分配
- 我需要等到 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
- 尝试移动声明:"unsigned char a = 0x01;" 到函数的开头或尝试将其定义为 volatile 全局变量。
- 考虑到 SSPBUF 既可读又可写buffer.check是否存在可能导致 I2C 模块复位此缓冲区的情况。