Stm32作为主设备使用DMA接收SPI数据

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);
  }
}

你可能感兴趣的:(Stm32)