spi2 dma读取flash stm32f407

源代码
SPI.C

#include “spi.h”
#include <stdbool.h>
static volatile int g_rx_flag = 0;
static volatile int g_tx_flag = 0;
static void spi_chip_select(bool select)
{
//spi_do_delay(5);
if (select == true)
{
GPIOB->BSRRH = GPIO_Pin_12;
}
else
{
GPIOB->BSRRL = GPIO_Pin_12;
}
//spi_do_delay(5);
}
static void spi_wait_rx(void)
{
while(!g_rx_flag);
g_rx_flag = 0;
}

static void spi_post_rx(void)
{
g_rx_flag = 1;
}

static void spi_wait_tx(void)
{
while(!g_tx_flag);
g_tx_flag = 0;
}

static void spi_post_tx(void)
{
g_tx_flag = 1;
}

static void spi_do_delay(uint16_t n)
{
uint16_t t = n;
while (-- t);
}
uint8_t spi_byte_transfer(uint8_t Dat)
{
while ((SPI2->SR & SPI_I2S_FLAG_TXE) == 0);
SPI2->DR = Dat;
while ((SPI2->SR & SPI_I2S_FLAG_RXNE) == 0);
return ((uint8_t)(SPI2->DR));
}

uint8_t spi_readbyte(void)
{
return spi_byte_transfer(0xA5);
}

/* ?? GPIO6 ?? CS ??
*/
void flash_wait_write(void)
{
uint8_t status = 0;

spi_chip_select(true);
spi_byte_transfer(0x05);
do
{
status = spi_byte_transfer(0xA5);
} while (status & 0x01);

spi_chip_select(false);
}

void flash_enable_write(void)
{
spi_chip_select(true);
spi_byte_transfer(0x06);
spi_chip_select(false);
}

void flash_write_status(uint8_t value)
{
flash_enable_write();

spi_chip_select(true);
spi_byte_transfer(0x01);
spi_byte_transfer(value);

spi_chip_select(false);

flash_wait_write();
}

void flash_disable_write(void)
{
flash_write_status(0);
}

uint32_t flash_read_identify(void)
{
uint8_t byte0 = 0, byte1 = 0, byte2 = 0;

spi_chip_select(true);

spi_byte_transfer(0x9F);
byte0 = spi_byte_transfer(0xA5);
byte1 = spi_byte_transfer(0xA5);
byte2 = spi_byte_transfer(0xA5);

spi_chip_select(false);

return ((byte0 << 16) | (byte1 << 8) | (byte2 << 0));
}

void flash_erase_sector(uint32_t SectorAddr)
{
flash_enable_write();

spi_chip_select(true);
spi_byte_transfer(0x20);
spi_byte_transfer((SectorAddr & 0xFF0000) >> 16);
spi_byte_transfer((SectorAddr & 0xFF00) >> 8);
spi_byte_transfer(SectorAddr & 0xFF);
spi_chip_select(false);

flash_wait_write();
}
void flash_write(uint16_t* buffer, uint32_t addr, uint32_t size)
{
flash_enable_write();

spi_chip_select(true);
spi_byte_transfer(0x02);
spi_byte_transfer((addr >> 16) & 0xFF);
spi_byte_transfer((addr >> 8) & 0xFF);
spi_byte_transfer((addr >> 0) & 0xFF);

flash_start_dma(buffer, size, false);

spi_chip_select(false);
flash_wait_write();
}

void flash_read(uint16_t *buffer, uint32_t addr,uint32_t size)
{
spi_chip_select(true);
spi_byte_transfer(0x03);
spi_byte_transfer((addr >> 16) & 0xFF);
spi_byte_transfer((addr >> 8) & 0xFF);
spi_byte_transfer((addr >> 0) & 0xFF);
// SPI2_Init(1);
flash_start_dma(buffer, size, true);
// SPI2_Init(0);
spi_chip_select(false);
}

void flash_start_dma(uint16_t *buffer, uint32_t length, uint8_t isread)
{
uint32_t temp = 0xffffffff;
DMA_InitTypeDef DMA_InitStructure;
DMA_StructInit(&DMA_InitStructure);
DMA_DeInit(DMA1_Stream3);
DMA_DeInit(DMA1_Stream4);
while(DMA_GetCmdStatus(DMA1_Stream3) != DISABLE);
while(DMA_GetCmdStatus(DMA1_Stream4) != DISABLE);
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI2->DR;
if (isread == true)
{
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)buffer;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
}
else
{
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&temp;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
}
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = length;
// DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
// DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream3, &DMA_InitStructure);

DMA_StructInit(&DMA_InitStructure);

DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI2->DR;

if (isread == true)
{
    /* ?????? 0xff */
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&temp;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
}
else
{
    /* ?????? buffer ??*/
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)buffer;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
}

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_BufferSize = length;  
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream4, &DMA_InitStructure);

DMA_ITConfig(DMA1_Stream3, DMA_IT_TC, ENABLE);
DMA_ITConfig(DMA1_Stream4, DMA_IT_TC, ENABLE);

DMA_Cmd(DMA1_Stream3, ENABLE);
DMA_Cmd(DMA1_Stream4, ENABLE);
SPI2_Init(1);
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx|SPI_I2S_DMAReq_Tx, ENABLE);
spi_wait_tx();
spi_wait_rx();
SPI2_Init(0);

}
//SPI2_CS PB12
//SPI2_CLK PB13
//SPI2_MISO PB14
//SPI2_MOSI PB15
//以下是SPI模块的初始化代码,配置成主机模式
//SPI口初始化
//这里针是对SPI2的初始化
void SPI2_Init(u8 mode)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
if(mode == 0)
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15 | GPIO_Pin_14;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_Init(GPIOB, &GPIO_InitStructure);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
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_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);
SPI_Cmd(SPI2, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream3_IRQn;
NVIC_Init(&NVIC_InitStructure);
spi_chip_select(false);
}
else if (mode == 1)
{
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);
SPI_Init(SPI2, &SPI_InitStructure);
SPI_Cmd(SPI2, ENABLE);
}
}
//SPI2速度设置函数
//SPI速度=fAPB2/分频系数
//@ref SPI_BaudRate_Prescaler:SPI_BaudRatePrescaler_2~SPI_BaudRatePrescaler_256
//fAPB2时钟一般为84Mhz:
void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler)
{
assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));//判断有效性
SPI2->CR1&=0XFFC7;//位3-5清零,用来设置波特率
SPI2->CR1|=SPI_BaudRatePrescaler; //设置SPI2速度
SPI_Cmd(SPI2,ENABLE); //使能SPI2
}
//SPI2 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPI2_ReadWriteByte(u8 TxData)
{

while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET){}//等待发送区空

SPI_I2S_SendData(SPI2, TxData); //通过外设SPIx发送一个byte  数据

while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET){} //等待接收完一个byte

return SPI_I2S_ReceiveData(SPI2); //返回通过SPIx最近接收的数据	

}

void DMA1_Stream3_IRQHandler(void)
{
if (DMA_GetFlagStatus(DMA1_Stream3, DMA_FLAG_TCIF3) != RESET)
{
/* 1.??? /
DMA_ClearFlag(DMA1_Stream3, DMA_FLAG_TCIF3);
/
2.?? DMA ??? /
DMA_ITConfig(DMA1_Stream3, DMA_IT_TC, DISABLE);
/
3.?? SPI TX DMA ?? /
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, DISABLE);
/
4.?? DMA Stream /
DMA_Cmd(DMA1_Stream3, DISABLE);
/
5.??? TX ??? */
spi_post_rx();
}
}

void DMA1_Stream4_IRQHandler(void)
{
if (DMA_GetFlagStatus(DMA1_Stream4, DMA_FLAG_TCIF4) != RESET)
{
/* 1.??? /
DMA_ClearFlag(DMA1_Stream4, DMA_FLAG_TCIF4);
/
2.?? DMA ??? /
DMA_ITConfig(DMA1_Stream4, DMA_IT_TC, DISABLE);
/
3.?? SPI TX DMA ?? /
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, DISABLE);
/
4.?? DMA Stream /
DMA_Cmd(DMA1_Stream4, DISABLE);
/
6.??? RX ??? */
spi_post_tx();
}
}

SPI.H文件

#ifndef __SPI_H
#define __SPI_H
#include “sys.h”
#define FLASH_SPI SPI2
#define FLASH_SPI_CLK RCC_APB1Periph_SPI2
#define FLASH_SPI_CLK_INIT RCC_APB1PeriphClockCmd

#define FLASH_SPI_SCK_PIN GPIO_Pin_13
#define FLASH_SPI_SCK_GPIO_PORT GPIOB
#define FLASH_SPI_SCK_GPIO_CLK RCC_AHB1Periph_GPIOB
#define FLASH_SPI_SCK_PINSOURCE GPIO_PinSource13
#define FLASH_SPI_SCK_AF GPIO_AF_SPI2

#define FLASH_SPI_MISO_PIN GPIO_Pin_14
#define FLASH_SPI_MISO_GPIO_PORT GPIOB
#define FLASH_SPI_MISO_GPIO_CLK RCC_AHB1Periph_GPIOB
#define FLASH_SPI_MISO_PINSOURCE GPIO_PinSource14
#define FLASH_SPI_MISO_AF GPIO_AF_SPI2

#define FLASH_SPI_MOSI_PIN GPIO_Pin_15
#define FLASH_SPI_MOSI_GPIO_PORT GPIOB
#define FLASH_SPI_MOSI_GPIO_CLK RCC_AHB1Periph_GPIOB
#define FLASH_SPI_MOSI_PINSOURCE GPIO_PinSource15
#define FLASH_SPI_MOSI_AF GPIO_AF_SPI2

#define FLASH_CS_PIN GPIO_Pin_12
#define FLASH_CS_GPIO_PORT GPIOB
#define FLASH_CS_GPIO_CLK RCC_AHB1Periph_GPIOB
void SPI2_Init(u8 mode); //初始化SPI2口
void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler); //设置SPI1速度
u8 SPI2_ReadWriteByte(u8 TxData);//SPI2总线读写一个字节
u16 SPI2_ReadWriteByte_TEXT(u8 TxData);
void flash_start_dma(uint16_t buffer, uint32_t length, uint8_t isread);
void flash_write(uint16_t
buffer, uint32_t addr, uint32_t size);
void flash_read(uint16_t *buffer, uint32_t addr,uint32_t size);
#endif

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值