DMA发送中断和DMA接收中断必须都打开,如果接受中断不开,貌似只能接收一次成功。同时DMA接收比发送优先级要高,这条没有测试过!!!
以下代码在stm32f407上测试通过
#include "spi_dma.h"
#include "stm32f4xx_dma.h"
#include "stm32f4xx.h"
#include "spi.h"
#include "SRAM.h"
#include "data_process.h"
#include
#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
static DMA_InitTypeDef DMA2_Tx_InitStructure;
static DMA_InitTypeDef DMA2_Rx_InitStructure;
int DMA2_Trans_OVER(void)
{
return GET_SPI1_STATE;
}
static void NVIC_DMA2_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//½ÓÊÕÓÅÏȼ¶Òª¸ßÓÚ·¢ËÍ
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void DMA2_Configuration(void)
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);
DMA_DeInit(DMA2_TX_STREAM);
DMA2_Tx_InitStructure.DMA_Channel = DMA2_TX_CHANNEL; //ͨµÀÑ¡Ôñ
DMA2_Tx_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI1->DR;//ÍâÉèµØÖ·
DMA2_Tx_InitStructure.DMA_Memory0BaseAddr = 0;//base_address;//ÄÚ´æµØÖ·
DMA2_Tx_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;//·½ÏòÊÇÄÚ´æµ½ÍâÉè
DMA2_Tx_InitStructure.DMA_BufferSize = 0;//ndtr;//´«ÊäÊý¾Ý´óС
DMA2_Tx_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//ÍâÉèÊý¾ÝÖ¸Õë²»±ä
DMA2_Tx_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//ÄÚ´æÿ´ÎµÝÔö
DMA2_Tx_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//ÍâÉèÒ»×Ö½ÚΪµ¥Î»
DMA2_Tx_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//ÄÚ´æÒÔ×Ö½ÚΪµ¥Î»
DMA2_Tx_InitStructure.DMA_Mode = DMA_Mode_Normal;//Õý³£Ä£Ê½
DMA2_Tx_InitStructure.DMA_Priority = DMA_Priority_Medium;
DMA2_Tx_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA2_Tx_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA2_Tx_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//´æ´¢Æ÷Í»·¢µ¥´Î´«Êä
DMA2_Tx_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//ÍâÉèÍ»·¢µ¥´Î´«Êä
///
DMA_DeInit(DMA2_RX_STREAM);
DMA2_Rx_InitStructure.DMA_Channel = DMA2_RX_CHANNEL; //ͨµÀÑ¡Ôñ
DMA2_Rx_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI1->DR;//ÍâÉèµØÖ·
DMA2_Rx_InitStructure.DMA_Memory0BaseAddr = 0;//base_address;//ÄÚ´æµØÖ·
DMA2_Rx_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;//·½ÏòÊÇÍâÉèµ½ÄÚ´æ
DMA2_Rx_InitStructure.DMA_BufferSize = 0;//ndtr;//´«ÊäÊý¾Ý´óС
DMA2_Rx_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//ÍâÉèÊý¾ÝÖ¸Õë²»±ä
DMA2_Rx_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//ÄÚ´æÿ´ÎµÝÔö
DMA2_Rx_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//ÍâÉèÒ»×Ö½ÚΪµ¥Î»
DMA2_Rx_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//ÄÚ´æÒÔ×Ö½ÚΪµ¥Î»
DMA2_Rx_InitStructure.DMA_Mode = DMA_Mode_Normal;//Õý³£Ä£Ê½
DMA2_Rx_InitStructure.DMA_Priority = DMA_Priority_Medium;
DMA2_Rx_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA2_Rx_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA2_Rx_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//´æ´¢Æ÷Í»·¢µ¥´Î´«Êä
DMA2_Rx_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//ÍâÉèÍ»·¢µ¥´Î´«Êä
///
NVIC_DMA2_Configuration();
DMA_ClearITPendingBit(DMA2_TX_STREAM,DMA_IT_TCIF3);
DMA_ClearITPendingBit(DMA2_RX_STREAM,DMA_IT_TCIF0);
DMA_ITConfig(DMA2_TX_STREAM, DMA_IT_TC, ENABLE);//ʹÄÜDMA·¢ËÍÖжÏ
DMA_ITConfig(DMA2_RX_STREAM, DMA_IT_TC, ENABLE);//ʹÄÜDMA½ÓÊÕÖжÏ
/* Enable SPI1 DMA TX request */
SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx,ENABLE);
SET_SPI1_DISABLE;
}
void SPI1_DMA2_Configuration(void)
{
printf(" ---------SPI1_DMA2_Configuration----------\n");
DMA2_Configuration();
}
void SPI1_DMA2_Sendbuffer(uint32_t base_address,uint16_t ndtr,uint8_t *send_buffer)
{
printf("DMA2 Sendbuffer : address = %x length = %x\r\n",base_address,ndtr);
while (DMA_GetCmdStatus(DMA2_TX_STREAM) != DISABLE){printf(",");}
DMA2_Tx_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA2_Tx_InitStructure.DMA_Memory0BaseAddr = (uint32_t)send_buffer;
DMA2_Tx_InitStructure.DMA_BufferSize = ndtr;
DMA_Init(DMA2_TX_STREAM, &DMA2_Tx_InitStructure);
SET_SPI1_ENABLE;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}
SPI_I2S_SendData(SPI1,0xe5);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}
SPI_I2S_SendData(SPI1,(base_address >> 16) & 0xff);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}
SPI_I2S_SendData(SPI1,(base_address >> 8) & 0xff);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}
SPI_I2S_SendData(SPI1,(base_address >> 0) & 0xff);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}
SPI_I2S_SendData(SPI1,(ndtr >> 8) & 0xff);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}
SPI_I2S_SendData(SPI1,(ndtr >> 0) & 0xff);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}
SPI_I2S_SendData(SPI1,0x00);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}
SPI_I2S_SendData(SPI1,0x00);
DMA_Cmd(DMA2_TX_STREAM, ENABLE);
}
void SPI1_DMA2_Recvbuffer(uint32_t base_address,uint16_t ndtr,uint8_t *recv_buffer)
{
unsigned char buffer = 0xff;
printf("DMA2 Recvbuffer : address = %x length = %x\r\n",base_address,ndtr);
while (DMA_GetCmdStatus(DMA2_RX_STREAM) != DISABLE){printf(".");}
while (DMA_GetCmdStatus(DMA2_TX_STREAM) != DISABLE){printf(",");}
DMA2_Rx_InitStructure.DMA_Memory0BaseAddr = (uint32_t)recv_buffer;
DMA2_Rx_InitStructure.DMA_BufferSize = ndtr;
DMA_Init(DMA2_RX_STREAM, &DMA2_Rx_InitStructure);
DMA2_Tx_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;//ÄÚ´æµÝÔö
DMA2_Tx_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&buffer;
DMA2_Tx_InitStructure.DMA_BufferSize = ndtr;
DMA_Init(DMA2_TX_STREAM, &DMA2_Tx_InitStructure);
SET_SPI1_ENABLE;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}
SPI_I2S_SendData(SPI1,0xaa);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}
SPI_I2S_SendData(SPI1,(base_address >> 16) & 0xff);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}
SPI_I2S_SendData(SPI1,(base_address >> 8) & 0xff);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}
SPI_I2S_SendData(SPI1,(base_address >> 0) & 0xff);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}
SPI_I2S_SendData(SPI1,(ndtr >> 8) & 0xff);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}
SPI_I2S_SendData(SPI1,(ndtr >> 0) & 0xff);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}
SPI_I2S_SendData(SPI1,0x00);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}
SPI_I2S_SendData(SPI1,0x00);
while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY) != RESET){printf(".");}
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != RESET){
SPI_I2S_ReceiveData(SPI1);
}
DMA_Cmd(DMA2_RX_STREAM, ENABLE);
DMA_Cmd(DMA2_TX_STREAM, ENABLE);
}
void SPI1_DMA2_GetCounter(void)
{
printf("DMA2 RECV %d | SEND %d\r\n",(uint16_t)(DMA2_RX_STREAM->NDTR),(uint16_t)(DMA2_TX_STREAM->NDTR));
}
void DMA2_Stream3_IRQHandler(void)
{
if(DMA_GetITStatus(DMA2_TX_STREAM,DMA_IT_TCIF3) != RESET)
{
DMA_ClearITPendingBit(DMA2_TX_STREAM,DMA_IT_TCIF3);
while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY) != RESET){printf(".");}
SET_SPI1_DISABLE;
//printf("[ISend]");
DMA_Cmd(DMA2_TX_STREAM, DISABLE);
}
}
void DMA2_Stream0_IRQHandler(void)
{
if(DMA_GetITStatus(DMA2_RX_STREAM,DMA_IT_TCIF0) != RESET)
{
DMA_ClearITPendingBit(DMA2_RX_STREAM,DMA_IT_TCIF0);
while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY) != RESET){printf(",");}
//printf("[IRecv]");
DMA_Cmd(DMA2_RX_STREAM, DISABLE);
}
}