首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >STM32发现F3环回RXFIFO不接收任何数据

STM32发现F3环回RXFIFO不接收任何数据
EN

Stack Overflow用户
提问于 2017-02-14 16:05:18
回答 1查看 733关注 0票数 2

我正在使用STM32 F3发现工具包,并开始处理SPI外围设备。我从一个简单的回循环系统开始:我检查TXFIFOLVL状态,如果没有满,我将数据发送到DR寄存器,然后它应该返回到我的RxBuffer (我从DR读取数据,而RXFIFOLVL并不是空的),但我遇到了一个问题--我在接收缓冲区中没有得到任何东西,我似乎也不明白为什么。我不使用HAL标准外设库,因此我配置SPI并通过寄存器值使用它,如下所示:

SPI代码的头文件:

代码语言:javascript
复制
#define GPIOA_ENABLE                    0b1<<17             // Enable GPIO port A clock in AHBENR register
#define SPI1_CLOCK_ENABLE               0b1<<12             // Enable SPI1 clock in APB2ENR register
#define SPI1_PIN_ALT_FNC                0b1010<<4           // Sets PA5,PA6 & PA7 to Alternative function
#define SPI1_OUTPUT_TYPE                ~(0b111<<5)         // Sets PA5, PA6 & PA7 to push-pull
#define SPI1_PIN_SPEED                  0b1111<<4           // Sets pins from 4 to 7 to work on 50 MHz output speed
#define SPI1_PIN_ALT_FNC_LOW            0b0101<<4           // Sets the Alternative function to AF5 in alternative function low register
#define SPI1_PIN_ALT_FNC_HIGH           0b0101<<4           // Sets the Alternative function to AF5 in alternative function high register
#define SPI1_BAUDRATE_PRESCALER_2       0b000<<3            // F_PCLK/2
#define SPI1_BAUDRATE_PRESCALER_128     0b110<<3            // F_PCLK/128
#define SPI1_MASTER_MODE                0b1<<2              // Sets the SPI1 to master mode
#define SPI1_PERI_ENABLE                0b1<<6              // Enable the SPI peripheral
#define SPI1_SSM_ENABLE                 0b1<<9              // Enable SPI software slave management
#define SPI1_SSI_ENABLE                 0b1<<8              // SPI1 internal slave select
#define SPI1_NSSP_ENABLE                0b1<<3              // Enable NSS pulse management
#define SPI1_FRXTH_8BIT                 0b1<<12             //Set the FIFO reception threshold to 8 bits
#define SPI1_DATA_SIZE                  0b0111<<8           // SPI1 DATA size
#define SPI1_TXFIFO_FULL_FLAG           0b11<<11            // SPI1 Tx FIFO transmission flag
#define SPI1_RXFIFO_EMPTY_FLAG          0b00<<9             // SPI1 Rx FIFO reception flag

#include "main.h"
#include "stm32f3xx_hal.h"

void spi_init();
void spi_WriteRead(uint8_t *rxBuffer, uint8_t *txBuffer, uint8_t bufferSize);

SPI代码的代码文件:

代码语言:javascript
复制
#include "SPI_toSD.h"

/* SPI1 configuration
 * PA5 - SCK
 * PA6 - MISO
 * PA7 - MOSI
 */
void spi_init(){

// Start the GPIO and peripheral clocks in Reset and Clock Control register
RCC->AHBENR |= GPIOA_ENABLE;
RCC->APB2ENR |= SPI1_CLOCK_ENABLE;

// Configure the GPIOs for SPI communication
GPIOA->MODER |= SPI1_PIN_ALT_FNC;
GPIOA->OTYPER &= SPI1_OUTPUT_TYPE;
GPIOA->OSPEEDR |= SPI1_PIN_SPEED;
GPIOA->AFR[0] |= SPI1_PIN_ALT_FNC_LOW;
GPIOA->AFR[1] |= SPI1_PIN_ALT_FNC_HIGH;

// Configure the SPI peripheral
SPI1->CR1 |= SPI1_BAUDRATE_PRESCALER_2;
SPI1->CR1 |= SPI1_SSM_ENABLE;
SPI1->CR1 |= SPI1_MASTER_MODE;
SPI1->CR1 |= SPI1_SSI_ENABLE;
SPI1->CR2 |= SPI1_DATA_SIZE;
SPI1->CR2 |= SPI1_FRXTH_8BIT;
SPI1->CR2 |= SPI1_NSSP_ENABLE;
SPI1->CR1 |= SPI1_PERI_ENABLE;
SPI1->CR1 &= ~SPI1_SSI_ENABLE;

}

void spi_WriteRead(uint8_t *rxBuffer, uint8_t *txBuffer, uint8_t bufferSize){
int i;
while((SPI1->SR & 0b11<<11)==SPI1_TXFIFO_FULL_FLAG);
for(i=0;i<bufferSize;i++){
        SPI1->DR |= *txBuffer;  // send *txBuffer++
        txBuffer++;


    while((SPI1->SR & 0b11<<9)!=SPI1_RXFIFO_EMPTY_FLAG){
        *rxBuffer = SPI1->DR;
        rxBuffer++;
    }
}

}

总的来说,我只需定义我的缓冲区并按如下方式初始化它们:

代码语言:javascript
复制
uint8_t rx_buff[SIZE] = {0,0,0,0,0,0,0,0,0,0};
uint8_t tx_buff[SIZE] = {1,2,3,4,5,6,7,8,9,10};

因此,在调用了我的spi_WriteRead()函数之后,我很自然地希望这些缓冲区具有相同的值。

我调用我的spi_init()函数,在while循环中调用spi_WriteRead()函数:

代码语言:javascript
复制
  spi_WriteRead(rx_buff,tx_buff,SIZE);

在我的main.c中,大小定义为:

代码语言:javascript
复制
#define SIZE  10

我使用SW4STM32环境来编码和调试,所以在我的调试器中我可以看到所有的寄存器值。我的SPI就像我定义的一样初始化,我的数据被发送到TXFIFO缓冲区,但是RXFIFO缓冲区没有收到任何东西。如果我检查SPI SR寄存器,我可以看到我的TXFIFO已被填满,但是RXFIFO标志显示它是空的。

有人知道我可能做错了什么吗?我是不是误解了SPI的一些简单的东西?谢谢你的意见!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-14 20:27:31

编辑:

好好看看这里:

代码语言:javascript
复制
#define SPI1_SSI_ENABLE                 0b1<<8
...
SPI1->CR1 |= SPI1_PERI_ENABLE;
SPI1->CR1 &= ~SPI1_SSI_ENABLE;

现在您可能知道为什么#define宏通常被认为是个坏主意。如果使用来自#define头的stm32f3xxx.h值,则不会出现此问题,因为所有有操作的值都有括号。你没有他们。这就是为什么编译器的代码如下所示:

代码语言:javascript
复制
SPI1->CR1 |= SPI1_PERI_ENABLE;
SPI1->CR1 &= ~0b1<<8;

相当于:

代码语言:javascript
复制
SPI1->CR1 |= SPI1_PERI_ENABLE;
SPI1->CR1 &= (~0b1)<<8;

并进一步:

代码语言:javascript
复制
SPI1->CR1 |= SPI1_PERI_ENABLE;
SPI1->CR1 &= 0xffffff00;

可能不是你想要的。

您还应该知道,如果您的设备是主设备,则应该同时设置SSI和SSM位。https://stackoverflow.com/a/42169600/157344

原件:

请注意,在这些设备中,当您直接访问SPI1->DR时,您将同时发送/接收两个字节。这是因为这个寄存器被定义为uint16_t和SPI支持所谓的“数据打包”(在参考手册中搜索它)。如果希望一次发送/接收一个字节,则需要将寄存器转换为写入和读取,如下所示:

代码语言:javascript
复制
readByte = (volatile uint8_t*)SPI1->DR;
(volatile uint8_t*)SPI1->DR = writeByte;

顺便说一句--为什么不使用CMSIS头提供的#defines呢?你不必定义像SPI1_MASTER_MODE这样的东西..。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42230862

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档