STM32F107下W25Q80求助

无知者无谓 2017-04-19 04:07:45
W25Q80是连接到SPI3下PC10~12,CS是PD2,SPI1有连接别的设备
使用ST库,初始化SPI后,可以使用0x90命令获取到0xef13,但是读写Flash错误。
最开始用一块板子,可以读写,但是当写到0xe4900地址时错误,无法写入,后面会连着10多个page无法写入,后面就开始有时能写有时不能写的情况。
后来同事拿走那块板子,我换了一块,同一批打的板子,结果更惨了,只能用0x90获取到device id。发现发送0x06后,status register 0根本没有设置WEL位,写入失败。
现在已经不知道怎么办了。请大家帮帮忙!

...全文
613 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
rzsheng 2017-04-20
  • 打赏
  • 举报
回复
这种情况怀疑是Flash硬件坏掉了。 不过还是首先检查一下写入指令和参数是否正确,确保无误后再验证一次。
无知者无谓 2017-04-20
  • 打赏
  • 举报
回复
搞定了,是SPI发送函数问题,我用的是

void SPIFlash_SendByte(uint8_t data) 
{
    /* Check if the SPI is already enabled */ 
    if((SPIFLASH_SPI->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) {
      /* Enable SPI peripheral */
      SET_BIT(SPIFLASH_SPI->CR1, SPI_CR1_SPE);
      HAL_Delay(1);  // Waiting for SPI ready
    }
	/* Wait for SPIFLASH_SPI Tx buffer empty */
    while (!(SPIFLASH_SPI->SR & SPI_SR_TXE)) ;

	/* Send byte through the SPIFLASH_SPI peripheral */
	SPIFLASH_SPI->DR = data;
    while (SPIFLASH_SPI->SR & SPI_SR_BSY) ;
    // Clear register
    uint8_t tmp = SPIFLASH_SPI->DR;
    UNUSED(tmp);
}
uint8_t tmp = SPIFLASH_SPI->DR; UNUSED(tmp); 本是要清DR的,根本没用。但是改为函数返回就可以 uint8_t res = SPIFLASH_SPI->DR; return res;
无知者无谓 2017-04-19
  • 打赏
  • 举报
回复
这是初始化代码

/* SPI defines */
#define SPIFLASH_SPI            SPI3
#define SPIFLASH_SPI_CLK        __HAL_RCC_SPI3_CLK_ENABLE
#define SPIFLASH_SPI_SPEED      SPI_BAUDRATEPRESCALER_8
#define SPIFLASH_SPI_DR_Base    SPI3_BASE+0x0C              // Using in DMA mode
/* CSK */
#define SPIFLASH_GPIO_PIN_SCK   GPIO_PIN_10
#define SPIFLASH_GPIO_PORT_SCK  GPIOC
#define SPIFLASH_GPIO_CLK_SCK   __HAL_RCC_GPIOC_CLK_ENABLE
/* MISO */
#define SPIFLASH_GPIO_PIN_MISO  GPIO_PIN_11
#define SPIFLASH_GPIO_PORT_MISO GPIOC
#define SPIFLASH_GPIO_CLK_MISO  __HAL_RCC_GPIOC_CLK_ENABLE
/* MOSI */
#define SPIFLASH_GPIO_PIN_MOSI  GPIO_PIN_12
#define SPIFLASH_GPIO_PORT_MOSI GPIOC
#define SPIFLASH_GPIO_CLK_MOSI  __HAL_RCC_GPIOC_CLK_ENABLE
/* CS */
#define SPIFLASH_GPIO_PIN_CS    GPIO_PIN_2
#define SPIFLASH_GPIO_PORT_CS   GPIOD
#define SPIFLASH_GPIO_CLK_CS    __HAL_RCC_GPIOD_CLK_ENABLE

#define SPIFLASH_SPI_CS_LOW()  HAL_GPIO_WritePin(SPIFLASH_GPIO_PORT_CS, SPIFLASH_GPIO_PIN_CS, GPIO_PIN_RESET)
#define SPIFLASH_SPI_CS_HIGH() HAL_GPIO_WritePin(SPIFLASH_GPIO_PORT_CS, SPIFLASH_GPIO_PIN_CS, GPIO_PIN_SET)

/* Flash defines */
#define SPIFLASH_DUMMY_BYTE               0xf0
// Command byte
#define SPIFLASH_COMMAND_READ_SR0         0x05  // Read status register 0
#define SPIFLASH_COMMAND_READ_SR1         0x35  // Read Status register 1
#define SPIFLASH_COMMAND_WRITE_ENABLE     0x06  // Enable write command
#define SPIFLASH_COMMAND_WRITE_DISABLE    0x04  // Disable write command
#define SPIFLASH_COMMAND_WRITE_SR         0x01  // Write status register 0 and status register 1
#define SPIFLASH_COMMAND_PAGE_PROGRAM     0x02  // Page program
#define SPIFLASH_COMMAND_READ_DATA        0x03  // Read Data
#define SPIFLASH_COMMAND_FASTREAD_DATA    0x0b  // Fast read data
#define SPIFLASH_COMMAND_BLOCK_ERASE_64K  0xd8  // Erase a block W25Q80/16/32 
#define SPIFLASH_COMMAND_BLOCK_ERASE_32K  0x52  // Erase a block     
#define SPIFLASH_COMMAND_SECTOR_ERASE     0x20  // Erase a sector
#define SPIFLASH_COMMAND_CHIP_ERASE       0x60  // 
#define SPIFLASH_COMMAND_POWERDOWN        0xb9  // 
#define SPIFLASH_COMMAND_DEVICEID         0x90  // Get manufactory ID and device ID
#define SPIFLASH_COMMAND_MBRST            0xff  // Mode Bit Reset
// Status register define
#define SPIFLASH_STATUS_BUSY              (1<<0) // Busy
#define SPIFLASH_STATUS_WEL               (1<<1) // Write Enable Latch
#define SPIFLASH_STATUS_BP0               (1<<2) // Block Protect Bits:0
#define SPIFLASH_STATUS_BP1               (1<<3) // Block Protect Bits:1
#define SPIFLASH_STATUS_BP2               (1<<4) // Block Protect Bits:2
#define SPIFLASH_STATUS_TB                (1<<5) // Top/Bottom Block Protect
#define SPIFLASH_STATUS_SEC               (1<<6) // Sector/Block Protect
#define SPIFLASH_STATUS_SRP0              (1<<7) // Status Register Protect: 0
#define SPIFLASH_STATUS_SRP1              (1<<8) // Status Register Protect: 1
#define SPIFLASH_STATUS_QE                (1<<9) // Quad Enable
/**
*  @brief  Initializes clock
*  @param  None
*  @retval void
*/
static void SPIFlash_RCCConfigSPI(void)
{
    /* Enable GPIO clock  */
    SPIFLASH_GPIO_CLK_SCK();
    SPIFLASH_GPIO_CLK_MISO();
    SPIFLASH_GPIO_CLK_MOSI();
    
    /* Enable SPI clock  */
    SPIFLASH_SPI_CLK();
}

/**
*  @brief  Initializes GPIO for SPI communication
*  @param  None
*  @retval None
*/
static void SPIFlash_GPIOConfigSPI(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    /* SPI_NSS  = High Level  */
    HAL_GPIO_WritePin(SPIFLASH_GPIO_PORT_SCK, SPIFLASH_GPIO_PIN_SCK, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(SPIFLASH_GPIO_PORT_MOSI, SPIFLASH_GPIO_PIN_MOSI, GPIO_PIN_SET);
    HAL_GPIO_WritePin(SPIFLASH_GPIO_PORT_MISO, SPIFLASH_GPIO_PIN_MISO, GPIO_PIN_SET);
    HAL_GPIO_WritePin(SPIFLASH_GPIO_PORT_CS, SPIFLASH_GPIO_PIN_CS, GPIO_PIN_SET);
    
    /* Configure SPI pins: SCK, MISO and MOSI */
    // SCK 
    GPIO_InitStructure.Pin             = SPIFLASH_GPIO_PIN_SCK;
    GPIO_InitStructure.Speed           = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStructure.Mode            = GPIO_MODE_AF_PP;
    HAL_GPIO_Init(SPIFLASH_GPIO_PORT_SCK, &GPIO_InitStructure);
    // MOSI
    GPIO_InitStructure.Pin             = SPIFLASH_GPIO_PIN_MOSI;
    HAL_GPIO_Init(SPIFLASH_GPIO_PORT_MOSI, &GPIO_InitStructure);
    // MISO
    /*  GPIO_InitStructure.Mode        = GPIO_Mode_AF_PP; */
    GPIO_InitStructure.Mode            = GPIO_MODE_INPUT;
    GPIO_InitStructure.Pin             = SPIFLASH_GPIO_PIN_MISO;
    HAL_GPIO_Init(SPIFLASH_GPIO_PORT_MISO, &GPIO_InitStructure);
    
    /* Configure I/O for Chip select */
    // CS
    GPIO_InitStructure.Pin             = SPIFLASH_GPIO_PIN_CS;
    GPIO_InitStructure.Speed           = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStructure.Mode            = GPIO_MODE_OUTPUT_PP;
    HAL_GPIO_Init(SPIFLASH_GPIO_PORT_CS, &GPIO_InitStructure);
    
    __HAL_AFIO_REMAP_SPI3_ENABLE();
}

/**
*  @brief  SET SPI protocol
*  @param  None
*  @retval None
*/
static void SPIFlash_StructureConfigSPI(void)
{
    // Reset SPI3
    SET_BIT(RCC->APB1RSTR, RCC_APB1RSTR_SPI3RST);
    // Cancel reset SPI3
    CLEAR_BIT(RCC->APB1RSTR, RCC_APB1RSTR_SPI3RST);
    
    SPI_HandleTypeDef Flashspi;
    /* SPI Config master with NSS manages by software using the SSI bit*/
    Flashspi.Instance               = SPIFLASH_SPI;
    Flashspi.Init.Mode              = SPI_MODE_MASTER;
    Flashspi.Init.Direction         = SPI_DIRECTION_2LINES;
    Flashspi.Init.DataSize          = SPI_DATASIZE_8BIT;
    Flashspi.Init.BaudRatePrescaler = SPIFLASH_SPI_SPEED;
    Flashspi.Init.NSS               = SPI_NSS_SOFT;
    Flashspi.Init.CLKPolarity       = SPI_POLARITY_LOW;
    Flashspi.Init.CLKPhase          = SPI_PHASE_1EDGE;
    Flashspi.Init.FirstBit          = SPI_FIRSTBIT_MSB;
    Flashspi.Init.TIMode            = SPI_TIMODE_DISABLE;
    Flashspi.Init.CRCCalculation    = SPI_CRCCALCULATION_DISABLE;
    Flashspi.Init.CRCPolynomial     = 7;
    /* Init the SPI BRIDGE */
    if (HAL_SPI_Init(&Flashspi) != HAL_OK) {
        //fatal("Init SPI for flash failed\r\n");
        while(1) ;
    }

}

/***
* NOTICE: 
**/
void SPIFlash_init(void)
{
    /* enables SPI and GPIO clocks */
    SPIFlash_RCCConfigSPI();
    /* configures GPIO as SPI bus  (NSS = SL) */
    SPIFlash_GPIOConfigSPI();
    /* Enable SPI bus */
    SPIFlash_StructureConfigSPI();
    /* Enable SPI peripheral */
    SET_BIT(SPIFLASH_SPI->CR1, SPI_CR1_SPE);
    HAL_Delay(2);  // Wait 1ms for SPI is ready
    /*
    * I do not known why it must send a 0xff byte right after initialization
    * 0xff is a Mode Bit Reset command
    */
    SPIFlash_SendByte(SPIFLASH_COMMAND_MBRST);

    // Make sure the SPI flash is setup successfully
    uint8_t tries = 0;
    while (SPIFlash_DeviceID(NULL) != SPIFLASH_DEVICEID) {
        if (tries++ > 5)
            HAL_NVIC_SystemReset();
        HAL_Delay(500);
        SPIFlash_SendByte(SPIFLASH_COMMAND_MBRST);
        debug("SPI flash W25Q80 initialize failed, try initializing again\r\n");
    }
    info("        Success!\r\n");
}

27,510

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧