使用带有STM32的SPI的

时间:2015-06-30 15:05:41

标签: c stm32 spi dma

我正在使用DMA通过外部闪存管理一些SPI传输。检索到的第一个和最后一个数据字节无效。我可以忍受最后一个字节无效(但仍然想知道原因)但不是第一个。

这是DMA初始化

// Deinitialize DMA Streams 
DMA_DeInit(DMA_TX_STREAM);
DMA_DeInit(DMA_RX_STREAM);

// Initialize buffer size
DMA_InitStructure.DMA_BufferSize = *nbData;
// Rest of Init
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable ;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single ;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

DMA_InitStructure.DMA_PeripheralBaseAddr = (Uint32)&(SPIx->DR);
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;

// Configure Tx DMA 
DMA_InitStructure.DMA_Channel = DMA_TX_CHANNEL;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_Memory0BaseAddr = (Uint32) data;
DMA_Init(DMA_TX_STREAM, &DMA_InitStructure);

// Configure Rx DMA 
DMA_InitStructure.DMA_Channel = DMA_RX_CHANNEL;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) data;
DMA_Init(DMA_RX_STREAM, &DMA_InitStructure);

DMA_ITConfig(DMA_RX_STREAM, DMA_IT_TC, ENABLE);

// Enable the DMA Stream IRQ Channel
NVIC_InitStructure.NVIC_IRQChannel = DMA_RX_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

// Enable DMA Streams
DMA_Cmd(DMA_RX_STREAM, ENABLE);
DMA_Cmd(DMA_TX_STREAM, ENABLE);

// Enable DMA SPI request
SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, ENABLE);
SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Tx, ENABLE);

在DMA传输开始之前,我尝试推送SPI传输在SPIx-> DR中有一些东西,但没有成功

while(SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPIx, (Uint16)0x00);

为什么会发生这种情况?您会如何建议修复它?

编辑:这是使用的定义

#define SPIx                            SPI2
#define DMA_RX_STREAM                   DMA1_Stream3
#define DMA_RX_CHANNEL                  DMA_Channel_0
#define DMA_RX_IRQ                      DMA1_Stream3_IRQn
#define DMA_IT_TCIF_RX                  DMA_IT_TCIF3
#define DMA_TX_STREAM                   DMA1_Stream4
#define DMA_TX_CHANNEL                  DMA_Channel_0
#define DMA_TX_IRQ                      DMA1_Stream4_IRQn
#define DMA_IT_TCIF_TX                  DMA_IT_TCIF4

编辑2:第一个和最后一个字节读取0而不是0xff。这是转移的开始和结束。

Start

End

为了澄清,我使用普通的SPI指令发送读命令,然后我为特定的数据长度配置DMA并开始传输(SCLK连续的部分)。 Flash为空(已验证),表示所有内容均为0xFF。数据缓冲区在第一个和最后一个字节中得到0 ......

1 个答案:

答案 0 :(得分:2)

我怀疑,当SPI已经开始转移时,你启动SS太迟了。并且在帧结束时过早禁用它,同时仍然有一些位被移位。

首先启动SPI,然后启动DMA。最后,等到DMA完成(SPI !BUSY不起作用,如果DMA太慢而无法连续提供SPI)。