我使用从官网下载的例程包中的\EXAM\SPI\SPI_FLASH文件夹内的程序来测试读取w25Q32JVSIQ中的数据(已经预先通过烧录器烧写进数据了)发现读取到的数据与实际数据不符,但是读取flash的ID又是正确的。
例如,我读取地址0xDA0,得到的数据是:00 00 00 00 18 00 00 00 00 18 00 00 00 00 0C 00 但实际上0xDA0地址的数据如下图。麻烦大家帮忙看看是什么原因?
程序如下(删掉了部分原代码):
*@Note SPI接口操作FLASH外设例程: Master:SPI1_SCK(PA5)、SPI1_MISO(PA6)、SPI1_MOSI(PA7)。 本例程演示 SPI 操作 Winbond W25Qxx SPIFLASH。 注: pins: CS —— PA2 DO —— PA6(SPI1_MISO) WP —— 3.3V DI —— PA7(SPI1_MOSI) CLK —— PA5(SPI1_SCK) HOLD —— 3.3V */ #include "debug.h" #include "string.h" /* Winbond SPIFalsh ID */ #define W25Q80 0XEF13 #define W25Q16 0XEF14 #define W25Q32 0XEF15 #define W25Q64 0XEF16 #define W25Q128 0XEF17 /* Winbond SPIFalsh Instruction List */ #define W25X_WriteEnable 0x06 //Write Enable #define W25X_WriteDisable 0x04 //Write Disable #define W25X_ReadStatusReg 0x05 //Read Status Register-1 #define W25X_WriteStatusReg 0x01 //Write Status Register-1 #define W25X_ReadData 0x03 //Read Data #define W25X_FastReadData 0x0B //Fast Read #define W25X_FastReadDual 0x3B //Fast Read Dual Output #define W25X_PageProgram 0x02 //Page Program #define W25X_BlockErase 0xD8 //Block Erase (64KB) #define W25X_SectorErase 0x20 //Sector Erase (4KB) #define W25X_ChipErase 0xC7 //Chip Erase #define W25X_PowerDown 0xB9 //Power-down #define W25X_ReleasePowerDown 0xAB //Release Power-down / ID #define W25X_DeviceID 0xAB #define W25X_ManufactDeviceID 0x90 //Manufacturer/Device ID #define W25X_JedecDeviceID 0x9F //JEDEC ID /* Global define */ /* Global Variable */ u8 SPI_FLASH_BUF[4096]; const u8 TEXT_Buf[] = {"CH32F103 SPI FLASH W25Qxx"}; #define SIZE sizeof(TEXT_Buf) /********************************************************************* * @fn SPI1_ReadWriteByte * * @brief SPI1 read or write one byte. * * @param TxData - write one byte data. * * @return Read one byte data. */ u8 SPI1_ReadWriteByte(u8 TxData) { u8 i = 0; while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET)//检测TXE是否置位,是,则表示 DR为空,可以写入数据 { i++; if(i > 200) return 0; } SPI_I2S_SendData(SPI1, TxData); i = 0; while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)//检测RXE是否置位,是,则表示 DR接收到数据,即发送完成 { i++; if(i > 200) return 0; } return SPI_I2S_ReceiveData(SPI1); } /********************************************************************* * @fn SPI_Flash_Init * * @brief Configuring the SPI for operation flash. * * @return none */ void SPI_Flash_Init(void) { GPIO_InitTypeDef GPIO_InitStructure = {0}; SPI_InitTypeDef SPI_InitStructure = {0}; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_SetBits(GPIOA, GPIO_Pin_2); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI1, &SPI_InitStructure); SPI_Cmd(SPI1, ENABLE); } /********************************************************************* * @fn SPI_Flash_ReadSR * * @brief Read W25Qxx status register. * ——BIT7 6 5 4 3 2 1 0 * ——SPR RV TB BP2 BP1 BP0 WEL BUSY * * @return byte - status register value. */ u8 SPI_Flash_ReadSR(void) { u8 byte = 0; GPIO_WriteBit(GPIOA, GPIO_Pin_2, 0); SPI1_ReadWriteByte(W25X_ReadStatusReg); byte = SPI1_ReadWriteByte(0Xff); GPIO_WriteBit(GPIOA, GPIO_Pin_2, 1); return byte; } /********************************************************************* * @fn SPI_Flash_ReadID * * @brief Read flash ID. * * @return Temp - FLASH ID. */ u16 SPI_Flash_ReadID(void) { u16 Temp = 0; GPIO_WriteBit(GPIOA, GPIO_Pin_2, 0);//cs SPI1_ReadWriteByte(W25X_ManufactDeviceID); SPI1_ReadWriteByte(0x00); SPI1_ReadWriteByte(0x00); SPI1_ReadWriteByte(0x00); Temp |= SPI1_ReadWriteByte(0xFF) << 8; Temp |= SPI1_ReadWriteByte(0xFF); printf("IDtemp=%x\n\r",Temp); GPIO_WriteBit(GPIOA, GPIO_Pin_2, 1); return Temp; } /********************************************************************* * @fn SPI_Flash_Read * * @brief Read data from flash. * * @param pBuffer - * ReadAddr -Initial address(24bit). * size - Data length. * * @return none */ void SPI_Flash_Read(u8 *pBuffer, u32 ReadAddr, u16 size) { u16 i; GPIO_WriteBit(GPIOA, GPIO_Pin_2, 0); SPI1_ReadWriteByte(W25X_ReadData); SPI1_ReadWriteByte((u8)((ReadAddr) >> 16));//发送24位地址 SPI1_ReadWriteByte((u8)((ReadAddr) >> 8)); SPI1_ReadWriteByte((u8)ReadAddr); printf("read=>0x%.6X\n\r",ReadAddr); for(i = 0; i < size; i++){ pBuffer[i] = SPI1_ReadWriteByte(0XFF); // printf("p-%.2x ",pBuffer[i]); } GPIO_WriteBit(GPIOA, GPIO_Pin_2, 1); } int main(void) { //u8 datap[SIZE]; u8 datap[16]; u16 Flash_Model; u8 x; Delay_Init(); USART_Printf_Init(115200); printf("SystemClk:%d\r\n", SystemCoreClock); SPI_Flash_Init(); Flash_Model = SPI_Flash_ReadID(); printf("Flash_Model->\r\n",Flash_Model); SPI_Flash_Read(datap, 0xDA0, 16);//从地址0xDA0读取16个字节 for(x=0; x<16; x++) { printf("%.2X ",datap[x]); } printf("\r\n"); while(1); }
热门产品 :
CH592: RISC-V内核BLE5.4无线MCU