赞
踩
W25Q256(256Mb)将32M(字节byte)的容量分为512个块(block),每个块大小为64K字节,每个块又分为16个扇区(sector),每个扇区4K字节。最小擦除单位为一个扇区,也就是4K字节。
首先应该配置SPI,但是这里有个大坑.
按照标准的SPI协议,当SPI被配置为主机模式后,通过SPI对从设备进行操作时,其NSS应该自动置低,从而选中(使能)从设备;一旦不对从设备进行操作,NSS立刻置为高。
但是,我在实际调试过程中发现:STM32 SPI NSS无法自动实现跳变。 一旦SPI初始化完成并使能SPI,NSS立刻置低,然后保持不变。
这个问题一直无法解决,直到我在ST官方论坛上看到国外有些技术人员也在讨论这个问题,他们得出的结论是:STM32 SPI NSS无法自动跳变。
ST官方技术人员也证实:STM32 SPI NSS是不会自动置位和复位的。按照官方说法,ST已经将其列入了改进计划。
对于这个问题,可以采用下面的方法解决:
在SPI初始化时,采用NSS soft模式,然后使能NSS输出功能。从而将NSS当做GPIO使用,通过软件set和reset来实现NSS的置位和复位。
具体在CubeMX中应将FLASH的NSS当成GPIO Output配置而不是SPI NSS.配置如图所示:
因为需要在flash中存入浮点数,所以需要类型转换,这里使用union联合体实现:
union test
{
float union_float;
uint8_t union_int8[4];
};
测试代码:
union test Test_write,Test_read; Test_write.union_float=1.23; //读flash的id BSP_W25Q256_Read_ID(id); printf("ID = 0x%02X%02X\r\n", id[0], id[1]); //测试flash的擦读写 BSP_W25Q256_Erase_Block(0); BSP_W25Q256_Write(Test_write.union_int8, 0, sizeof(Test_write.union_int8)); BSP_W25Q256_Read(Test_read.union_int8, 0, sizeof(Test_read.union_int8)); printf("Ready to write: float: %f, trans to uint8: 0x%x 0x%x 0x%x 0x%x\r\n", Test_write.union_float, Test_write.union_int8[0], Test_write.union_int8[1], Test_write.union_int8[2], Test_write.union_int8[3]); printf("Read from Flash: uint8: 0x%x 0x%x 0x%x 0x%x, trans to float: %f\r\n", Test_read.union_int8[0], Test_read.union_int8[1], Test_read.union_int8[2], Test_read.union_int8[3], Test_read.union_float);
参考:
关于STM32 SPI NSS的讨论 https://blog.csdn.net/chseangs/article/details/4520733
SPI problem with hardware NSS management https://community.st.com/s/question/0D50X00009XkbvdSAB/spi-problem-with-hardware-nss-management
STM32CbueMX之W25Q256 https://blog.csdn.net/sudaroot/article/details/93158309
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。