stm32f100读写w25q32问题,读写不了数据,差不出什么原因

2019-08-23 16:59发布

程序如下:


void SPI2_Init(void)
{       
        SPI_InitTypeDef  SPI_InitStructure;
        GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2 ,ENABLE);
        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );   //PORTB时钟使能
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 |GPIO_Pin_14| GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
    GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);  //PB13/14/15上拉
       


       
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;                 //PB12:CS片选信号
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;           //推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB,&GPIO_InitStructure);
        GPIO_SetBits(GPIOB,GPIO_Pin_12);
   
  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_2;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPI2, &SPI_InitStructure);
  //打开SPI2
  SPI_Cmd(SPI2, ENABLE);
  //SPI2_ReadWriteByte(0xff);//启动传输  

}   

//SPI写入一个字节
u8 SPI_FLASH_SendByte(u8 byte)
{
        /* Loop while DR register in not emplty */
        while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);

        /* Send byte through the SPI1 peripheral */
        SPI_I2S_SendData(SPI2, byte);

          /* Wait to receive a byte */
        while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);

  /* Return the byte read from the SPI bus */
  return SPI_I2S_ReceiveData(SPI2);
}



#define SPI_FLASH_PageSize 256

u16 SPI_FLASH_TYPE=W25Q32;//默认就是25Q32

//4Kbytes为一个Sector
//8个扇区为1个Block
//W25Q32
//容量为4M字节,共有64个Block,1024个Sector
                                                                                                         
//初始化SPI FLASH的IO口
void SPI_Flash_Init(void)
{   
        SPI2_Init();                           //初始化SPI
        SPI_FLASH_CS=1;     //取消片选
}  


//SPI_FLASH写使能       
//将WEL置位   
void SPI_FLASH_Write_Enable(void)   
{
        SPI_FLASH_CS=0;                            //使能器件   
  SPI_FLASH_SendByte(W25X_WriteEnable);      //发送写使能  
        SPI_FLASH_CS=1;                            //取消片选                  
}

//SPI_FLASH写禁止       
//将WEL清零  
void SPI_FLASH_Write_Disable(void)   
{  
        SPI_FLASH_CS=0;                            //使能器件   
  SPI_FLASH_SendByte(W25X_WriteDisable);     //发送写禁止指令   
        SPI_FLASH_CS=1;                            //取消片选                  
}                


void SPI_FLASH_WaitForWriteEnd(void)
{
        u8 byte=0;
        SPI_FLASH_CS=0;
        SPI_FLASH_SendByte(W25X_ReadStatusReg);    //发送读取状态寄存器命令
        do
        {
                byte=SPI_FLASH_SendByte(0X00);
        } while((byte & W25X_WriteStatusReg)==SET);
       
        SPI_FLASH_CS=1;        //取消片选  
}
//读取SPI_FLASH的状态寄存器
u8 SPI_Flash_ReadSR(void)   
{  
        u8 byte=0;   
        SPI_FLASH_CS=0;                            //使能器件   
        SPI_FLASH_SendByte(W25X_ReadStatusReg);    //发送读取状态寄存器命令   
        byte=SPI_FLASH_SendByte(0X00);                //发送一个字节           
        SPI_FLASH_CS=1;        //取消片选  
  return         byte & 0x01 ;
}

//擦除扇区
void SPI_Flash_Erase_Sector(u32 SectorAddr)   
{  
  SPI_FLASH_Write_Enable();                  //SET WEL           
  SPI_FLASH_CS=0;                            //使能器件   
  SPI_FLASH_SendByte(W25X_SectorErase);      //发送扇区擦除指令
        /* Send SectorAddr high nibble address byte */
  SPI_FLASH_SendByte((SectorAddr & 0xFF0000) >> 16);
  /* Send SectorAddr medium nibble address byte */
  SPI_FLASH_SendByte((SectorAddr & 0xFF00) >> 8);
  /* Send SectorAddr low nibble address byte */
  SPI_FLASH_SendByte(SectorAddr & 0xFF);
        SPI_FLASH_CS=1;                            //取消片选                  
}  



//写1个字节
void SPI_FLASH_ByteWrite(u8 Buffer, u32 WriteAddr)
{
  /* Wait the end of Flash writing */
  SPI_FLASH_WaitForWriteEnd();  
       
        /* Enable the write access to the FLASH */
  SPI_FLASH_Write_Enable();

  /* Select the FLASH: Chip Select low */
  SPI_FLASH_CS=0;
  /* Send "Write to Memory " instruction */
  SPI_FLASH_SendByte(W25X_PageProgram);
  /* Send WriteAddr high nibble address byte to write to */
  SPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16);
  /* Send WriteAddr medium nibble address byte to write to */
  SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8);  
  /* Send WriteAddr low nibble address byte to write to */
  SPI_FLASH_SendByte(WriteAddr & 0xFF);


        /* Send the current byte */
        SPI_FLASH_SendByte(Buffer);
        /* Point on the next byte to be written */

  /* Deselect the FLASH: Chip Select high */
  SPI_FLASH_CS=1;
}



//写1页
void SPI_FLASH_PageWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
{
  /* Enable the write access to the FLASH */
  SPI_FLASH_Write_Enable();

  /* Select the FLASH: Chip Select low */
  SPI_FLASH_CS=0;
  /* Send "Write to Memory " instruction */
  SPI_FLASH_SendByte(W25X_PageProgram        );
  /* Send WriteAddr high nibble address byte to write to */
  SPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16);
  /* Send WriteAddr medium nibble address byte to write to */
  SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8);  
  /* Send WriteAddr low nibble address byte to write to */
  SPI_FLASH_SendByte(WriteAddr & 0xFF);

  /* while there is data to be written on the FLASH */
  while(NumByteToWrite--)
  {
    /* Send the current byte */
    SPI_FLASH_SendByte(*pBuffer);
    /* Point on the next byte to be written */
    pBuffer++;
  }

  /* Deselect the FLASH: Chip Select high */
  SPI_FLASH_CS=1;

  /* Wait the end of Flash writing */
  SPI_FLASH_WaitForWriteEnd();  
}

/*******************************************************************************
* Function Name  : SPI_FLASH_BufferWrite
* Description    : Writes block of data to the FLASH. In this function, the
*                  number of WRITE cycles are reduced, using Page WRITE sequence.
* Input          : - pBuffer : pointer to the buffer  containing the data to be
*                    written to the FLASH.
*                  - WriteAddr : FLASH's internal address to write to.
*                  - NumByteToWrite : number of bytes to write to the FLASH.
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_FLASH_BufferWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
{
        u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0;

        Addr = WriteAddr % SPI_FLASH_PageSize;
        count = SPI_FLASH_PageSize - Addr;
        NumOfPage =  NumByteToWrite / SPI_FLASH_PageSize;
        NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;

        if(Addr == 0) /* WriteAddr is SPI_FLASH_PageSize aligned  */
        {
                if(NumOfPage == 0) /* NumByteToWrite < SPI_FLASH_PageSize */
                {
                        SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
                }
                else /* NumByteToWrite > SPI_FLASH_PageSize */
                {
                        while(NumOfPage--)
                        {
                                SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);
                                WriteAddr +=  SPI_FLASH_PageSize;
                                pBuffer += SPI_FLASH_PageSize;  
                        }
                        SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);
                }
        }
        else /* WriteAddr is not SPI_FLASH_PageSize aligned  */
        {
                if(NumOfPage== 0) /* NumByteToWrite < SPI_FLASH_PageSize */
                {
                        if(NumOfSingle > count) /* (NumByteToWrite + WriteAddr) > SPI_FLASH_PageSize */
                        {
                                temp = NumOfSingle - count;
                          
                                SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);
                                WriteAddr +=  count;
                                pBuffer += count;
                               
                                SPI_FLASH_PageWrite(pBuffer, WriteAddr, temp);
                        }
                        else
                        {
                                SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
                        }
                }
                else /* NumByteToWrite > SPI_FLASH_PageSize */
                {
                        NumByteToWrite -= count;
                        NumOfPage =  NumByteToWrite / SPI_FLASH_PageSize;
                        NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;
                  
                        SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);
                        WriteAddr +=  count;
                        pBuffer += count;  
                 
                        while(NumOfPage--)
                        {
                                SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);
                                WriteAddr +=  SPI_FLASH_PageSize;
                                pBuffer += SPI_FLASH_PageSize;
                        }
                  
                        if(NumOfSingle != 0)
                        {
                                SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);
                        }
                }
        }
}


//读取SPI FLASH  
void SPI_FLASH_StartReadSequence(u32 ReadAddr)
{                                                                     
         SPI_FLASH_CS=0;                            //使能器件   
   SPI_FLASH_SendByte(W25X_ReadData);         //发送读取命令   
   SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);  //发送24bit地址   
   SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
   SPI_FLASH_SendByte(ReadAddr & 0xFF);

}  


//读取一个字节

u8 SPI_FLASH_ReadByte(void)
{
  return (SPI_FLASH_SendByte(0x00));
}


//关掉SPI FLASH操作
void SPI_FLASH_ReadOff(void)
{
  SPI_FLASH_CS=1;
}

//读取数据块的FLASH
void SPI_FLASH_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)
{
  /* Select the FLASH: Chip Select low */
  SPI_FLASH_CS=0;

  /* Send "Read from Memory " instruction */
  SPI_FLASH_SendByte(W25X_FastReadData);

  /* Send ReadAddr high nibble address byte to read from */
  SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
  /* Send ReadAddr medium nibble address byte to read from */
  SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
  /* Send ReadAddr low nibble address byte to read from */
  SPI_FLASH_SendByte(ReadAddr & 0xFF);
  SPI_FLASH_SendByte(0x00);


  while(NumByteToRead--) /* while there is data to be read */
  {
    /* Read a byte from the FLASH */
    *pBuffer= SPI_FLASH_SendByte(0x00);
    /* Point to the next location where the byte read will be saved */
    pBuffer++;
  }

  /* Deselect the FLASH: Chip Select high */
  SPI_FLASH_CS=1;
}


//读取芯片ID
//返回值如下:                                  
//0XEF13,表示芯片型号为W25Q80  
//0XEF14,表示芯片型号为W25Q16   
//0XEF15,表示芯片型号为W25Q32  
//0XEF16,表示芯片型号为W25Q64             
u16 SPI_Flash_ReadID(void)
{
        u16 Temp = 0;          
        SPI_FLASH_CS=0;                                    
        SPI_FLASH_SendByte(0x90);//发送读取ID命令            
        SPI_FLASH_SendByte(0x00);             
        SPI_FLASH_SendByte(0x00);             
        SPI_FLASH_SendByte(0x00);                                    
        Temp|=SPI_FLASH_SendByte(0xFF)<<8;  
        Temp|=SPI_FLASH_SendByte(0xFF);         
        SPI_FLASH_CS=1;                                    
        return Temp;
}                       


//擦除整个芯片                  
//等待时间超长...
//W25X16:25s
//W25X32:40s
//W25X64:40s
void SPI_Flash_Erase_Chip(void)   
{   
  SPI_FLASH_CS=0;          
  SPI_FLASH_Write_Enable();         //SET WEL
  SPI_FLASH_CS=1;          
  SPI_Flash_Wait_Busy();   
  SPI_FLASH_CS=0;                            //使能器件   
  SPI_FLASH_SendByte(W25X_ChipErase);        //发送片擦除命令  
        SPI_FLASH_CS=1;                            //取消片选                  
        SPI_Flash_Wait_Busy();                                      //等待芯片擦除结束
}   

//等待空闲
void SPI_Flash_Wait_Busy(void)   
{   
        while((SPI_Flash_ReadSR()&0x01)==0x01);   // 等待BUSY位清空
}  
//进入掉电模式
void SPI_Flash_PowerDown(void)   
{
          SPI_FLASH_CS=0;                            //使能器件   
    SPI_FLASH_SendByte(W25X_PowerDown);        //发送掉电命令  
          SPI_FLASH_CS=1;                            //取消片选                  
    delay_us(3);                               //等待TPD  
}   
//唤醒
void SPI_Flash_WAKEUP(void)   
{  
  SPI_FLASH_CS=0;                            //使能器件   
  SPI_FLASH_SendByte(W25X_ReleasePowerDown);   //  send W25X_PowerDown command 0xAB   
        SPI_FLASH_CS=1;                            //取消片选                  
  delay_us(3);                               //等待TRES1
}   



#define K1        GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13)

/*要写入到W25Q32的字符串数组*/
const u8 TEXT_Buffer[]={0x00,0x01,0x02};
#define SIZE sizeof(TEXT_Buffer)
       
/*************主函数**************************/
int main(void)
{

        u8 i;
  u8 flag=0;
        u8 datatemp[SIZE];
  delay_init(24);
        RCC_Configuration();
        PortInit();
        USART_Configuration();
        NVIC_Configuration();
  ADC_DMA_init();
        SPI_Flash_Init();                  //SPI FLASH 初始化        
  while(1)
        {       


           if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13)==0)
                 {
                         delay_ms(200);
                         if(K1 ==0)
                         {
                                 SPI_Flash_Erase_Chip();
                                 printf(" 开始写入W25Q32 SPI FLASH芯片....");
                           SPI_FLASH_BufferWrite((u8*)TEXT_Buffer,100,SIZE);//从100字节处开始写
                           printf(" 写入完成!");//提示传送完成
                                 flag=1;
                         }
                 }
                       
                 
                if(flag)
     {
                          printf(" 开始从W25Q32 SPI FLASH芯片读取数据.... ");
                          SPI_FLASH_BufferRead(datatemp,100,SIZE);//从100地址处开始读
                          printf(" 读取完成,读出的数据为: %s  ", datatemp);//提示传送完成
                         flag=0;
                 }
                 i++;
                delay_ms(20);
                if(i==20)
                {
                //提示系统正在运行
                        GPIO_SetBits(GPIOB, GPIO_Pin_2);
                  delay_ms(200);
                        GPIO_ResetBits(GPIOB, GPIO_Pin_2);;
                        i=0;
                }                  
       


        }
          

}





友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。