Winbond W25Q和STM32F411 BlackPill -SPI不响应

发布于 2025-02-12 07:03:04 字数 2663 浏览 0 评论 0原文

我正在在CMSI上写SPI驱动程序,用于在STM32F411 BlackPill Board上填充的W25Q(25Q64FVSIG)。我的问题是闪存没有通过SPI响应信号。 MCU被配置为主人,Flash作为从。产生时钟和MOSI信号,将CS设置为低。但是,如下图所示,我没有在味o上观察到答案。

引脚映射: (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和 /闪光灯销,通过板的设计将其设置为高,以下示意图。

STM32F411 BlackPill示意图(左下方闪光灯):

I'm writing SPI driver on top of CMSIS for W25Q (25Q64FVSIG) populated on STM32F411 Blackpill board. My problem is that flash memory are not responding to signals via SPI. MCU is configured as master, flash as slave. Clock and MOSI signal are generated, CS is set low. However, I do not observe the answer on MISO, as in picture below.

Pin mapping:
(PA4 - CS)
(PA5 - SCK)
(PA7 - MOSI)
(PB4 - MISO)

I suspected problems with the flash chip, but after replacing it with a new one, I observe no improvement. At the same time, I'm looking at the code and waveforms and can't work out what I'm doing wrong. I also don't have anyone by my side to look with me. So I am counting on your help!

Oscilloscope measurement picture - attempt to read JEDEC ID

This is what my driver code looks like:

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

And its used this way to read 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 and /FLASH pins are set up to high by design of board, schematic included below.

STM32F411 Blackpill schematic (flash in bottom left):
STM32F411 Blackpill schematic

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

傲娇萝莉攻 2025-02-19 07:03:04

我发现了这个问题。正是我板上的Flash的味o被连接到引脚PA7,而不是PB4的文档中。我可能有不同版本的该板。

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

I found the problem. It was that the MISO for flash on my board is connected to pin PA7, not as in the documentation to PB4. I probably have a different version of this board.

Never trust schematics! Check for yourself on a real board!

哆啦不做梦 2025-02-19 07:03:04
    GPIOA->MODER &= ~GPIO_MODER_MODE4;
    GPIOA->MODER &= ~GPIO_MODER_MODE5;
    GPIOA->MODER &= ~GPIO_MODER_MODE7;
    GPIOB->MODER &= ~GPIO_MODER_MODE4;

GPIOA三倍,只有一个GPIOB。设置时相同。我相信复制粘贴错误。检查代码中是否存在类似的错误。

您应该使用功能来避免此类问题。

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

three times GPIOA and only one GPIOB. Same when setting. Copy paste error I believe. Check for similar errors in your code.

You should use functions to avoid such problems.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文