学前班
最后登录1970-1-1
在线时间 小时
注册时间2017-6-9
|
楼主 |
发表于 2017-6-9 11:36:31
|
显示全部楼层
驱动 如下:
/**
******************************************************************************
* @file bsp_xxx.c
* @author STMicroelectronics
* @version V1.0
* @date 2013-xx-xx
* @brief spi flash μ×2ãó|óÃoˉêybsp
******************************************************************************
* @attention
*
* êμÑéƽì¨:ò°»e iSO STM32 ¿a·¢°å
* ÂÛì3 :http://www.chuxue123.com
* ìÔ±| :http://firestm32.taobao.com
*
******************************************************************************
*/
#include "bsp_spi_flash.h"
#include <string.h>
#include <stdio.h>
u8 SPI_Flash_SR(void){
u8 byte=0;
SPI_FLASH_CS_LOW();
SPI_FLASH_SendByte(W25X_ReadStatusReg);
byte=SPI_FLASH_SendByte(0Xff);
SPI_FLASH_CS_HIGH();
return byte;
}
// ′íÎó′òó¡
void eerping(char * errsr){
int Num=0;
FlagStatus dexian; //êÇ·ñμÃÏD·¢£¡
while (Num<strlen(errsr)+1){
dexian= USART_GetFlagStatus(USART1, USART_FLAG_TC);
if( dexian != RESET){
USART_SendData(USART1,errsr[Num]);
Num++;
}
}
}
/**
* @brief SPI_FLASH3õê¼»ˉ
* @param ÎT
* @retval ÎT
*/
void SPI_FLASH_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* ê1ÄüSPIê±Öó */
SPI_APBxClock_FUN ( SPI_CLK, ENABLE );
/* ÅäÖÃSPIμÄ CSòy½Å£¬ÆÕí¨IO¼′¿é */
SPI_CS_APBxClock_FUN ( SPI_CS_CLK, ENABLE );
GPIO_InitStructure.GPIO_Pin = SPI_CS_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(SPI_CS_PORT, &GPIO_InitStructure);
/* ÅäÖÃSPIμÄ SCKòy½Å*/
SPI_SCK_APBxClock_FUN ( SPI_SCK_CLK, ENABLE );
GPIO_InitStructure.GPIO_Pin = SPI_SCK_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(SPI_SCK_PORT, &GPIO_InitStructure);
/* ÅäÖÃSPIμÄ MISOòy½Å*/
SPI_MISO_APBxClock_FUN ( SPI_MISO_CLK, ENABLE );
GPIO_InitStructure.GPIO_Pin = SPI_MISO_PIN;
GPIO_Init(SPI_MISO_PORT, &GPIO_InitStructure);
/* ÅäÖÃSPIμÄ MOSIòy½Å*/
SPI_MOSI_APBxClock_FUN ( SPI_MOSI_CLK, ENABLE );
GPIO_InitStructure.GPIO_Pin = SPI_MOSI_PIN;
GPIO_Init(SPI_MOSI_PORT, &GPIO_InitStructure);
/* í£Ö1DÅoÅ FLASH: CSòy½Å¸ßμçƽ*/
SPI_FLASH_CS_HIGH();
/* SPI Ä£ê½ÅäÖà */
// FLASHD¾Æ¬ Ö§3ÖSPIÄ£ê½0¼°Ä£ê½3£¬¾Y′ËéèÖÃCPOL CPHA
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_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPIx , &SPI_InitStructure);
/* ê1Äü SPI */
SPI_Cmd(SPIx , ENABLE);
}
/**
* @brief 2á3yFLASHéèÇø
* @param SectorAddr£oòa2á3yμÄéèÇøμØÖ·
* @retval ÎT
*/
void SPI_FLASH_SectorErase(u32 SectorAddr)
{
/* ·¢ËíFLASHD′ê1ÄüÃüáî */
SPI_FLASH_WriteEnable();
SPI_FLASH_WaitForWriteEnd();
/* 2á3yéèÇø */
/* Ñ¡ÔñFLASH: CSμíμçƽ */
SPI_FLASH_CS_LOW();
/* ·¢ËíéèÇø2á3yÖ¸áî*/
SPI_FLASH_SendByte(W25X_SectorErase);
/*·¢Ëí2á3yéèÇøμØÖ·μĸßλ*/
SPI_FLASH_SendByte((u8)((SectorAddr & 0xFF0000) >> 16));
/* ·¢Ëí2á3yéèÇøμØÖ·μÄÖDλ */
SPI_FLASH_SendByte((u8)((SectorAddr & 0xFF00) >> 8));
/* ·¢Ëí2á3yéèÇøμØÖ·μÄμíλ */
SPI_FLASH_SendByte((u8)(SectorAddr & 0xFF));
/* í£Ö1DÅoÅ FLASH: CS ¸ßμçƽ */
SPI_FLASH_CS_HIGH();
/* μè′y2á3yíê±Ï*/
SPI_FLASH_WaitForWriteEnd();
}
/**
* @brief 2á3yFLASHéèÇø£¬ÕûƬ2á3y
* @param ÎT
* @retval ÎT
*/
void SPI_FLASH_BulkErase(void)
{
/* ·¢ËíFLASHD′ê1ÄüÃüáî */
SPI_FLASH_WriteEnable();
/* Õû¿é Erase */
/* Ñ¡ÔñFLASH: CSμíμçƽ */
SPI_FLASH_CS_LOW();
/* ·¢ËíÕû¿é2á3yÖ¸áî*/
SPI_FLASH_SendByte(W25X_ChipErase);
/* í£Ö1DÅoÅ FLASH: CS ¸ßμçƽ */
SPI_FLASH_CS_HIGH();
/* μè′y2á3yíê±Ï*/
SPI_FLASH_WaitForWriteEnd();
}
/**
* @brief ¶ÔFLASH°′ò3D′èëêy¾Y£¬μ÷óñ¾oˉêyD′èëêy¾YÇ°DèòaÏè2á3yéèÇø
* @param pBuffer£¬òaD′èëêy¾YμÄÖ¸Õë
* @param WriteAddr£¬D′èëμØÖ·
* @param NumByteToWrite£¬D′èëêy¾Y3¤¶è£¬±ØDëD¡óúμèóúSPI_FLASH_PerWritePageSize
* @retval ÎT
*/
void SPI_FLASH_PageWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
{
/* ·¢ËíFLASHD′ê1ÄüÃüáî */
SPI_FLASH_WriteEnable();
/* Ñ¡ÔñFLASH: CSμíμçƽ */
SPI_FLASH_CS_LOW();
/* D′ò3D′Ö¸áî*/
SPI_FLASH_SendByte(W25X_PageProgram);
/*·¢ËíD′μØÖ·μĸßλ*/
SPI_FLASH_SendByte((u8)((WriteAddr & 0xFF0000) >> 16));
/*·¢ËíD′μØÖ·μÄÖDλ*/
SPI_FLASH_SendByte((u8)((WriteAddr & 0xFF00) >> 8));
/*·¢ËíD′μØÖ·μÄμíλ*/
SPI_FLASH_SendByte((u8)(WriteAddr & 0xFF));
if(NumByteToWrite > SPI_FLASH_PerWritePageSize)
{
NumByteToWrite = SPI_FLASH_PerWritePageSize;
// FLASH_ERROR("SPI_FLASH_PageWrite too large!");
char * Pagestr ="SPI_FLASH_PageWrite too large!";
eerping(Pagestr);
}
/* D′èëêy¾Y*/
while (NumByteToWrite--)
{
/* ·¢Ëíμ±Ç°òaD′èëμÄ×Ö½úêy¾Y */
char xie=8;
xie=*pBuffer;
SPI_FLASH_SendByte(*pBuffer);
/* Ö¸ÏòÏÂò»×Ö½úêy¾Y */
pBuffer++;
}
/* í£Ö1DÅoÅ FLASH: CS ¸ßμçƽ */
SPI_FLASH_CS_HIGH();
/* μè′yD′èëíê±Ï*/
SPI_FLASH_WaitForWriteEnd();
}
/**
* @brief ¶ÔFLASHD′èëêy¾Y£¬μ÷óñ¾oˉêyD′èëêy¾YÇ°DèòaÏè2á3yéèÇø
* @param pBuffer£¬òaD′èëêy¾YμÄÖ¸Õë
* @param WriteAddr£¬D′èëμØÖ·
* @param NumByteToWrite£¬D′èëêy¾Y3¤¶è
* @retval ÎT
*/
void SPI_FLASH_BufferWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
{
u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0;
/*modÔËËãÇóó࣬èôwriteAddrêÇSPI_FLASH_PageSizeÕûêy±¶£¬ÔËËã½á1ûAddrÖμÎa0*/
Addr = WriteAddr % SPI_FLASH_PageSize;
/*2îcount¸öêy¾YÖ죬¸ÕoÿéòÔ¶ÔÆëμ½ò3μØÖ·*/
count = SPI_FLASH_PageSize - Addr;
/*¼ÆËã3öòaD′¶àéùÕûêyò3*/
NumOfPage = NumByteToWrite / SPI_FLASH_PageSize;
/*modÔËËãÇóó࣬¼ÆËã3öê£óà2»Âúò»ò3μÄ×Ö½úêy*/
NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;
/* Addr=0,ÔòWriteAddr ¸Õoð′ò3¶ÔÆë aligned */
if (Addr == 0)
{
/* NumByteToWrite < SPI_FLASH_PageSize */
if (NumOfPage == 0)
{
SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
}
else /* NumByteToWrite > SPI_FLASH_PageSize */
{
/*Ïè°ÑÕûêyò3¶¼D′áË*/
while (NumOfPage--)
{
SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);
WriteAddr += SPI_FLASH_PageSize;
pBuffer += SPI_FLASH_PageSize;
}
/*èôóD¶àóàμÄ2»Âúò»ò3μÄêy¾Y£¬°ÑËüD′íê*/
SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);
}
}
/* èôμØÖ·óë SPI_FLASH_PageSize 2»¶ÔÆë */
else
{
/* NumByteToWrite < SPI_FLASH_PageSize */
if (NumOfPage == 0)
{
/*μ±Ç°ò3ê£óàμÄcount¸öλÖñèNumOfSingleD¡£¬ò»ò3D′2»íê*/
if (NumOfSingle > count)
{
temp = NumOfSingle - count;
/*ÏèD′Âúμ±Ç°ò3*/
SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);
WriteAddr += count;
pBuffer += count;
/*ÔùD′ê£óàμÄêy¾Y*/
SPI_FLASH_PageWrite(pBuffer, WriteAddr, temp);
}
else /*μ±Ç°ò3ê£óàμÄcount¸öλÖÃÄüD′íêNumOfSingle¸öêy¾Y*/
{
SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
}
}
else /* NumByteToWrite > SPI_FLASH_PageSize */
{
/*μØÖ·2»¶ÔÆë¶à3öμÄcount·Ö¿a′|àí£¬2»¼óèëÕa¸öÔËËã*/
NumByteToWrite -= count;
NumOfPage = NumByteToWrite / SPI_FLASH_PageSize;
NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;
/* ÏèD′íêcount¸öêy¾Y£¬ÎaμÄêÇèÃÏÂò»′ÎòaD′μÄμØÖ·¶ÔÆë */
SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);
/* ½óÏÂà′¾íÖظ′μØÖ·¶ÔÆëμÄÇé¿ö */
WriteAddr += count;
pBuffer += count;
/*°ÑÕûêyò3¶¼D′áË*/
while (NumOfPage--)
{
SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);
WriteAddr += SPI_FLASH_PageSize;
pBuffer += SPI_FLASH_PageSize;
}
/*èôóD¶àóàμÄ2»Âúò»ò3μÄêy¾Y£¬°ÑËüD′íê*/
if (NumOfSingle != 0)
{
SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);
}
}
}
}
/**
* @brief ¶áè¡FLASHêy¾Y
* @param pBuffer£¬′æ′¢¶á3öêy¾YμÄÖ¸Õë
* @param ReadAddr£¬¶áè¡μØÖ·
* @param NumByteToRead£¬¶áè¡êy¾Y3¤¶è
* @retval ÎT
*/
void SPI_FLASH_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)
{
/* Ñ¡ÔñFLASH: CSμíμçƽ */
SPI_FLASH_CS_LOW();
/* ·¢Ëí ¶á Ö¸áî */
SPI_FLASH_SendByte(W25X_ReadData);
/* ·¢Ëí ¶á μØÖ·¸ßλ */
SPI_FLASH_SendByte((u8)((ReadAddr & 0xFF0000) >> 16));
/* ·¢Ëí ¶á μØÖ·ÖDλ */
SPI_FLASH_SendByte((u8)((ReadAddr& 0xFF00) >> 8));
/* ·¢Ëí ¶á μØÖ·μíλ */
SPI_FLASH_SendByte((u8)(ReadAddr & 0xFF));
/* ¶áè¡êy¾Y */
while (NumByteToRead--) /* while there is data to be read */
{
/* ¶áè¡ò»¸ö×Ö½ú*/
*pBuffer = SPI_FLASH_SendByte(0Xff);
/* Ö¸ÏòÏÂò»¸ö×Ö½ú»o3åÇø */
pBuffer++;
}
/* í£Ö1DÅoÅ FLASH: CS ¸ßμçƽ */
SPI_FLASH_CS_HIGH();
}
/**
* @brief ¶áè¡FLASH ID
* @param ÎT
* @retval FLASH ID
*/
u32 SPI_FLASH_ReadID(void)
{
u32 Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;
/* ¿aê¼í¨Ñ¶£oCSμíμçƽ */
SPI_FLASH_CS_LOW();
/* ·¢ËíJEDECÖ¸á¶áè¡ID */
SPI_FLASH_SendByte(W25X_JedecDeviceID);
/* ¶áè¡ò»¸ö×Ö½úêy¾Y */
Temp0 = SPI_FLASH_SendByte(Dummy_Byte);
/* ¶áè¡ò»¸ö×Ö½úêy¾Y */
Temp1 = SPI_FLASH_SendByte(Dummy_Byte);
/* ¶áè¡ò»¸ö×Ö½úêy¾Y */
Temp2 = SPI_FLASH_SendByte(Dummy_Byte);
/* í£Ö1í¨Ñ¶£oCS¸ßμçƽ */
SPI_FLASH_CS_HIGH();
/*°Ñêy¾Y×éoÏÆeà′£¬×÷ÎaoˉêyμÄ·μ»ØÖμ*/
Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;
return Temp;
}
/**
* @brief ¶áè¡FLASH Device ID
* @param ÎT
* @retval FLASH Device ID
*/
u32 SPI_FLASH_ReadDeviceID(void)
{
u32 Temp = 0;
/* Select the FLASH: Chip Select low */
SPI_FLASH_CS_LOW();
/* Send "RDID " instruction */
SPI_FLASH_SendByte(W25X_DeviceID);
SPI_FLASH_SendByte(Dummy_Byte);
SPI_FLASH_SendByte(Dummy_Byte);
SPI_FLASH_SendByte(Dummy_Byte);
/* Read a byte from the FLASH */
Temp = SPI_FLASH_SendByte(Dummy_Byte);
/* Deselect the FLASH: Chip Select high */
SPI_FLASH_CS_HIGH();
return Temp;
}
/*******************************************************************************
* Function Name : SPI_FLASH_StartReadSequence
* Description : Initiates a read data byte (READ) sequence from the Flash.
* This is done by driving the /CS line low to select the device,
* then the READ instruction is transmitted followed by 3 bytes
* address. This function exit and keep the /CS line low, so the
* Flash still being selected. With this technique the whole
* content of the Flash is read with a single READ instruction.
* Input : - ReadAddr : FLASH's internal address to read from.
* Output : None
* Return : None
*******************************************************************************/
void SPI_FLASH_StartReadSequence(u32 ReadAddr)
{
/* Select the FLASH: Chip Select low */
SPI_FLASH_CS_LOW();
/* Send "Read from Memory " instruction */
SPI_FLASH_SendByte(W25X_ReadData);
/* Send the 24-bit address of the address to read from -----------------------*/
/* Send ReadAddr high nibble address byte */
SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
/* Send ReadAddr medium nibble address byte */
SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
/* Send ReadAddr low nibble address byte */
SPI_FLASH_SendByte(ReadAddr & 0xFF);
}
/**
* @brief ê1óÃSPI¶áè¡ò»¸ö×Ö½úμÄêy¾Y
* @param ÎT
* @retval ·μ»Ø½óêÕμ½μÄêy¾Y
*/
u8 SPI_FLASH_ReadByte(void)
{
return (SPI_FLASH_SendByte(Dummy_Byte));
}
/**
* @brief ê1óÃSPI·¢Ëíò»¸ö×Ö½úμÄêy¾Y
* @param byte£oòa·¢ËíμÄêy¾Y
* @retval ·μ»Ø½óêÕμ½μÄêy¾Y
*/
u8 SPI_FLASH_SendByte(u8 byte)
{
/* μè′y·¢Ëí»o3åÇøÎa¿Õ£¬TXEê¼t */
while (SPI_I2S_GetFlagStatus(SPIx , SPI_I2S_FLAG_TXE) == RESET);
/* D′èëêy¾Y¼Ä′æÆ÷£¬°ÑòaD′èëμÄêy¾YD′èë·¢Ëí»o3åÇø */
SPI_I2S_SendData(SPIx , byte);
/* μè′y½óêÕ»o3åÇø·Ç¿Õ£¬RXNEê¼t */
while (SPI_I2S_GetFlagStatus(SPIx , SPI_I2S_FLAG_RXNE) == RESET);
/* ¶áè¡êy¾Y¼Ä′æÆ÷£¬»ñ衽óêÕ»o3åÇøêy¾Y */
return SPI_I2S_ReceiveData(SPIx );
}
/**
* @brief ê1óÃSPI·¢Ëíὸö×Ö½úμÄêy¾Y
* @param byte£oòa·¢ËíμÄêy¾Y
* @retval ·μ»Ø½óêÕμ½μÄêy¾Y
*/
u16 SPI_FLASH_SendHalfWord(u16 HalfWord)
{
/* μè′y·¢Ëí»o3åÇøÎa¿Õ£¬TXEê¼t */
while (SPI_I2S_GetFlagStatus(SPIx , SPI_I2S_FLAG_TXE) == RESET);
/* D′èëêy¾Y¼Ä′æÆ÷£¬°ÑòaD′èëμÄêy¾YD′èë·¢Ëí»o3åÇø */
SPI_I2S_SendData(SPIx , HalfWord);
/* μè′y½óêÕ»o3åÇø·Ç¿Õ£¬RXNEê¼t */
while (SPI_I2S_GetFlagStatus(SPIx , SPI_I2S_FLAG_RXNE) == RESET);
/* ¶áè¡êy¾Y¼Ä′æÆ÷£¬»ñ衽óêÕ»o3åÇøêy¾Y */
return SPI_I2S_ReceiveData(SPIx );
}
/**
* @brief ÏòFLASH·¢Ëí D′ê1Äü Ãüáî
* @param none
* @retval none
*/
void SPI_FLASH_WriteEnable(void)
{
/* í¨Ñ¶¿aê¼£oCSμí */
SPI_FLASH_CS_LOW();
/* ·¢ËíD′ê1ÄüÃüáî*/
SPI_FLASH_SendByte(W25X_WriteEnable);
/*í¨Ñ¶½áêø£oCS¸ß */
SPI_FLASH_CS_HIGH();
}
/* WIP(busy)±êÖ¾£¬FLASHÄú2¿ÕyÔúD′èë */
#define WIP_Flag 0x01
/**
* @brief μè′yWIP(BUSY)±êÖ¾±»ÖÃ0£¬¼′μè′yμ½FLASHÄú2¿êy¾YD′èëíê±Ï
* @param none
* @retval none
*/
void SPI_FLASH_WaitForWriteEnd(void)
{
u8 FLASH_Status = 0;
/* Ñ¡Ôñ FLASH: CS μí */
SPI_FLASH_CS_LOW();
/* ·¢Ëí ¶á×′쬼Ä′æÆ÷ Ãüáî */
SPI_FLASH_SendByte(W25X_ReadStatusReg);
/* èôFLASHÃ|Â죬Ôòμè′y */
do
{
/* ¶áè¡FLASHD¾Æ¬μÄ×′쬼Ä′æÆ÷ */
FLASH_Status = SPI_FLASH_SendByte(Dummy_Byte);
}
while ((FLASH_Status & WIP_Flag) == SET); /* ÕyÔúD′èë±êÖ¾ */
/* í£Ö1DÅoÅ FLASH: CS ¸ß */
SPI_FLASH_CS_HIGH();
}
//½øèëμôμçÄ£ê½
void SPI_Flash_PowerDown(void)
{
/* í¨Ñ¶¿aê¼£oCSμí */
SPI_FLASH_CS_LOW();
/* ·¢Ëí μôμç Ãüáî */
SPI_FLASH_SendByte(W25X_PowerDown);
/*í¨Ñ¶½áêø£oCS¸ß */
SPI_FLASH_CS_HIGH();
}
//»½DÑ
void SPI_Flash_WAKEUP(void)
{
/*Ñ¡Ôñ FLASH: CS μí */
SPI_FLASH_CS_LOW();
/* ·¢Ëí éÏμç Ãüáî */
SPI_FLASH_SendByte(W25X_ReleasePowerDown);
/* í£Ö1DÅoÅ FLASH: CS ¸ß */
SPI_FLASH_CS_HIGH();
}
/*********************************************END OF FILE**********************/
|
|