使用CH32V203C8T6的Demo程序读取W25Q32JVSIQ数据与实际写入的数据不符

我使用从官网下载的例程包中的\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地址的数据如下图。麻烦大家帮忙看看是什么原因?1.png

程序如下(删掉了部分原代码):

 *@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);
}


我找到原因了,原来程序、接线、电压都是没问题的。因为我是用编程器读取W25Q32里的数据时,直接插在了原来的板子上,所以造成编程器读到的内容是错的。把W25Q32从板子上取下来,重新读取,内容就和程序里面读取到的内容是一致的了。


只有登录才能回复,可以选择微信账号登录