C语言 Winbond W25Q和STM32F411 Blackpill - SPI无响应



我在CMSIS上为W25Q (25Q64FVSIG)编写SPI驱动程序,该驱动程序填充在STM32F411 Blackpill板上。我的问题是,闪存不响应通过SPI信号。配置MCU为主,flash为从。时钟和MOSI信号产生,CS设置低。然而,我没有看到MISO上的答案,如下图所示。

销映射:(pa4 - cs)(PA5 - SCK)(pa7 - mosi)(PB4 - MISO)

我怀疑闪存芯片有问题,但更换新芯片后,我发现没有任何改善。与此同时,我看着代码和波形,不知道我做错了什么。我身边也没有人陪我看。所以我就指望你的帮助了!

示波器测量图-尝试读取JEDEC ID

我的驱动程序代码是这样的:

uint32_t w25_pin_spi_init(void)
{
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
/* setup alternate functions of PA5/PA7/PB4 and output to PA4 (NSS)*/
GPIOA->MODER &= ~GPIO_MODER_MODE4;
GPIOA->MODER &= ~GPIO_MODER_MODE5;
GPIOA->MODER &= ~GPIO_MODER_MODE7;
GPIOB->MODER &= ~GPIO_MODER_MODE4;
GPIOA->MODER |= GPIO_MODER_MODE4_0; //output
GPIOA->MODER |= GPIO_MODER_MODE5_1; //alternate
GPIOA->MODER |= GPIO_MODER_MODE7_1;
GPIOB->MODER |= GPIO_MODER_MODE4_1;
GPIOA->OSPEEDR |= (GPIO_OSPEEDR_OSPEED4_0 | GPIO_OSPEEDR_OSPEED4_1);
/* OTYPER in reset state */
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD5;
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD7;
GPIOB->PUPDR &= ~GPIO_PUPDR_PUPD4;
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD4;
/* pull-up for MISO */
GPIOB->PUPDR |= GPIO_PUPDR_PUPD4_0;
GPIOA->AFR[0] |= (GPIO_AFRL_AFSEL5_0 | GPIO_AFRL_AFSEL5_2);
GPIOA->AFR[0] |= (GPIO_AFRL_AFSEL7_0 | GPIO_AFRL_AFSEL7_2);
GPIOB->AFR[0] |= (GPIO_AFRL_AFSEL4_0 | GPIO_AFRL_AFSEL4_2);
return 0;
}
void w25_CS_enable(void)
{
GPIOA->BSRR |= GPIO_BSRR_BR4;
}
void w25_CS_disable (void)
{
GPIOA->BSRR |= GPIO_BSRR_BS4;
}
uint32_t w25_spi_init(void)
{
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
SPI1->CR1 &= ~SPI_CR1_DFF;
SPI1->CR1 |= (SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0);
SPI1->CR1 |= SPI_CR1_MSTR;
SPI1->CR1 |= SPI_CR1_SSM;
SPI1->CR1 |= SPI_CR1_SSI;
SPI1->CR1 |= SPI_CR1_SPE;
return 0;
}
uint16_t w25_send_receive_data(uint16_t data)
{
while(!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = data;
while(!(SPI1->SR & SPI_SR_RXNE));
return SPI1->DR;
}

用这种方式读取JEDEC ID:

w25_pin_spi_init();
w25_spi_init();
[...]
w25_CS_enable();
w25_send_receive_data(0x9F);
uint16_t manuf = w25_send_receive_data(0x00);
uint16_t mem_type = w25_send_receive_data(0x00);
uint16_t capa = w25_send_receive_data(0x00);
w25_CS_disable();

/WP和/FLASH引脚通过电路板设计设置为高电平,原理图如下。

STM32F411黑丸原理图(左下闪烁):STM32F411黑丸原理图

我找到问题了。这是我的板上的flash的MISO连接到引脚PA7,而不是在文档中连接到PB4。我可能有一个不同版本的黑板。

永远不要相信原理图!在一块真正的板子上自己检查一下!

GPIOA->MODER &= ~GPIO_MODER_MODE4;
GPIOA->MODER &= ~GPIO_MODER_MODE5;
GPIOA->MODER &= ~GPIO_MODER_MODE7;
GPIOB->MODER &= ~GPIO_MODER_MODE4;

是GPIOA的三倍,只有一个GPIOB。设置时也一样。我想是复制粘贴错误。检查代码中是否有类似的错误。

你应该使用函数以避免此类问题。

最新更新