#include "includes.h"
/*
W25Q64
8M×Ö½Ú
128¿é
ÿ¿éÊÇ64K
ÿ¿éÓÖÓÐ16¸öÉÈÇø
ÿ¸öÉÈÇø4k
ÿ¸öÉÈÇø·ÖΪ16Ò³
1Ò³ÊÇ256¸ö×Ö½Ú
8M = 128*64K= 2048*4K = 2048*16*256byte
¿é ÉÈÇø Ò³
*/
/*
1.GPIO¿Ú³õʼ»¯
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
2.STM32 SPI¿ØÖÆÆ÷³õʼ»¯
void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct);
*/
void FLASH_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
//MOSI -- PB15 SCK -- PB13
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15 | GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
//CS
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
//MISO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB,&GPIO_InitStructure);
//SPIÐÒéµÄ³õʼ»¯
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_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2,&SPI_InitStructure);
SPI_Cmd(SPI2,ENABLE);
}
/*
ͨ¹ýSPI·¢ËÍÊý¾Ý
void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data);
ͨ¹ýSPI½ÓÊÜÊý¾Ý
uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx);
ÅжϷ¢ËͼĴæÆ÷ÊÇ·ñ·¢Ëͳɹ¦
FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
1.µÈ´ý·¢ËÍÇøΪ¿Õ
2.
*/
u8 SPI2_Send_Receive_Byte(u8 data)
{
while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI2,data);
while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE) == RESET);
return SPI_I2S_ReceiveData(SPI2);
}
//дʹÄÜ
void FLASH_WriteEnable(void)
{
/*!< Select the FLASH: Chip Select low */
FLASH_CS_LOW();
/*!< Send "Write Enable" instruction */
SPI2_Send_Receive_Byte(CMD_WRITE_ENABLE);
/*!< Deselect the FLASH: Chip Select high */
FLASH_CS_HIGH();
}
//ÅжÏFLASHÊÇ·ñBUSY
void FLASH_WaitForWriteEnd(void)
{
uint8_t flashstatus = 0;
/*!< Select the FLASH: Chip Select low */
FLASH_CS_LOW();
/*!< Send "Read Status Register" instruction */
SPI2_Send_Receive_Byte(CMD_READ_REGISTER1);
/*!< Loop as long as the memory is busy with a write cycle */
do
{
/*!< Send a dummy byte to generate the clock needed by the FLASH
and put the value of the status register in FLASH_Status variable */
flashstatus = SPI2_Send_Receive_Byte(FLASH_DUMMY_BYTE);
}
while ((flashstatus & 0x01) == SET); /* Write in progress */
/*!< Deselect the FLASH: Chip Select high */
FLASH_CS_HIGH();
}
/*
ÍùFLASHÖÐдÊý¾Ý£¨Ð´Ò»´ÎµÄÊý¾Ý´óСΪСÓÚ256£©
1.ÅжÏFLASHÊÇ·ñ´¦ÓÚæ״̬ 1 æ 0 ²»Ã¦
2.дʹÄÜ
3.ƬѡCSÀµÍ
4.·¢ËÍдÃüÁî
5.·¢ËÍ24λµØÖ·
6.ÍùSPIÖÐдСÓÚ4K³¤¶ÈµÄÊý¾Ý
7.CSÀ¸ß
8.ÅжÏFLASH״̬ÊÇ·ñæ
*/
void FLASH_WritePage(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
/*!< Enable the write access to the FLASH */
FLASH_WriteEnable();
/*!< Select the FLASH: Chip Select low */
FLASH_CS_LOW();
/*!< Send "Write to Memory " instruction */
SPI2_Send_Receive_Byte(CMD_PAGE_PROGRAM);
/*!< Send WriteAddr high nibble address byte to write to */
SPI2_Send_Receive_Byte((WriteAddr & 0xFF0000) >> 16);
/*!< Send WriteAddr medium nibble address byte to write to */
SPI2_Send_Receive_Byte((WriteAddr & 0xFF00) >> 8);
/*!< Send WriteAddr low nibble address byte to write to */
SPI2_Send_Receive_Byte(WriteAddr & 0xFF);
/*!< while there is data to be written on the FLASH */
while (NumByteToWrite--)
{
/*!< Send the current byte */
SPI2_Send_Receive_Byte(*pBuffer);
/*!< Point on the next byte to be written */
pBuffer++;
}
/*!< Deselect the FLASH: Chip Select high */
FLASH_CS_HIGH();
/*!< Wait the end of Flash writing */
FLASH_WaitForWriteEnd();
}
//ÏòFLASHÖз¢ËÍbufferµÄÊý¾Ý
void FLASH_WriteBuffer(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0;
Addr = WriteAddr % FLASH_SPI_PAGESIZE;//´ú±í´ÓÒ»Ò³ÖÐÄĸöµØÖ·¿ªÊ¼Ð´Êý¾Ý
count = FLASH_SPI_PAGESIZE - Addr;//´ú±í¸ÃÒ³»¹¿ÉÒÔд¶àÉÙÊý¾Ý
NumOfPage = NumByteToWrite / FLASH_SPI_PAGESIZE;//´ú±íÒª´æÈëµÄÊý¾Ý³¤¶È¿ÉÒÔд¶àÉÙÒ³
NumOfSingle = NumByteToWrite % FLASH_SPI_PAGESIZE;//´ú±í³ýÁËÕûÒ³Êý¾ÝÍ⣬»¹¿ÉÒÔдµÄÊý¾Ý³¤¶È
if (Addr == 0) /*!< WriteAddr is sFLASH_PAGESIZE aligned */
{
if (NumOfPage == 0) /*!< NumByteToWrite < sFLASH_PAGESIZE */
{
FLASH_WritePage(pBuffer, WriteAddr, NumByteToWrite);
}
else /*!< NumByteToWrite > sFLASH_PAGESIZE */
{
while(NumOfPage--)
{
FLASH_WritePage(pBuffer, WriteAddr, FLASH_SPI_PAGESIZE);
WriteAddr += FLASH_SPI_PAGESIZE;
pBuffer += FLASH_SPI_PAGESIZE;
}
FLASH_WritePage(pBuffer, WriteAddr, NumOfSingle);
}
}
else /*!< WriteAddr is not sFLASH_PAGESIZE aligned */
{
if (NumOfPage == 0) /*!< NumByteToWrite < sFLASH_PAGESIZE */
{
if (NumOfSingle > count) /*!< (NumByteToWrite + WriteAddr) > sFLASH_PAGESIZE */
{
temp = NumOfSingle - count;
FLASH_WritePage(pBuffer, WriteAddr, count);
WriteAddr += count;
pBuffer += count;
FLASH_WritePage(pBuffer, WriteAddr, temp);
}
else
{
FLASH_WritePage(pBuffer, WriteAddr, NumByteToWrite);
}
}
else /*!< NumByteToWrite > sFLASH_PAGESIZE */
{
NumByteToWrite -= count;
NumOfPage = NumByteToWrite / FLASH_SPI_PAGESIZE;
NumOfSingle = NumByteToWrite % FLASH_SPI_PAGESIZE;
FLASH_WritePage(pBuffer, WriteAddr, count);
WriteAddr += count;
pBuffer += count;
while (NumOfPage--)
{
FLASH_WritePage(pBuffer, WriteAddr, FLASH_SPI_PAGESIZE);
WriteAddr += FLASH_SPI_PAGESIZE;
pBuffer += FLASH_SPI_PAGESIZE;
}
if (NumOfSingle != 0)
{
FLASH_WritePage(pBuffer, WriteAddr, NumOfSingle);
}
}
}
}
//´ÓFLASHÖжÁÊý¾Ý
void FLASH_ReadBuffer(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)
{
/*!< Select the FLASH: Chip Select low */
FLASH_CS_LOW();
/*!< Send "Read from Memory " instruction */
SPI2_Send_Receive_Byte(CMD_READ_DATA);
/*!< Send ReadAddr high nibble address byte to read from */
SPI2_Send_Receive_Byte((ReadAddr & 0xFF0000) >> 16);
/*!< Send ReadAddr medium nibble address byte to read from */
SPI2_Send_Receive_Byte((ReadAddr& 0xFF00) >> 8);
/*!< Send ReadAddr low nibble address byte to read from */
SPI2_Send_Receive_Byte(ReadAddr & 0xFF);
while (NumByteToRead--) /*!< while there is data to be read */
{
/*!< Read a byte from the FLASH */
*pBuffer = SPI2_Send_Receive_Byte(FLASH_DUMMY_BYTE);
/*!< Point to the next location where the byte read will be saved */
pBuffer++;
}
/*!< Deselect the FLASH: Chip Select high */
FLASH_CS_HIGH();
}
//¶ÁID
uint32_t FLASH_ReadID(void)
{
uint32_t Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;
/*!< Select the FLASH: Chip Select low */
FLASH_CS_LOW();
/*!< Send "RDID " instruction */
SPI2_Send_Receive_Byte(CMD_READ_ID);
/*!< Read a byte from the FLASH */
Temp0 = SPI2_Send_Receive_Byte(FLASH_DUMMY_BYTE);
/*!< Read a byte from the FLASH */
Temp1 = SPI2_Send_Receive_Byte(FLASH_DUMMY_BYTE);
/*!< Read a byte from the FLASH */
Temp2 = SPI2_Send_Receive_Byte(FLASH_DUMMY_BYTE);
/*!< Deselect the FLASH: Chip Select high */
FLASH_CS_HIGH();
Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;
return Temp;
}
//ÉÈÇø²Á³ý
void FLASH_EraseSector(uint32_t SectorAddr)
{
/*!< Send write enable instruction */
FLASH_WriteEnable();
/*!< Sector Erase */
/*!< Select the FLASH: Chip Select low */
FLASH_CS_LOW();
/*!< Send Sector Erase instruction */
SPI2_Send_Receive_Byte(CMD_SECTOR_ERASE);
/*!< Send SectorAddr high nibble address byte */
SPI2_Send_Receive_Byte((SectorAddr & 0xFF0000) >> 16);
/*!< Send SectorAddr medium nibble address byte */
SPI2_Send_Receive_Byte((SectorAddr & 0xFF00) >> 8);
/*!< Send SectorAddr low nibble address byte */
SPI2_Send_Receive_Byte(SectorAddr & 0xFF);
/*!< Deselect the FLASH: Chip Select high */
FLASH_CS_HIGH();
/*!< Wait the end of Flash writing */
FLASH_WaitForWriteEnd();
}
u8 flash_buffer[256] = "i love you my girl -- hl\n\r";
void Test_Flash(void)
{
u32 i;
u32 flash_ID;
u8 flash_flag = 0;
// DMA_Start(26);
do
{
if(flash_flag)
{
printf("¶ÁÈ¡µ½µÄID²»ÕýÈ·!\n\r");
Delay_ms(500);
}
flash_ID = FLASH_ReadID();
printf("%x\n\r",flash_ID);
flash_flag = 1;
}while(flash_ID != FLASH_W25Q64_ID);
FLASH_EraseSector(0x645000);
// DMA_Start(26);
for(i=0;i<256;i++)
{
flash_buffer[i] = i;
}
printf("¿ªÊ¼Ð´FLASH\n\r");
printf("ÕýÔÚд¡¡\n\r");
FLASH_WritePage(flash_buffer,0x645500,256);
printf("д³É¹¦£¡\n\r");
Clear_buffer(flash_buffer);
printf("¿ªÊ¼¶ÁFLASH\n\r");
printf("ÕýÔÚ¶Á¡¡\n\r");
FLASH_ReadBuffer(flash_buffer,0x645505,10);
printf("¶Á³É¹¦\n\r");
Display_buffer(flash_buffer);
// DMA_Start(256);
}
void Clear_buffer(u8 *buffer)
{
u32 i = 0;
for(i=0;i<256;i++)
{
buffer[i] = 0;
}
}
void Display_buffer(u8 *buffer)
{
u32 i,j;
for(i=0;i<16;i++)
{
for(j=0;j<16;j++)
{
printf("%x\t",*buffer++);
}
printf("\n\r");
}
}