×
单片机 > 单片机程序设计 > 详情

武林教你学PIC32(十七)SPI操作M25P16 FLASH存储器

发布时间:2020-07-08 发布时间:
|

首先介绍下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 ------------------------------------------------------------*/

#define  FLASH_WriteAddress     0x00100

#define  FLASH_ReadAddress      FLASH_WriteAddress

#define  FLASH_SectorToErase    FLASH_WriteAddress

#define  sFLASH_ID       0x202015

 

#define  BufferSize (countof(Tx_Buffer)-1)

 

/* Private macro -------------------------------------------------------------*/

#define countof(a) (sizeof(a) / sizeof(*(a)))

/* Private variables ---------------------------------------------------------*/

uint8_t Tx_Buffer[] = "\n\r欢迎访问EEFOUCS MIPS社区 http://mips.eefocus.com/bbs/index_list.html\r\n SPI Flash Test Example: communication with an TI M25P16 SPI FLASH\r\n";

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("\r\n Device ID is 0x%X \r\n", FlashID);

      if (FlashID == sFLASH_ID)

       {

         /* Turn on LED1 */

         LED1_ON();//表明检测到FLASH芯片

      

         printf("\r\n ST M25P16 Identitied!\r\n");

      

         /* 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("\r\n M25P16 Test Suceed!\n\r");

         }

         else

         {

             LED4_ON();

             printf("\r\n -->Failed: M25P16 Test Failed!\n\r");

         }

       }

       else

       {

         /* Error: Turn on LED3 */

         LED3_ON();

         printf("\r\n M25P16 not detected!\n\r");

       }

       while(1);

}

TestStatus Buffercmp(uint8_t *pBuffer1, uint8_t *pBuffer2, uint16_t BufferLength)

{

  while(BufferLength--)

  {

    if(*pBuffer1 != *pBuffer2)

    {

      return FAILED;

    }

 

    pBuffer1++;

    pBuffer2++;

  }

 

  return PASSED;

}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机中高阻态的实质及意义