打印

Str750的SSP读写SPI flash不成功

[复制链接]
4756|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jlong12|  楼主 | 2007-7-16 09:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
版主好,我的Keil+ulink和750的开发板,想调试一下读写spi flash,但始终调不通,代码如下,您看我的代码是否有问题!谢谢!
/*
*******************************************************************************
常量定义
*******************************************************************************
*/
#define SPI_FLASH_PageSize 256

#define WRITE      0x02  /* Write to Memory instruction */
#define WRSR       0x01  /* Write Status Register instruction */ 
#define WREN       0x06  /* Write enable instruction */

#define READ       0x03  /* Read from Memory instruction */
#define RDSR       0x05  /* Read Status Register instruction  */
#define RDID       0x9F  /* Read identification */
#define SE         0xD8  /* Sector Erase instruction */
#define BE         0xC7  /* Bulk Erase instruction */

#define WIP_Flag   0x01  /* Write In Progress (WIP) flag */

#define Dummy_Byte 0xA5

#define Low        0x00  /* ChipSelect line low */
#define High       0x01  /* ChipSelect line high */

/*
*******************************************************************************
* 类型定义
*******************************************************************************
*/

/*
*******************************************************************************
* 变量定义
*******************************************************************************
*/

/*
*******************************************************************************
* 函数原型定义
*******************************************************************************
*/

/*******************************************************************************
* Function Name  : SPI_EE_ChipSelect
* Description    : Selects or deselects the EEPROM.
* Input          : State : level to be applied on the EEPROM's ChipSelect pin.
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_FLASH_ChipSelect(u8 State)
{
  /* Set High or low the chip select line on P04 pin */
  GPIO_WriteBit(GPIO0, GPIO_Pin_4, (BitAction)State);
}


/*******************************************************************************
* Function Name  : SPI_FLASH_Init
* Description    : Initializes the peripherals used by the SPI FLASH driver.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_FLASH_Init(void)
{
  SSP_InitTypeDef  SSP_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
   
  /* SSP0 pins configuration */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 ; 
  GPIO_Init(GPIO0, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; 
  GPIO_Init(GPIO0, &GPIO_InitStructure);

  SPI_FLASH_ChipSelect(High);
  /* SSP0 configuration */ 
  SSP_InitStructure.SSP_FrameFormat = SSP_FrameFormat_Motorola;
  SSP_InitStructure.SSP_Mode = SSP_Mode_Master;
  SSP_InitStructure.SSP_CPOL = SSP_CPOL_High;
  SSP_InitStructure.SSP_CPHA = SSP_CPHA_2Edge;
  SSP_InitStructure.SSP_DataSize = SSP_DataSize_8b;
  SSP_InitStructure.SSP_NSS = SSP_NSS_Soft;
  SSP_InitStructure.SSP_ClockRate = 2;
  SSP_InitStructure.SSP_ClockPrescaler = 2; /* SSP baud rate : PCLK/2*(2+1) */
  SSP_Init(SSP0, &SSP_InitStructure);
  /* SSP0 enable */
  SSP_Cmd(SSP0, ENABLE);  
}


/*******************************************************************************
* Function Name  : SPI_FLASH_SectorErase
* Description    : Erases the specified FLASH sector.
* Input          : SectorAddr: address of the sector to erase.
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_FLASH_SectorErase(u32 SectorAddr)
{
  /* Send write enable instruction */
  SPI_FLASH_WriteEnable();

  /* Sector Erase */ 
  /* Select the FLASH: Chip Select low */
  SPI_FLASH_ChipSelect(Low);       
  /* Send Sector Erase instruction */
  SPI_FLASH_SendByte(SE);
  /* 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);
  /* Deselect the FLASH: Chip Select high */
  SPI_FLASH_ChipSelect(High);

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


/*******************************************************************************
* Function Name  : SPI_FLASH_BulkErase
* Description    : Erases the entire FLASH.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_FLASH_BulkErase(void)
{
  /* Send write enable instruction */
  SPI_FLASH_WriteEnable();

  /* Bulk Erase */ 
  /* Select the FLASH: Chip Select low */
  SPI_FLASH_ChipSelect(Low);       
  /* Send Bulk Erase instruction  */
  SPI_FLASH_SendByte(BE);
  /* Deselect the FLASH: Chip Select high */
  SPI_FLASH_ChipSelect(High);

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


/*******************************************************************************
* Function Name  : SPI_EE_PageWrite
* Description    : Writes more than one byte to the EEPROM with a single WRITE
*                  cycle(Page WRITE sequence). The number of byte can't exceed
*                  the EEPROM page size.
* Input          : - pBuffer : pointer to the buffer  containing the data to be 
*                    written to the EEPROM.
*                  - WriteAddr : EEPROM's internal address to write to.
*                  - NumByteToWrite : number of bytes to write to the EEPROM,
*                    must be equal or less than "SPI_EE_PageSize" value. 
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_FLASH_PageWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
{
  /* Enable the write access to the EEPROM */
  SPI_FLASH_WriteEnable();        
  
  /* Select the EEPROM: Chip Select low */
  SPI_FLASH_ChipSelect(Low);       
  /* Send "Write to Memory " instruction */    
  SPI_FLASH_SendByte(WRITE);    
  
  /* 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 EEPROM */
  while(NumByteToWrite--) 
  {
    /* Send the current byte */            
    SPI_FLASH_SendByte(*pBuffer);                
    
    /* Point on the next byte to be written */
    pBuffer++; 
  }        
  
  /* Deselect the EEPROM: Chip Select high */
  SPI_FLASH_ChipSelect(High);
  
  /* Wait the end of EEPROM writing */
  SPI_FLASH_WaitForWriteEnd();    
}

/*******************************************************************************
* Function Name  : SPI_EE_BufferWrite
* Description    : Writes block of data to the EEPROM. 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 EEPROM.
*                  - WriteAddr : EEPROM's internal address to write to.
*                  - NumByteToWrite : number of bytes to write to the EEPROM.
* 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_EE_PageSize aligned  */
  {
    if(NumOfPage == 0) /* NumByteToWrite < SPI_EE_PageSize */
    {
      SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
    }
    else /* NumByteToWrite > SPI_EE_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_EE_PageSize aligned  */
  {
    if(NumOfPage== 0) /* NumByteToWrite < SPI_EE_PageSize */
    {
      if(NumOfSingle > count) /* (NumByteToWrite + WriteAddr) > SPI_EE_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_EE_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);
      }
    }
  }          
}

/*******************************************************************************
* Function Name  : SPI_EE_BufferRead
* Description    : Reads a block of data from the EEPROM.
* Input          : - pBuffer : pointer to the buffer that receives the data read 
*                    from the EEPROM.
*                  - ReadAddr : EEPROM's internal address to read from.
*                  - NumByteToRead : number of bytes to read from the EEPROM.
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_FLASH_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)
{
  /* Select the EEPROM: Chip Select low */
  SPI_FLASH_ChipSelect(Low);       
  
  /* Send "Read from Memory " instruction */
  SPI_FLASH_SendByte(READ);     
  
  /* 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);

  while(NumByteToRead--) /* while there is data to be read */
  {
    /* Read a byte from the EEPROM */            
    *pBuffer = SPI_FLASH_SendByte(Dummy_Byte);
   
    /* Point to the next location where the byte read will be saved */
    pBuffer++;
  }    
  
  /* Deselect the EEPROM: Chip Select high */
  SPI_FLASH_ChipSelect(High);        
}

/*******************************************************************************
* Function Name  : SPI_FLASH_ReadID
* Description    : Reads FLASH identification.
* Input          : None
* Output         : None
* Return         : FLASH identification
*******************************************************************************/
u32 SPI_FLASH_ReadID(void)
{
  u32 Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;

  /* Select the FLASH: Chip Select low */
  SPI_FLASH_ChipSelect(Low);       
  
  /* Send "RDID " instruction */
  SPI_FLASH_SendByte(0x9F);

  /* Read a byte from the FLASH */
  Temp0 = SPI_FLASH_SendByte(Dummy_Byte);

  /* Read a byte from the FLASH */
  Temp1 = SPI_FLASH_SendByte(Dummy_Byte);

  /* Read a byte from the FLASH */
  Temp2 = SPI_FLASH_SendByte(Dummy_Byte);

  /* Deselect the FLASH: Chip Select high */
  SPI_FLASH_ChipSelect(High);        
         
  Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;

  return Temp;
}

/*******************************************************************************
* Function Name  : SPI_FLASH_ReadByte
* Description    : Reads a byte from the SPI Flash.
*                  This function must be used only if the Start_Read_Sequence
*                  function has been previously called.
* Input          : None
* Output         : None
* Return         : Byte Read from the SPI Flash.
*******************************************************************************/
u8 SPI_FLASH_ReadByte(void)
{
  return (SPI_FLASH_SendByte(Dummy_Byte));
}


/*******************************************************************************
* Function Name  : SPI_EE_SendByte
* Description    : Sends a byte through the SSP interface and return the  byte 
*                  received from the SPI bus.
* Input          : byte : byte to send.
* Output         : None
* Return         : The value of the received byte.
*******************************************************************************/
u8 SPI_FLASH_SendByte(u8 byte)
{
  /* Send byte through the SSP0 peripheral */    
  SSP_SendData(SSP0, byte);    
  
  /* Loop while Transmit FIFO is full */
  while(SSP_GetFlagStatus(SSP0, SSP_FLAG_TxFifoEmpty) == RESET);   
  
  /* Loop while Receive FIFO is empty */
  while(SSP_GetFlagStatus(SSP0, SSP_FLAG_RxFifoNotEmpty) == RESET);    
  
  /* Return the byte read from the SPI bus */
  return SSP_ReceiveData(SSP0);       
}

/*******************************************************************************
* Function Name  : SPI_EE_WriteEnable
* Description    : Enables the write access to the EEPROM.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_FLASH_WriteEnable(void)  
{
  /* Select the EEPROM: Chip Select low */
  SPI_FLASH_ChipSelect(Low);    
  
  /* Send "Write Enable" instruction */
  SPI_FLASH_SendByte(WREN);
  
  /* Deselect the EEPROM: Chip Select high */
  SPI_FLASH_ChipSelect(High);    
}

/*******************************************************************************
* Function Name  : SPI_EE_WaitForWriteEnd
* Description    : Polls the status of the Write In Progress (WIP) flag in the  
*                  EEPROM's status  register  and  loop  until write  opertaion
*                  has completed.  
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_FLASH_WaitForWriteEnd(void) 
{
  u8 EE_Status = 0;
  
  /* Select the EEPROM: Chip Select low */
  SPI_FLASH_ChipSelect(Low);
      
  /* Send "Read Status Register" instruction */
  SPI_FLASH_SendByte(RDSR);
  
  /* Loop as long as the memory is busy with a write cycle */         
  do
  {     
    /* Send a dummy byte to generate the clock needed by the EEPROM 
    and put the value of the status register in EE_Status variable */
    EE_Status = SPI_FLASH_SendByte(Dummy_Byte);  
                                                            
  } while((EE_Status & WIP_Flag) == SET); /* Write in progress */  

  /* Deselect the EEPROM: Chip Select high */
  SPI_FLASH_ChipSelect(High);         
}
沙发
jlong12|  楼主 | 2007-7-16 12:54 | 只看该作者

顶一下,别沉下去了

顶一下,别沉下去了,有高手的话快点帮帮忙啊!

使用特权

评论回复
板凳
grant_jx| | 2007-7-16 18:03 | 只看该作者

也不描述一下,这么一大段代码,谁那么有空啊

问题要描述清楚,到底问题出在哪?不会你连这个都不清楚吧。总不能你随便找个例子,读不到数据就说有问题,有什么问题呢?别人没有你的环境,想回答也只能是猜,那还不如不回答。想问问题也没点技巧,唉!

刚才又看了一下,发现连要读取的Flash型号都没有,猜谜啊?

使用特权

评论回复
地板
jlong12|  楼主 | 2007-7-17 09:21 | 只看该作者

你这是什么态度?

或许是我真的没描述清楚!但作为技术人员,请你给别人最起码的尊重!我开始就说了,是str750的开发板,只是没说是英蓓得提供的,我也告诉你是用Keil+ulink的开发环境,我贴这么一段代码是想让你们看得全一点,稍微有点常识的人就知道看代码只要看看关键点就行了,看来你连分析代码的基本常识都没有,而且极度没有耐心和没有责任感,我不知道ST怎么会让你这种人到这里来瞎忽悠!

市面上所有的SPI flash的操作方式都是一样的,你要求我告诉你型号干嘛!就算我告诉你我用的是m25p80你又能做什么????无知的跳梁小丑,最好滚出这个论坛,别在这里丢人现眼!

使用特权

评论回复
5
grant_jx| | 2007-7-17 09:45 | 只看该作者

就你这个态度,谁敢回答你啊?

顺便告诉你,我不是ST的,你用不着那么激动。三个版主里面只有一个是ST的。帖子放在这里,有人看,看看到底是谁态度差?谁在这里是瞎忽悠。林子大了真是什么鸟都有。叫你把问题描述清楚点,你还有气了?

使用特权

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

本版积分规则

4

主题

7

帖子

1

粉丝