2015-04-30 55 views
0

我正在編寫代碼以在需要從另一個器件接收2個字節(16位)數據的PIC18F2680單片機的中斷服務程序中接收SPI數據微控制器。 PIC只接收數據(被動收聽),並且不向發送者返回任何內容。這兩條數據線在設備上使用MISO和SCLK。在SPI通信中沒有使用從機選擇,而MOSI對於收聽命令不是必需的,只有從機響應。我在設計時並沒有意識到SPI數據包一次發送16位,否則我會使用不同的微控制器。PIC18F SPI從器件中斷在4 MHz時接收多個字節問題

我想知道是否有辦法在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

while循環中的條件不是錯誤的嗎?你不應該等到緩衝區滿了(BF是1)嗎?現在它等待直到BF == 0,這應該立即成立(即不等待)。 –

回答

0

SPI總線的本質是對稱的,意味着SPI端口上的每個數據傳輸同時是變速器和主的前臺。發送在MOSI線上的位和從設備讀取它,而從設備在MISO線上發送一位數據,主設備讀取它。即使只有單向數據傳輸的目的,這個序列仍然保持。

我已經實現了8,12和16位數據傳輸,但不作爲中斷代碼,我覺得把它在一個純粹的中斷可能會有點棘手,但可能我

閱讀是從以下當我無法理解SPI總線時,Microchip PIC對我非常有幫助。
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的工作原理有所幫助。