来源:项目中需要用stm32对外部spi flash(m25p16 2MB)进行快速读取,主要是图像数据。
平台:stm32f407---168MHz,FreeRTOS V7.3.0
主要参考:http://blog.csdn.net/sinat_20598829/article/details/44408125
貌似发现了其中的一个小问题,未使用中断!!!见图
期间还参考帖子:http://blog.csdn.net/chenwei2002/article/details/49722373,本人不才,未能实现文中使用的方法。对于文中所讲:我们把SPI模式配置成只读模式,如上面程序中的样子,这个时候就可以直接读取数据,而不需要在发送无效数据0xff,大大提高了性能。SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_RxOnly; 然而在配置为只读模式后没有spi时钟驱动flash进行数据输出,故放弃此方法。
代码来源:st 官方spi flash驱动文件
(STM32F4xx_DSP_StdPeriph_Lib_V1.4.0ProjectSTM32F4xx_StdPeriph_ExamplesSPISPI_FLASH)
在官方文件的基础上进行修改(注意修改红色部分):
/**
******************************************************************************
*
* +-----------------------------------------------------------+
* | Pin assignment |
* +-----------------------------+---------------+-------------+
* | STM32 SPI Pins | sFLASH | Pin |
* +-----------------------------+---------------+-------------+
* | sFLASH_CS_PIN | ChipSelect(/S)| 1 |
* | sFLASh_SPI_MISO_PIN / MISO | DataOut(Q) | 2 |
* | | VCC | 3 (3.3 V)|
* | | GND | 4 (0 V) |
* | sFLASH_SPI_MOSI_PIN / MOSI | DataIn(D) | 5 |
* | sFLASH_SPI_SCK_PIN / SCK | Clock(C) | 6 |
* | | VCC | 7 (3.3 V)|
* | | VCC | 8 (3.3 V)|
* +-----------------------------+---------------+-------------+
******************************************************************************
* @attention
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "spi_dma_flash.h"
#include
/** @addtogroup STM32F4xx_StdPeriph_Examples
* @{
*/
/** @addtogroup SPI_FLASH
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define USE_SPI_DMA
#define SET_SPI1_ENABLE SPI_Cmd(sFLASH_DMA_SPI, ENABLE);
#define DMA2_TX_STREAM DMA2_Stream3
#define DMA2_TX_CHANNEL DMA_Channel_3
#define DMA2_RX_STREAM DMA2_Stream0
#define DMA2_RX_CHANNEL DMA_Channel_3
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static DMA_InitTypeDef DMA2_Tx_InitStructure;
static DMA_InitTypeDef DMA2_Rx_InitStructure;
/* Private function prototypes -----------------------------------------------*/
void sFLASH_DMA_LowLevel_DeInit(void);
void sFLASH_DMA_LowLevel_Init(void);
/* Private functions ---------------------------------------------------------*/
/**
* @brief DeInitializes the peripherals used by the SPI FLASH driver.
* @param None
* @retval None
*/
void sFLASH_DMA_DeInit(void)
{
sFLASH_DMA_LowLevel_DeInit();
}
/**
* @brief Initializes the peripherals used by the SPI FLASH driver.
* @param None
* @retval None
*/
void sFLASH_DMA_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
sFLASH_DMA_LowLevel_Init();
/*!< Deselect the FLASH: Chip Select high */
sFLASH_DMA_CS_HIGH();
/*!< SPI configuration */
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_2;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
DMA_Configuration_SPI1();
SPI_Init(sFLASH_DMA_SPI, &SPI_InitStructure);
SET_SPI1_ENABLE;
}
/**
* @brief Erases the specified FLASH sector.
* @param SectorAddr: address of the sector to erase.
* @retval None
*/
void sFLASH_DMA_EraseSector(uint32_t SectorAddr)
{
/*!< Send write enable instruction */
sFLASH_DMA_WriteEnable();
/*!< Sector Erase */
/*!< Select the FLASH: Chip Select low */
sFLASH_DMA_CS_LOW();
/*!< Send Sector Erase instruction */
sFLASH_DMA_SendByte(sFLASH_DMA_CMD_SE);
/*!< Send SectorAddr high nibble address byte */
sFLASH_DMA_SendByte((SectorAddr & 0xFF0000) >> 16);
/*!< Send SectorAddr medium nibble address byte */
sFLASH_DMA_SendByte((SectorAddr & 0xFF00) >> 8);
/*!< Send SectorAddr low nibble address byte */
sFLASH_DMA_SendByte(SectorAddr & 0xFF);
/*!< Deselect the FLASH: Chip Select high */
sFLASH_DMA_CS_HIGH();
/*!< Wait the end of Flash writing */
sFLASH_DMA_WaitForWriteEnd();
}
/**
* @brief Erases the entire FLASH.
* @param None
* @retval None
*/
void sFLASH_DMA_EraseBulk(void)
{
/*!< Send write enable instruction */
sFLASH_DMA_WriteEnable();
/*!< Bulk Erase */
/*!< Select the FLASH: Chip Select low */
sFLASH_DMA_CS_LOW();
/*!< Send Bulk Erase instruction */
sFLASH_DMA_SendByte(sFLASH_DMA_CMD_BE);
/*!< Deselect the FLASH: Chip Select high */
sFLASH_DMA_CS_HIGH();
/*!< Wait the end of Flash writing */
sFLASH_DMA_WaitForWriteEnd();
}
/**
* @brief Writes more than one byte to the FLASH with a single WRITE cycle
* (Page WRITE sequence).
* @note The number of byte can't exceed the FLASH page size.
* @param pBuffer: pointer to the buffer containing the data to be written
* to the FLASH.
* @param WriteAddr: FLASH's internal address to write to.
* @param NumByteToWrite: number of bytes to write to the FLASH, must be equal
* or less than "sFLASH_DMA_PAGESIZE" value.
* @retval None
*/
void sFLASH_DMA_WritePage(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
/*!< Enable the write access to the FLASH */
sFLASH_DMA_WriteEnable();
/*!< Select the FLASH: Chip Select low */
sFLASH_DMA_CS_LOW();
/*!< Send "Write to Memory " instruction */
sFLASH_DMA_SendByte(sFLASH_DMA_CMD_WRITE);
/*!< Send WriteAddr high nibble address byte to write to */
sFLASH_DMA_SendByte((WriteAddr & 0xFF0000) >> 16);
/*!< Send WriteAddr medium nibble address byte to write to */
sFLASH_DMA_SendByte((WriteAddr & 0xFF00) >> 8);
/*!< Send WriteAddr low nibble address byte to write to */
sFLASH_DMA_SendByte(WriteAddr & 0xFF);
/*!< while there is data to be written on the FLASH */
while (NumByteToWrite--)
{
/*!< Send the current byte */
sFLASH_DMA_SendByte(*pBuffer);
/*!< Point on the next byte to be written */
pBuffer++;
}
/*!< Deselect the FLASH: Chip Select high */
sFLASH_DMA_CS_HIGH();
/*!< Wait the end of Flash writing */
sFLASH_DMA_WaitForWriteEnd();
}
/**
* @brief Writes block of data to the FLASH. In this function, the number of
* WRITE cycles are reduced, using Page WRITE sequence.
* @param pBuffer: pointer to the buffer containing the data to be written
* to the FLASH.
* @param WriteAddr: FLASH's
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』