PIC18F SPI从器件中断在4 MHz问题上接收多个字节

时间:2015-04-30 17:32:49

标签: pic interrupt-handling spi 8-bit

我正在编写代码以在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?

谢谢,

约翰

1 个答案:

答案 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的工作原理。