- SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
- SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
- SPI_InitStructure.SPI_DataWidth = 8;
- SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
- SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
- SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
- SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
- SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
- SPI_Init(SPI2, &SPI_InitStructure);
- exSPI_DataEdgeAdjust(SPI2, SPI_DataEdgeAdjust_FAST);
- SPI_BiDirectionalLineConfig(SPI2, SPI_Direction_Tx);
- SPI_BiDirectionalLineConfig(SPI2, SPI_Direction_Rx);
- SPI_Cmd(SPI2, ENABLE);
(2)编写SPI发送和读取数据的函数;
- uint32_t writeAndReadData(uint8_t data)
- {
- SPI_SendData(SPI2, data);
- while (1) {
- if(SPI_GetFlagStatus(SPI2, SPI_FLAG_TXEPT)) {
- break;
- }
- }
- while (1) {
- if(SPI_GetFlagStatus(SPI2, SPI_FLAG_RXAVL)) {
- return SPI_ReceiveData(SPI2);
- }
- }
- }
(3)获取W25Q80的设备ID;
- SPI_CSInternalSelected(SPI2, ENABLE); // 片选
- writeAndReadData(0x9F); // 读ID指令
- ID |= writeAndReadData(0x00) << 16;
- ID |= writeAndReadData(0x00) << 8;
- ID |= writeAndReadData(0x00);
- SPI_CSInternalSelected(SPI2, DISABLE); // 取消片选
- printf("\n\nread device id: %X", ID);
(4)全片擦除W25Q80,并检查状态等待擦除完成;
- SPI_CSInternalSelected(SPI2, ENABLE);
- writeAndReadData(0x06); // 写使能
- SPI_CSInternalSelected(SPI2, DISABLE);
-
- SPI_CSInternalSelected(SPI2, ENABLE);
- writeAndReadData(0xC7); // 全片擦除指令
- SPI_CSInternalSelected(SPI2, DISABLE);
-
- SPI_CSInternalSelected(SPI2, ENABLE);
- writeAndReadData(0x05); // 读状态寄存器
- while(1) {
- temp = writeAndReadData(0x00);
- if((temp & 0x01) == 0x0) // 擦除完成
- break;
- }
- SPI_CSInternalSelected(SPI2, DISABLE);
- printf("\n\nerase complete");
(5)写数据,并检查状态等待写完;
- for (i = 0; i < 256; i++) txData[i] = i;
- SPI_CSInternalSelected(SPI2, ENABLE);
- writeAndReadData(0x06);// 写使能
- SPI_CSInternalSelected(SPI2, DISABLE);
-
- SPI_CSInternalSelected(SPI2, ENABLE);
- writeAndReadData(0x02); // 页编程
- writeAndReadData(0x00); // 页地址
- writeAndReadData(0x00);
- writeAndReadData(0x00);
- for (i = 0; i < 256; i++)
- {
- writeAndReadData(txData[i]);
- }
- SPI_CSInternalSelected(SPI2, DISABLE);
-
- SPI_CSInternalSelected(SPI2, ENABLE);
- writeAndReadData(0x05); // 读状态寄存器
- while(1) {
- temp = writeAndReadData(0x00);
- if((temp & 0x01) == 0x0) // 页编程完成
- break;
- }
- SPI_CSInternalSelected(SPI2, DISABLE);
- printf("\n\npage programm complete");
(6)读数据,并打印出来。
- SPI_CSInternalSelected(SPI2, ENABLE);
- writeAndReadData(0x03); // 读数据
- writeAndReadData(0x00); // 页地址
- writeAndReadData(0x00);
- writeAndReadData(0x00);
- for (i = 0; i < 10; i++)
- {
- rxData[i] = writeAndReadData(0x00);
- }
- SPI_CSInternalSelected(SPI2, DISABLE);
- printf("\n\nread data completely\n");
- for (i = 0; i < 10; i++)
- printf("\nrxDate[%d] = %d", i, rxData[i]);
3.串口输出结果
下图为串口输出数据,基本符合程序流程和结果。
4.逻辑分析仪
下图为逻辑分析仪截取的发送接收图片,可以清楚的看到当前SCK速度接近1.125MHz,以及发送数据也符合预期。