我正在编写代码以在PIC18F2680微控制器上的中断服务程序中接收SPI数据,该微控制器运行在40MHz,需要从另一个微控制器接收2字节(16位)数据。 PIC仅接收数据(被动侦听),并且不向发送方发送任何内容。在设备上使用MISO和SCLK的两条数据线。 SPI通信中没有使用从机选择,MOSI不是监听命令所必需的,只有从机响应。
我在设计时没有意识到SPI数据包一次发送16位,否则我会使用不同的微控制器。
我想知道是否有一种方法可以读取SPI ISR中的两个连续字节,而不会丢失任何数据。我目前的实施:
OpenSPI(SLV_SSOFF,MODE_00,SMPMID);
//***********************************SPI ISR*********************************
#pragma code InterruptVectorHigh = 0x08
void InterruptVectorHigh (void)
{
_asm
goto InterruptHandlerHigh //jump to interrupt routine
_endasm
}
//----------------------------------------------------------------------------
// High priority interrupt routine
#pragma code
#pragma interrupt InterruptHandlerHigh
void InterruptHandlerHigh () {
unsigned int next;
//the interrupt flag is set for SPI
if(PIR1bits.SSPIF ==1){
spiByte1 = SSPBUF;
while(SSPSTATbits.BF != 0);
spiByte2 = SSPBUF;
}
PIR1bits.SSPIF = 0;
}
但是,这似乎得到了一些正确的数据,但却失去了很多其他字节。有没有更好的方法来实现这一点,或者我是使用8位MCU的SOL?
谢谢,
约翰
答案 0 :(得分:0)
SPI总线的性质是对称的,这意味着SPI端口上的每个数据传输同时是传输和接收。主机在MOSI线上发送一个位,从机读取它,而从机发送一个位。 MISO线和主人读它。即使只打算进行单向数据传输,也会保持此序列。
我已经实现了8位,12位和16位数据传输但不是中断代码,我认为把它放在纯中断中可能有点棘手但是这可能是我
阅读以下来自Microchip PIC的内容,当我无法理解SPI总线时,对我有很大的帮助 Overview and Use of the PICmicro Serial Peripheral Interface
如果有帮助,我会与您分享我的一些代码,用于从连接到PIC的MAX6675 SPI器件读取12位的温度值。这不是在一个中断中完成的,只是你可以拥有的数百万个应用程序中的一个,我只是把它放在这里,我在这里展示它,因为如果你研究它可能会有所帮助。
unsigned int spi_temp(void) // Read the temp from MAX6675 connected to SPI output is (12bit)
{
unsigned int spi_12bit; // specify an int so can hold the 12bit number
CHIP_EN = 0 ; // Enable SPI on MAX6675. (When Low enables the Max6675 and stops any conversion process)
__delay_ms(1); // Small delay required by MAXX6675 after enabling CS (Chip Select)
SSPIF = 0; // Clear Master Synchronous Serial Port Flag
spi_12bit = SSPBUF; // Read Buffer to clear it and to reset the BF Flag
SSPBUF = 0b10101010; // Loading the Buffer with some data junk to start transmision (We're not sending them anywhere)
while (!SSPIF) continue; // wait until data is clocked out
spi_12bit = (0b01111111 & SSPBUF)<<8; // Read the Buffer with the fresh first 8bit DATA from MAX6675
// disregard MSB bit of unimportant data and shift it left
SSPIF = OFF; // Clear Flag to get ready for the next 8bit DATA
SSPBUF = 0b10101010; // Load the Buffer with more junk data
while (!SSPIF) continue; // wait until data is clocked out
SSPIF = OFF; // Clear the Flag
spi_12bit = spi_12bit | SSPBUF; // Read the Buffer with the other 8bit data and keep it as a 16bit variable
spi_12bit = spi_12bit >>3; // We disregard the leftmost 3 bits on unimportant Data according to Datasheet
CHIP_EN = 1 ; // disabling CS (Chip Select). Let MAX6675 continue conversion processreading
delay_200ms(1); // Small delay required by MAXX6675 to do conversion typ 0.2sec
spi_12bit = (int)(spi_12bit * 0.25);//(reading in 12bit * 1024 total steps / 4096;
return spi_12bit;
} // spi_temp
这只是一个例子,希望它可以帮助理解SPI的工作原理。