武林教你学PIC32(十七)SPI操作M25P16 FLASH存储器
扫描二维码
随时随地手机看文章
首先介绍下TI的M25P16,它是16Mbit(2Mbyte)的FLASH存储器,与常用的华邦公司的W25X16,ATMEL公司的AT51DB161比较接近。最高支持50M的SPI时钟,存储器可以以1到256字节byte,使用页编程操作将2M的容量分为32个块(Block),每个块含有256页,每页里有256字节宽带,因此整个存储器包含8192页或者2,097,152字节。操作命令为:
我们根据这些命令,做好下面封装函数:
//需要外接函数
extern unsigned char SPI_FLASH_SendByte(unsigned char ch);
extern unsigned char SPI_FLASH_ReadByte(unsigned char ch);
//高级函数
u32 SPI_FLASH_ReadID(void);//读取芯片ID正确发回0X202015
u8 SPI_FLASH_ByteRead(u32 ReadAddr);//读一个数据
void SPI_FLASH_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead);
void SPI_FLASH_PageWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite);//页写
void SPI_FLASH_BufferWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite);
void SPI_FLASH_SectorErase(u32 SectorAddr);//扇区擦除
void SPI_FLASH_BulkErase(void);//全部擦除
void SPI_Flash_PowerDown(void); //进入掉电模式
void SPI_Flash_WAKEUP(void);//唤醒
//底层函数
void SPI_FLASH_WriteEnable(void);
void SPI_FLASH_WriteDisable(void);
void SPI_FLASH_WaitForWriteEnd(void);
我们申请到的FLASH模块与SPI2连接,如图所示:
主函数里面实现这样的测试功能:首先测试芯片的型号,看是不是TI M25P16芯片,然后擦除扇区,再写入要测试的数据,最后读回来看是不是这些内容。
主函数代码:
#include "usart2.h"
#include "spi2.h"
#include "m25p16.h"
#include "led.h"
/* Private typedef -----------------------------------------------------------*/
typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
/* Private define ------------------------------------------------------------*/
#defineFLASH_WriteAddress0x00100
#defineFLASH_ReadAddressFLASH_WriteAddress
#defineFLASH_SectorToEraseFLASH_WriteAddress
#definesFLASH_ID0x202015
#defineBufferSize (countof(Tx_Buffer)-1)
/* Private macro -------------------------------------------------------------*/
#define countof(a) (sizeof(a) / sizeof(*(a)))
/* Private variables ---------------------------------------------------------*/
uint8_t Tx_Buffer[] = "nr欢迎访问EEFOUCS MIPS社区http://mips.eefocus.com/bbs/index_list.htmlrn SPI Flash Test Example: communication with an TI M25P16 SPI FLASHrn";
uint8_t Index, Rx_Buffer[BufferSize];
volatile TestStatus TransferStatus1 = FAILED, TransferStatus2 = PASSED;
uint32_t FlashID = 0;
/* Private function prototypes -----------------------------------------------*/
TestStatus Buffercmp(uint8_t *pBuffer1, uint8_t *pBuffer2, uint16_t BufferLength);
int main(void)
{
usart2_init(9600);
init_spi2();
LED_INIT();
/* Get SPI Flash Device ID */
FlashID = SPI_FLASH_ReadID();
printf("rn Device ID is 0x%X rn", FlashID);
if (FlashID == sFLASH_ID)
{
/* Turn on LED1 */
LED1_ON();//表明检测到FLASH芯片
printf("rn ST M25P16 Identitied!rn");
/* Perform a write in the Flash followed by a read of the written data */
/* Erase SPI FLASH Sector to write on */
SPI_FLASH_SectorErase(FLASH_SectorToErase);
printf("Tx_Buffer:%s", Tx_Buffer);
/* Write Tx_Buffer data to SPI FLASH memory */
SPI_FLASH_BufferWrite(Tx_Buffer, FLASH_WriteAddress, BufferSize);
/* Read data from SPI FLASH memory */
SPI_FLASH_BufferRead(Rx_Buffer, FLASH_ReadAddress, BufferSize);
printf("Rx_Buffer:%s", Rx_Buffer);
/* Check the corectness of written dada */
TransferStatus1 = Buffercmp(Tx_Buffer, Rx_Buffer, BufferSize);
/* Perform an erase in the Flash followed by a read of the written data */
/* Erase SPI FLASH Sector to write on */
SPI_FLASH_SectorErase(FLASH_SectorToErase);
/* Read data from SPI FLASH memory */
SPI_FLASH_BufferRead(Rx_Buffer, FLASH_ReadAddress, BufferSize);
/* Check the corectness of erasing operation dada */
for (Index = 0; Index < BufferSize; Index++)
{
if (Rx_Buffer[Index] != 0xFF)//因为擦除后都为0XFF
{
TransferStatus2 = FAILED;
break;
}
}
/* TransferStatus2 = PASSED, if the specified sector part is erased */
/* TransferStatus2 = FAILED, if the specified sector part is not well erased */
if((PASSED == TransferStatus1) && (PASSED == TransferStatus2))
{
/* OK: Turn on LED2 */
LED2_ON();
printf("rn M25P16 Test Suceed!nr");
}
else
{
LED4_ON();
printf("rn -->Failed: M25P16 Test Failed!nr");
}
}
else
{
/* Error: Turn on LED3 */
LED3_ON();
printf("rn M25P16 not detected!nr");
}
while(1);
}
TestStatus Buffercmp(uint8_t *pBuffer1, uint8_t *pBuffer2, uint16_t BufferLength)
{
while(BufferLength--)
{
if(*pBuffer1 != *pBuffer2)
{
return FAILED;
}
pBuffer1++;
pBuffer2++;
}
return PASSED;
}