打印
[STM32F1]

stm32cubemx 读写W25Q64的问题。

[复制链接]
2041|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dairen|  楼主 | 2016-1-8 09:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我做一个项目,很久没用过STM32的IC了,现在用CUbeMX生成的项目,SPI口读写W25Q64,能读ID就是不能写入数据,用其它的可以读写的,程序也是照搬的,配置也正确,搞了我好几天了找不到问题,我是想做U盘+FATFS的,其它例程都不全,但现在就卡在写上面了,哪位大哥知道或弄过用stm32cubemx 读写W25Q64的 我用的是F103VET6 100pin的
沙发
dairen|  楼主 | 2016-1-8 09:04 | 只看该作者
int16_t SPI_ReadID(void)
{
        uint8_t Tx[6]={0x90,0,0,0,0,0};
        uint8_t Ws[3]={0x01,0,0};
        uint16_t i=0;
        SPI_CS_L;
        HAL_SPI_Transmit(&hspi1,Ws,3,100);
        SPI_CS_H;

        SPI_CS_L;
        SPIx_ReadWriteByte(0x90);
        SPIx_ReadWriteByte(0x00);
        SPIx_ReadWriteByte(0x00);
        SPIx_ReadWriteByte(0x00);
        Rx[4] =SPIx_ReadWriteByte(0xff);
        Rx[5] =SPIx_ReadWriteByte(0xff);
//        HAL_SPI_TransmitReceive(&hspi1,Tx,Rx,6,100);
        SPI_CS_H;
        i |= Rx[4]<<8;
        i |= Rx[5];
        return i;
}

void SPI_Read_Busy(void)
{
        SPI_CS_L;
        while ((SPI_Flash_ReadSR()&0x01)==0x01);   // µÈ´ýBUSYλÇå¿Õ
        SPI_CS_H;
       
}
//SPI_FLASHдʹÄÜ       
//½«WELÖÃλ   
void SPI_FLASH_Write_Enable(void)   
{
//        SPIx_ReadWriteByte(W25X_WriteEnable);      //·¢ËÍдʹÄÜ  
        SPI_CS_L;                            //ʹÄÜÆ÷¼þ     
        HAL_SPI_Transmit(&hspi1,(uint8_t*)0x06,1,100);
        SPI_CS_H;                            //È¡ÏûƬѡ                  
}
void SPI_Flash_Read(uint8_t* pBuffer,uint32_t Addr,uint16_t NumByte)
{               
        uint8_t buf[4]={0x03,Addr>>16,Addr>>8,Addr};
        SPI_CS_L;
        HAL_SPI_Transmit(&hspi1,buf,4,100);
        HAL_SPI_Receive(&hspi1,pBuffer,NumByte,100);       
        SPI_CS_H;
}
uint8_t SPI_FLASH_BUF[4096];
void SPI_Flash_Write(uint8_t* pBuffer,uint32_t Addr,uint16_t NumByte)
{
        uint32_t secpos;
        uint16_t secoff;
        uint16_t secremain;          
        uint16_t i=0;  

        secpos=Addr/4096;//ÉÈÇøµØÖ· 0~511 for w25x16
        secoff=Addr%4096;//ÔÚÉÈÇøÄÚµÄÆ«ÒÆ
        secremain=4096-secoff;//ÉÈÇøÊ£Óà¿Õ¼ä´óС   
        if(NumByte<=secremain)secremain=NumByte;//²»´óÓÚ4096¸ö×Ö½Ú
        while(1)
        {       
                SPI_Flash_Read(SPI_FLASH_BUF,secpos*4096,4096);//¶Á³öÕû¸öÉÈÇøµÄÄÚÈÝ
                for(i=0;i<secremain;i++)//УÑéÊý¾Ý
                {
                        if(SPI_FLASH_BUF[secoff+i]!=0xFF)break;//ÐèÒª²Á³ý            
                }
                if(i<secremain)//ÐèÒª²Á³ý
                {
                        SPI_Flash_Erase_Sector(secpos);//²Á³ýÕâ¸öÉÈÇø
                        for(i=0;i<secremain;i++)           //¸´ÖÆ
                        {
                                SPI_FLASH_BUF[i+secoff]=pBuffer[i];          
                        }
                        SPI_Flash_Write_NoCheck(SPI_FLASH_BUF,secpos*4096,4096);//дÈëÕû¸öÉÈÇø  

                }
                else SPI_Flash_Write_NoCheck(pBuffer,Addr,secremain);//дÒѾ­²Á³ýÁ˵Ä,Ö±½ÓдÈëÉÈÇøÊ£ÓàÇø¼ä.                                   
                if(NumByte==secremain)break;//дÈë½áÊøÁË
                else//дÈëδ½áÊø
                {
                        secpos++;//ÉÈÇøµØÖ·Ôö1
                        secoff=0;//Æ«ÒÆλÖÃΪ0          

                           pBuffer+=secremain;  //Ö¸ÕëÆ«ÒÆ
                          Addr+=secremain;//дµØÖ·Æ«ÒÆ          
                           NumByte-=secremain;                                //×Ö½ÚÊýµÝ¼õ
                        if(NumByte>4096)secremain=4096;        //ÏÂÒ»¸öÉÈÇø»¹ÊÇд²»Íê
                        else secremain=NumByte;                        //ÏÂÒ»¸öÉÈÇø¿ÉÒÔдÍêÁË
                }         
        }       
}
//SPIÔÚÒ»Ò³(0~65535)ÄÚдÈëÉÙÓÚ256¸ö×Ö½ÚµÄÊý¾Ý
//ÔÚÖ¸¶¨µØÖ·¿ªÊ¼Ð´Èë×î´ó256×Ö½ÚµÄÊý¾Ý
//pBuffer:Êý¾Ý´æ´¢Çø
//WriteAddr:¿ªÊ¼Ð´ÈëµÄµØÖ·(24bit)
//NumByteToWrite:ҪдÈëµÄ×Ö½ÚÊý(×î´ó256),¸ÃÊý²»Ó¦¸Ã³¬¹ý¸ÃÒ³µÄÊ£Óà×Ö½ÚÊý!!!         
void SPI_Flash_Write_Page(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
{
                uint8_t Buff[]={0x02,WriteAddr>>16,WriteAddr>>8,WriteAddr};
//                SPI_FLASH_Write_Enable();
                SPI_CS_L;               
                HAL_SPI_Transmit(&hspi1,Buff,4,200);
                HAL_SPI_Transmit(&hspi1,pBuffer,NumByteToWrite,200);           
                SPI_CS_H;
                while ((SPI_Flash_ReadSR()&0x01)==0x01);   // µÈ´ýBUSYλÇå¿Õ                                              //µÈ´ýдÈë½áÊø
               
}
//ÎÞ¼ìÑéдSPI FLASH
//±ØÐëÈ·±£ËùдµÄµØÖ··¶Î§ÄÚµÄÊý¾ÝÈ«²¿Îª0XFF,·ñÔòÔÚ·Ç0XFF´¦Ð´ÈëµÄÊý¾Ý½«Ê§°Ü!
//¾ßÓÐ×Ô¶¯»»Ò³¹¦ÄÜ
//ÔÚÖ¸¶¨µØÖ·¿ªÊ¼Ð´ÈëÖ¸¶¨³¤¶ÈµÄÊý¾Ý,µ«ÊÇҪȷ±£µØÖ·²»Ô½½ç!
//pBuffer:Êý¾Ý´æ´¢Çø
//WriteAddr:¿ªÊ¼Ð´ÈëµÄµØÖ·(24bit)
//NumByteToWrite:ҪдÈëµÄ×Ö½ÚÊý(×î´ó65535)
//CHECK OK
void SPI_Flash_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)   
{                                           
        uint16_t pageremain;          
        pageremain=256-WriteAddr%256; //µ¥Ò³Ê£ÓàµÄ×Ö½ÚÊý                             
        if(NumByteToWrite<=pageremain)pageremain=NumByteToWrite;//²»´óÓÚ256¸ö×Ö½Ú
        while(1)
        {          
                SPI_Flash_Write_Page(pBuffer,WriteAddr,pageremain);
                if(NumByteToWrite==pageremain)break;//дÈë½áÊøÁË
                 else //NumByteToWrite>pageremain
                {
                        pBuffer+=pageremain;
                        WriteAddr+=pageremain;       

                        NumByteToWrite-=pageremain;                          //¼õÈ¥ÒѾ­Ð´ÈëÁ˵Ä×Ö½ÚÊý
                        if(NumByteToWrite>256)pageremain=256; //Ò»´Î¿ÉÒÔдÈë256¸ö×Ö½Ú
                        else pageremain=NumByteToWrite;           //²»¹»256¸ö×Ö½ÚÁË
                }
        }            
}
//²Á³ýÒ»¸öÉÈÇø
//Dst_Addr:ÉÈÇøµØÖ· 0~511 for w25x16
//²Á³ýÒ»¸öɽÇøµÄ×îÉÙʱ¼ä:150ms
void SPI_Flash_Erase_Sector(uint32_t Dst_Addr)   
{                       
                Dst_Addr*=4096;
                uint8_t buf[]={0x20,Dst_Addr>>16,Dst_Addr>>8,Dst_Addr};
                SPI_CS_L;
                HAL_SPI_Transmit(&hspi1,buf,4,100);//·¢ËÍÉÈÇø²Á³ýÖ¸Áî         
                SPI_CS_H;
          while ((SPI_Flash_ReadSR()&0x01)==0x01);   // µÈ´ýBUSYλÇå¿Õ                  
}  
//¶ÁÈ¡SPI_FLASHµÄ״̬¼Ä´æÆ÷
//BIT7  6   5   4   3   2   1   0
//SPR   RV  TB BP2 BP1 BP0 WEL BUSY
//SPR:ĬÈÏ0,״̬¼Ä´æÆ÷±£»¤Î»,ÅäºÏWPʹÓÃ
//TB,BP2,BP1,BP0:FLASHÇøÓòд±£»¤ÉèÖÃ
//WEL:дʹÄÜËø¶¨
//BUSY:æ±ê¼Çλ(1,æ;0,¿ÕÏÐ)
//ĬÈÏ:0x00
uint8_t BUSY;
uint8_t SPI_Flash_ReadSR(void)   
{  
        uint8_t Tx[2]={W25X_ReadStatusReg,0};   
  uint8_t Rx[2]={0,0};
        SPI_CS_L;  
        HAL_SPI_TransmitReceive(&hspi1,Tx,Rx,2,100);    //·¢ËͶÁȡ״̬¼Ä´æÆ÷ÃüÁî  
  SPI_CS_H;
        BUSY = Rx[1];
        return Rx[1];   
}
//²Á³ýÕû¸öоƬ
//ÕûƬ²Á³ýʱ¼ä:
//W25X16:25s
//W25X32:40s
//W25X64:40s
//µÈ´ýʱ¼ä³¬³¤...
void SPI_Flash_Erase_Chip(void)   
{         
//                uint8_t Tx[]={}
                SPI_CS_L;
    HAL_SPI_Transmit(&hspi1,(uint8_t*)W25X_WriteEnable,1,200);      //·¢ËÍдʹÄÜ      
                SPI_CS_H;
                SPI_CS_L;
    HAL_SPI_Transmit(&hspi1,(uint8_t*)(W25X_ChipErase),1,200);      //·¢ËÍƬ²Á³ýÃüÁî        
                SPI_CS_H;
                while ((SPI_Flash_ReadSR()&0x01)==0x01);   // µÈ´ýBUSYλÇå¿Õ
                               
}   

/* SPI1 init function */
void MX_SPI1_Init(void)
{
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
//        hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
//  hspi1.Init.NSS = SPI_NSS_SOFT; //
        hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLED;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLED;//SPI_CRCCALCULATION_DISABLED;
  hspi1.Init.CRCPolynomial = 7;
  HAL_SPI_Init(&hspi1);
       
}

void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{

  GPIO_InitTypeDef GPIO_InitStruct;
//        SPI_InitTypeDef                SPI_InitStructure;
//        GPIO_InitTypeDef        GPIO_InitStructure;
  if(hspi->Instance==SPI1)
  {
  /* USER CODE BEGIN SPI1_MspInit 0 */

  /* USER CODE END SPI1_MspInit 0 */
    /* Peripheral clock enable */
    __SPI1_CLK_ENABLE();
  
    /**SPI1 GPIO Configuration   
    PA4     ------> SPI1_NSS
    PA5     ------> SPI1_SCK
    PA6     ------> SPI1_MISO
    PA7     ------> SPI1_MOSI
    */
//                GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
//                GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
//                GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
               
    GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
               
                GPIO_InitStruct.Pin = GPIO_PIN_4;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* Peripheral interrupt init*/
//    HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0);
//    HAL_NVIC_EnableIRQ(SPI1_IRQn);
//                HAL_SPI_Transmit_IT(&hspi1,(uint8_t*)0x00,1);
  /* USER CODE BEGIN SPI1_MspInit 1 */
        SPI_FLASH_Write_Enable();
  /* USER CODE END SPI1_MspInit 1 */
  }
}

void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
{

  if(hspi->Instance==SPI1)
  {
  /* USER CODE BEGIN SPI1_MspDeInit 0 */

  /* USER CODE END SPI1_MspDeInit 0 */
    /* Peripheral clock disable */
    __SPI1_CLK_DISABLE();
  
    /**SPI1 GPIO Configuration   
    PA4     ------> SPI1_NSS
    PA5     ------> SPI1_SCK
    PA6     ------> SPI1_MISO
    PA7     ------> SPI1_MOSI
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);

    /* Peripheral interrupt Deinit*/
    HAL_NVIC_DisableIRQ(SPI1_IRQn);

  }
  /* USER CODE BEGIN SPI1_MspDeInit 1 */

  /* USER CODE END SPI1_MspDeInit 1 */
}

使用特权

评论回复
板凳
qq4988| | 2016-1-8 09:57 | 只看该作者
网上的读写程序好多啊

使用特权

评论回复
地板
dairen|  楼主 | 2016-1-8 10:25 | 只看该作者
我找了好多,都是很老的,不太合适我。

使用特权

评论回复
5
icecut| | 2016-1-8 10:43 | 只看该作者
注意异步传输.函数返回了不一定是执行结束了.cs 不能冒然拉高....

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

26

帖子

0

粉丝