PIC16LF1824 SPI从接口

时间:2018-08-05 21:24:43

标签: c pic spi interrupt-handling microchip

我正在尝试通过SPI接收多个字节。目的是当主机开始SPI传输时,从MCU中断,它应通过SPI读取数据并将其存储在一个数组中,然后由我的应用程序用于其他操作,例如确定设备ID和数据包的内容。

void interrupt __high_priority my_isr_high(void) {

if (PIR1bits.SSP1IF) { // Interrupt from SPI? 
    rx[buffer_pointer] = SSP1BUF; // Get data from MSSP and store in RX buffer
    buffer_pointer++; // Next data
    if (buffer_pointer < FRAME_SIZE) // Ended?
        SSP1BUF = tx[buffer_pointer]; // Send next byte to SPI
    else
       buffer_pointer = FRAME_SIZE;
    PIR1bits.SSP1IF = 0; // Clear interrupt flag
   }
 }

但是,我没有正确接收3个字节。我是从主人那里寄来的:

dataPacket[0] = 0x43; // Decimal 67
dataPacket[1] = 0x42; //66
dataPacket[2] = 0x41; //65

虽然我从ISR()收到以下信息:

rx[0]: 67 
rx[1]: 65 
rx[2]: 67 

我丢失了某些东西或对SPI的处理不正确吗?

这将真正解决我所坚持的问题,也许还会帮助那些需要接收多个字节的人。

我在这里共享我的代码,以帮助快速找到解决方案。还包括一个用于编译的.zip文件。 Check the Codes here

到目前为止,以上代码对我而言无法正常工作。因此,在网上和其他论坛上进行了一些探索之后,我发现了以下读取多个字节的方法:

uint8_t SPI_ExchangeHandler(uint8_t byte){
static uint8_t i = 0;
for(i=0; i<3; i++){
    SSP1BUF =0x00;
    while(!SSP1STATbits.BF);
    rx_buff[i]=SSP1BUF;
 }
State = SEND; 
return byte;
}

尽管上面的代码给了我期望的结果(即以有序的方式纠正了数据包),但是,它每次都会丢失两个SPI中断,然后显示/捕获正确的数据。因此,总是丢失两组数据,然后正确接收第三组数据。 是否配置错误或丢失?

1 个答案:

答案 0 :(得分:0)

最后,我设法正确接收了所有3个字节。分享以下代码: 我的中断服务程序在主SPI有数据要发送时触发MCU。

void interrupt INTERRUPT_InterruptManager (void){
if(PIE1bits.SSP1IE == 1 && PIR1bits.SSP1IF == 1)
 { 
    SPI_ISR();
 } 
}

SPI_ISR代码是由MCC GUI自动生成的。

void SPI_ISR(void)
{
     SSP1BUF = SPI_xchgHandler(SSP1BUF);
}

void SPI_setExchangeHandler(uint8_t (* InterruptHandler)(uint8_t))
{
     SPI_xchgHandler = InterruptHandler;
}

然后,我使用SPI_setExchangeHandler()通过自定义函数处理SPI,如下所示:

#define FRAME_SIZE 10 // Frame fixed size
volatile static uint8_t rx_buff[FRAME_SIZE]; //RX buffer

uint8_t SPI_ExchangeHandler(uint8_t byte)
{
   static uint8_t i = 0;
   rx_buff[i]=SSP1BUF;
   i++;
   if(i <= 2){
       rx_buff[i]=SSP1BUF;
       SSP1BUF = 0x00; 
       while(!SSP1STATbits.BF){};
        i++;
   }
   else{
     i = 2;
   }

   PIR1bits.SSP1IF = 0; // Clear the SPI interrupt flag
   State = SEND;
   return byte;
}

然后我打印出以下值进行调试:

printf("CMD:%d \n", rx_buff[0]);
printf("BUF1: %d \n", rx_buff[1]);
printf("BUF2: %d \n\n", rx_buff[2]);

但是,我很确定这不是处理SPI中多个字节的最佳/优化方法,因此,如果有替代方法,请共享...