2

在 STM32 SPI 中读取 Rx 缓冲区时我有一点问题。在我的示波器中发送或接收信号时,我可以观察到我的信号。但我永远无法在我的 Rx 缓冲区中获取任何数据。我只是在这个项目中使用 coocox 软件。

对于这个项目,我使用 STM32F103 和 LoRa 模块 (SX1278)。我对我的 SPI 配置使用全双工通信。在我的 LoRa 模块中有 2 个周期来读取寄存器状态。第一个周期是写地址,第二个周期是读/写寄存器。我的问题是在我的 LoRa 模块中读取寄存器。

这是我读取寄存器的简单代码。

  void SPI2_IRQHandler(void)
  {
       RxSPIBuff = &Buffer_Rx[0];
       if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_RXNE) == SET)
       {
          /* Store the I2S2 received data in the relative data table */
          //Buffer_Rx[RxIdx++] = SPI_I2S_ReceiveData(SPI2);
         //if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_FLAG_RXNE)==SET)
            USART_SendData(USART1, SPI_I2S_ReceiveData(SPI2));
       }
  }

 void InitSPI_Lora(void)
 {
SPI_InitTypeDef SPI_InitStruct;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

// RCC Peripheral Configuration
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

// GPIO Configuration
GPIO_InitStructure.GPIO_Pin = MOSI_LoRa | SCLK_LoRa;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SPI_LoRa, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = NSS_LoRa;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(PeriphNSS_LoRa, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = MISO_LoRa;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SPI_LoRa, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = Reset_LoRa;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(PeriphRst_LoRa, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = DIO0_LoRa;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(PeriphDI0_LoRa, &GPIO_InitStructure);

// SPI Configuration
SPI_InitStruct.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_32; // 7us every 8 bit data
SPI_InitStruct.SPI_CPHA=SPI_CPHA_1Edge;
SPI_InitStruct.SPI_CPOL=SPI_CPOL_Low;
SPI_InitStruct.SPI_DataSize=SPI_DataSize_8b;
SPI_InitStruct.SPI_Direction=SPI_Direction_2Lines_FullDuplex;
SPI_InitStruct.SPI_FirstBit=SPI_FirstBit_MSB;
SPI_InitStruct.SPI_Mode=SPI_Mode_Master;
SPI_InitStruct.SPI_NSS=SPI_NSS_Soft;

// NVIC Configuration
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* SPI1 IRQ Channel configuration */
NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

SPI_I2S_DeInit(SPI2);

/* Enable the I2S1 RxNE interrupt */
SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);

SPI_Init(SPI2, &SPI_InitStruct);
SPI_Cmd(SPI2, ENABLE);
 }

 void SendSPI_Lora(unsigned short val, unsigned char status)
 {
SPI_I2S_SendData(SPI2, val);
while(SPI_I2S_GetITStatus(SPI2, SPI_I2S_FLAG_TXE)==SET);
SPI_I2S_ClearFlag(SPI2, SPI_I2S_FLAG_TXE);
 }


 void AccessSPI(unsigned char Cmd, unsigned short *ptrBuff, unsigned char    Operation)
 {
unsigned short m, temp;

NSS_LO_LoRa;
SendSPI_Lora(Cmd, kWriteSPI);       // Send Command
if (Operation==kWriteSPI)
{
    temp=*ptrBuff;
    SendSPI_Lora(temp, Operation);
}
else
{
    RxIdx=0;
    SendSPI_Lora(0, Operation);
    ptrBuff = RxSPIBuff;
}
Delay(2);
NSS_HI_LoRa;
 }

 // Main Sequence
 void test(void)
 {
unsigned char statusLoRa,buff,irqFlags,newData,newOpMode;
unsigned char size = 0;

AccessSPI(R_REGISTER|RegVersion, &newOpMode, kReadSPI);
 }

在此处输入图像描述 图 1. MOSI 引脚写入信号

在此处输入图像描述 图 2. MISO 引脚中的读取信号

我认为我的问题是关于使用 SPI 传输数据后接收数据的延迟。但我无法解决这个问题,因为我应该传输数据来接收。有什么解决办法吗?

4

1 回答 1

1
  1. I'm not sure about this one, but I think MISO should also be configured as alternate mode. At least that's what works for me.
  2. You have configured RXNE interrupt, but use TXE as interrupt also. Use SPI_I2S_GetFlagStatus instead of SPI_I2S_GetITStatus
  3. while(SPI_I2S_GetITStatus(SPI2, SPI_I2S_FLAG_TXE)==SET); is an error. Reference manual for STM32F103, page 710:

    The TXE flag (Tx buffer empty) is set when the data are transferred from the Tx buffer to the shift register. It indicates that the internal Tx buffer is ready to be loaded with the next data.

    So it should be while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE)==RESET);

  4. With RXNE interrupt you will be sending to USART also after sending the first byte (the register addess)

    Here is a CMSIS code for similar transmission ("First cycle is to write address and second cycle is for read/write register.", but without using interrupts, and using STM32F4 with SPI configured as follows:

    //af5, afrl
    GPIOB->AFR[0] |= ( GPIO_AFRL_AFSEL3_2 | GPIO_AFRL_AFSEL3_0 |
                       GPIO_AFRL_AFSEL5_2 | GPIO_AFRL_AFSEL5_0 );
    GPIOA->AFR[0] |= ( GPIO_AFRL_AFSEL6_2 | GPIO_AFRL_AFSEL6_0 );
    //B3 SCK
    //A6 MISO
    //B5 MOSI
    //B6 SS
    GPIOA->MODER |= ( GPIO_MODER_MODE6_1 );
    GPIOB->MODER |= ( GPIO_MODER_MODE3_1 |
                      GPIO_MODER_MODE5_1 |
                      GPIO_MODER_MODE6_0 ); //alternate, 6 output
    
    GPIOA->PUPDR &= ~(GPIO_PUPDR_PUPD6_Msk ); // no pull
    GPIOB->PUPDR |= GPIO_PUPDR_PUPD3_1;
    
  5. Are you using a Nano board? If so into which connector did you plug your MISO? I've spent a week once because I have plugged it into Arduino connector that was connected to some other peripheral instead of Morpho connector.

于 2019-10-24T10:05:17.763 回答