版主好,我的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); } |
|