直入正题,用的芯片是STM32F091RCT6, 用SPI读取W25Q64时,读取数据不对,主要原因是SPI的分频值配置的问题。
当我将SPI分频值配置8的时候,读取的数据都不对,只有将分频配置成8,也就是速度是6MBits/s的时候,读取的数据才是正确的。
看hal库spi的说明:
#define GPIO_SPEED_FREQ_LOW (0x00000000U) /*!< range up to 2 MHz, please refer to the product datasheet */
#define GPIO_SPEED_FREQ_MEDIUM (0x00000001U) /*!< range 4 MHz to 10 MHz, please refer to the product datasheet */
#define GPIO_SPEED_FREQ_HIGH (0x00000003U) /*!< range 10 MHz to 50 MHz, please refer to the product datasheet */
我的SPI配置是:
void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; //必须是8分频才行,读取数据才是正确的
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 7;
hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
}
分频是32,即48/32=1.5MBits/s,属于低速,所以引脚配置为:
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;//这里是HIGH还是MEDIUM都可以
GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
这样读取出来的数据就是正确的了:只有在8分频的时候读取的才是正确的。其他都试过,都不正确
2020-3-30日更正:
经过这几天的测试,上面的方法也不能保证每次读取都是正确的,通过查找资源以及原来F1芯片上的代码,发现通过在初始化完成后,进行1字节的读取操作,之后每次的读写操作就都是正确的了,虽然问题解决了,但是还不清楚原理???
如下图,加上红色框框里面的这句话就读写正常了:
同时,也是受到这篇文章的启发,https://blog.csdn.net/weixin_44529321/article/details/103720347https://blog.csdn.net/weixin_44529321/article/details/103720347
但是我按照这篇文章中的方法将CS默认高电平,我的程序也还是不行,只有加上那句读写1字节的才做才可以。