0

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

谢谢,

约翰

4

1 回答 1

0

SPI 总线的本质是对称的,即 SPI 端口上的每个数据传输同时是一个传输和一个接收。主机在 MOSI 线上发送一个位,从机读取它,而从机在 MISO 线上发送一个位,然后主人读它。即使只打算进行单向数据传输,也会保持此顺序。

我已经实现了 8、12 和 16 位数据传输,但不是作为中断代码,我认为将其置于纯中断中可能有点棘手,但这可能是我

阅读以下来自 Microchip PIC 的内容,当我无法理解 SPI 总线时,这对我有很大帮助。
PICmicro 串行外设接口的概述和使用

如果有帮助,我将与您分享我的一些代码,用于从连接到 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 的工作原理。

于 2015-05-04T11:54:32.790 回答