我正在使用 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。这是传输的开始和结束。
为了澄清,我使用普通 SPI 指令发送读取命令,然后将 DMA 配置为特定数据长度并开始传输(SCLK 连续的部分)。闪存为空(已验证),这意味着一切都为 0xFF。数据缓冲区的第一个和最后一个字节为 0...
最佳答案
我怀疑,当 SPI 已经开始传输时,您启用 SS 的时间太晚了。并在帧结束时过早禁用它,同时仍有位被移动。
开始时,首先启用 SPI,然后启动 DMA。最后,等待 DMA 完成(如果 DMA 太慢而无法连续馈送 SPI,则 SPI !BUSY
将不起作用)。
关于c - 使用 STM32 进行 SPI 的 DMA 时数据无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31141950/