我正在为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;
我在主服务器上获得了两个字节。我甚至可以看到在示波器上传输的字节的波形。很有趣!
但是当我尝试使用如下变量设置SSPBUF时:
unsigned char a = 0x01;
SSPBUF = a;
我在主人身上得到零。
这让我发疯了。
我放弃了一些假设:
对我来说没有意义。如果你不能使用变量定义任意值,那有多好?
请那里的大师,启发这位可怜的程序员。
提前致谢。
答案 0 :(得分:0)
它与编译器如何生成代码以及SSPBUF周围的一些未记录/未知的PIC限制有关(无论如何它都是一个特殊的寄存器)。
我发现它在编译器使用movwf时有效,而在编译器使用movff时不起作用。
我将问题转移到另一个论坛,因为我意识到那里的观众更充足。
您可以在此处找到更多详细信息: https://electronics.stackexchange.com/questions/251763/writing-sspbuf-from-variable-in-i2c-slave-protocol-in-pic18/251771#251771
答案 1 :(得分:0)