简体   繁体   English

在 SPI STM32 中读取 Rx 缓冲区的问题

[英]Problem with Reading Rx buffer in SPI STM32

I have little bit problem when reading Rx Buffer in STM32 SPI.在 STM32 SPI 中读取 Rx 缓冲区时我有一点问题。 I can watch my signal when transmit or receive in my scope.我可以在 scope 中发送或接收信号时观察我的信号。 But I never can get any data in my Rx Buffer.但我永远无法在我的 Rx 缓冲区中获取任何数据。 I just use coocox software for this project.我只是在这个项目中使用 coocox 软件。

For this project, I use STM32F103 and LoRa module (SX1278).对于这个项目,我使用 STM32F103 和 LoRa 模块 (SX1278)。 I use Full duplex communication for my SPI Configuration.我对我的 SPI 配置使用全双工通信。 There is 2 cycle to read register status in my LoRa module.在我的 LoRa 模块中有 2 个周期来读取寄存器状态。 First cycle is to write address and second cycle is for read/write register.第一个周期是写地址,第二个周期是读/写寄存器。 My problem is reading register in my LoRa module.我的问题是在我的 LoRa 模块中读取寄存器。

This is my simple code to read register.这是我读取寄存器的简单代码。

  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);
 }

在此处输入图像描述 Pict 1. Write signal in MOSI pin图 1. MOSI 引脚写入信号

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

I think my problem is about delay to receive data after transmit data with SPI.我认为我的问题是关于使用 SPI 传输数据后接收数据的延迟。 But i cannot solve this problem because i should transmit data to receive.但我无法解决这个问题,因为我应该传输数据来接收。 Is there any solution for this?有什么解决办法吗?

  1. I'm not sure about this one, but I think MISO should also be configured as alternate mode.我不确定这个,但我认为 MISO 也应该配置为备用模式。 At least that's what works for me.至少这对我有用。
  2. You have configured RXNE interrupt, but use TXE as interrupt also.您已经配置了 RXNE 中断,但也使用 TXE 作为中断。 Use SPI_I2S_GetFlagStatus instead of SPI_I2S_GetITStatus使用SPI_I2S_GetFlagStatus而不是SPI_I2S_GetITStatus
  3. while(SPI_I2S_GetITStatus(SPI2, SPI_I2S_FLAG_TXE)==SET); is an error.是一个错误。 Reference manual for STM32F103 , page 710: STM32F103 参考手册,第 710 页:

    The TXE flag (Tx buffer empty) is set when the data are transferred from the Tx buffer to the shift register.当数据从 Tx 缓冲区传输到移位寄存器时,TXE 标志(Tx 缓冲区为空)置位。 It indicates that the internal Tx buffer is ready to be loaded with the next data.它表示内部 Tx 缓冲区已准备好加载下一个数据。

    So it should be while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE)==RESET);所以应该是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)使用 RXNE 中断,您还将在发送第一个字节(寄存器地址)后发送到 USART

    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:是用于类似传输的CMSIS代码(“第一个周期是写地址,第二个周期是读/写寄存器。”,但不使用中断,并使用STM32F4和SPI配置如下:

     //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?如果是这样,您将 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.我花了一周时间,因为我已将其插入 Arduino 连接器,该连接器连接到其他外围设备而不是 Morpho 连接器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM