stm32f429串口读写DMA方式

头文件
下面展示一些 内联代码片

#ifndef __HAL_UART_H
#define __HAL_UART_H

#ifdef __cplusplus
extern "C" {
#endif 
//RS232全双工,接收发送缓冲区分开(直接操作DMA缓冲区,注意:DMA收发数据缓冲区不做保护的)	
#define Uart2RXbuffMax		256												//接收缓冲区大小
#define Uart2TXbuffMax		256												//发送缓冲区大小	
extern unsigned char  Uart2RXbuff[Uart2RXbuffMax];							//接收缓冲区
extern unsigned short Uart2RXbuff_len;										//接收数据长度,最高位置一,则接收完整一帧数据
extern unsigned char  Uart2TXbuff[Uart2TXbuffMax];	
void Uart2SetBaudRate(unsigned int ulBaudRate);
char Uart2SendBuff(unsigned short data_len);
//带保护读写串口
void ReadUart2buffSafety(unsigned char *buff,unsigned short *len);			//*len=读取到数据的长度
void WriteUart2buffSafety(unsigned char *buff,unsigned short *len);			//*len=发送数据的长度
#ifdef __cplusplus
}
#endif

#endif

C源文件

/*********************************************************************************************************/

/*********************************************************************************************************/
//串口2
//A3(RX2)		DMA1_Stream5		chanel4	
//A2(TX2)		DMA1_Stream6		chanel4	

/*********************************************************************************************************/

/*********************************************************************************************************/
unsigned char  Uart2RXbuff[Uart2RXbuffMax];
unsigned short Uart2RXbuff_len=0;
unsigned char  Uart2TXbuff[Uart2TXbuffMax];	
static void uart2_init(u32 ulBaudRate)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); 
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
	
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_3;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
					
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_2;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);        
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); 

	//USART3 初始化设置
	USART_InitStructure.USART_BaudRate = ulBaudRate;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
	USART_Init(USART2, &USART_InitStructure); 
	
	USART_Cmd(USART2, ENABLE); 
	
	USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);//开启相关中断  
	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=13;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;  
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);  

	USART_DMACmd(USART2,USART_DMAReq_Rx,ENABLE); //使用rx dma   
	USART_DMACmd(USART2,USART_DMAReq_Tx,ENABLE);//使用tx dma
	
//	for(;;)
//	{
//	while((USART2->SR&0X40)==0);//循环发送,直到发送完毕   
//    USART2->DR = 'a'; 
//	delay_us(50);
//	}
	
}
static void uart2_dma_init(void)
{
	DMA_InitTypeDef  DMA_InitStructure;
	NVIC_InitTypeDef  NVIC_InitStructure;
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);

	//uart2dma发送		DMA1_Stream6
	DMA_DeInit(DMA1_Stream6);
	DMA_StructInit(&DMA_InitStructure);
	while (DMA_GetCmdStatus(DMA1_Stream6) != DISABLE){}
	/*  DMA Stream */
	DMA_InitStructure.DMA_Channel = DMA_Channel_4;  
	DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&(USART2->DR));
	DMA_InitStructure.DMA_Memory0BaseAddr = (u32)Uart2TXbuff;
	DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
	DMA_InitStructure.DMA_BufferSize = 0;//Uart3TXbuffMax;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
	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_Stream6, &DMA_InitStructure);
	

	//uart2dma接收		DMA1_Stream5
	DMA_DeInit(DMA1_Stream5);  
	while (DMA_GetCmdStatus(DMA1_Stream5) != DISABLE);					//等待DMA可配置	
	/* DMA Stream */  
	DMA_InitStructure.DMA_Channel = DMA_Channel_4;						//通道选择	
	DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&(USART2->DR));	//DMA外设地址  
	DMA_InitStructure.DMA_Memory0BaseAddr = (u32)Uart2RXbuff;			//DMA 存储器0地址	
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory ;			//外设到存储器模式	
	DMA_InitStructure.DMA_BufferSize = Uart2RXbuffMax;					//数据传输量   
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;	//外设非增量模式  
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;				//存储器增量模式  
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;		//外设数据长度:8位  
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;				//存储器数据长度:8位  
	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_Stream5, &DMA_InitStructure);							//初始化DMA Stream  
	//接收完成中断DMA NVIC	  
	//DMA_ITConfig(DMA1_Stream1,DMA_IT_TC,ENABLE);
	NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream5_IRQn;    
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 13;	 
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;	  
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;    
	NVIC_Init(&NVIC_InitStructure);   
	
	DMA_Cmd(DMA1_Stream5, ENABLE);										//开启DMA传输	

//	ucRTUBuf[9]=0x55;	
//	modbus_com_send(10);	
//	delay_10ms(100);
//	
//	ucRTUBuf[9]=0xaa;	
//	modbus_com_send(10);	
//	delay_10ms(100);

}



//空闲中断(关注帧中断)
void USART2_IRQHandler(void)  
{  
//	u16 i=0;
    u16 data;  
    if(USART_GetITStatus(USART2,USART_IT_IDLE) != RESET)  
    {  
			DMA_Cmd(DMA1_Stream5, DISABLE); //关闭DMA,防止处理其间有数据 
			DMA_ClearITPendingBit(DMA1_Stream5, DMA_IT_TCIF5);
			Uart2RXbuff_len =Uart2RXbuffMax-DMA_GetCurrDataCounter(DMA1_Stream5);  
			Uart2RXbuff_len|=0x8000;
			data = USART2->SR;
			data=data;
			data = USART2->DR;  
			DMA_ClearFlag(DMA1_Stream5,DMA_FLAG_TCIF5 | DMA_FLAG_FEIF5 | DMA_FLAG_DMEIF5 | DMA_FLAG_TEIF5 | DMA_FLAG_HTIF5); 
			DMA_SetCurrDataCounter(DMA1_Stream5, Uart2RXbuffMax);  
			DMA_Cmd(DMA1_Stream5, ENABLE);     //打开DMA, 
			DMA_ClearITPendingBit(DMA1_Stream5, DMA_IT_TCIF5);
    }  
} 

//接收完成中断
void DMA1_Stream5_IRQHandler(void)  
{  
    //清除标志  
    if(DMA_GetFlagStatus(DMA1_Stream5,DMA_FLAG_TCIF5)!=RESET)//等待DMA1_Steam3传输完成  
    {   
        DMA_Cmd(DMA1_Stream5, DISABLE); //关闭DMA,防止处理其间有数据  
        DMA_ClearFlag(DMA1_Stream5,DMA_FLAG_TCIF5 | DMA_FLAG_FEIF5 | DMA_FLAG_DMEIF5 | DMA_FLAG_TEIF5 | DMA_FLAG_HTIF5);//清除DMA1_Steam3传输完成标志  
        DMA_ClearITPendingBit(DMA1_Stream5, DMA_IT_TCIF5); //清中断标志位(跟上一个标志位不一样的)
        DMA_SetCurrDataCounter(DMA1_Stream5, Uart2RXbuffMax);  
        DMA_Cmd(DMA1_Stream5, ENABLE);     //打开DMA,  
    }  
} 

//返回1串口发送成功
char Uart2SendBuff(unsigned short data_len)
{	
	u16 wait_count=0;
	//while(DMA_GetITStatus(DMA1_Stream3,DMA_FLAG_TCIF3)==RESET)//
	//while((DMA_GetFlagStatus(DMA1_Stream3,DMA_FLAG_TCIF3)==RESET))//407无需开启DMA_IT_TC,可查询改标志位,429有bug必须开启DMA_IT_TC
	while(DMA_GetCurrDataCounter(DMA1_Stream6))//等待上一次传输完成
	{ 
		delay_ms(1);
		++wait_count;
		if(wait_count>100)//1s
		{
			return 0;
		}
	}
	DMA_ClearFlag(DMA1_Stream6,DMA_FLAG_TCIF6);//清除传输完成标志位
	
	DMA_Cmd(DMA1_Stream6, DISABLE);   	//该函数必须在DMA_SetCurrDataCounter之前调用,否则不传输
	while (DMA_GetCmdStatus(DMA1_Stream6) != DISABLE)
	{
		delay_ms(1);
	}	
	
	DMA_SetCurrDataCounter(DMA1_Stream6,data_len);    //设置传送字节数      
 
	DMA_Cmd(DMA1_Stream6, ENABLE);    

	return 1;
}

void WriteUart2buffSafety(unsigned char *buff,unsigned short *len)
{
	memcpy(Uart2TXbuff,buff,*len);
	Uart2SendBuff(*len);
}
void ReadUart2buffSafety(unsigned char *buff,unsigned short *len)
{
	if((Uart2RXbuff_len&0x8000)!=0x8000)	//帧处理未完毕
	{
		*len=0;
		return ;
	}
	Uart2RXbuff_len&=0x7fff;				//清接收帧标志
	*len=Uart2RXbuff_len;					//真实数据长度
	memcmp(buff,Uart2RXbuff,*len);
}

void Uart2SetBaudRate(unsigned int ulBaudRate)
{
	USART_InitTypeDef USART_InitStructure;
	
	USART_Cmd(USART2, DISABLE);
	
	USART_InitStructure.USART_BaudRate = ulBaudRate;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No ;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_Init(USART2, &USART_InitStructure);
	
	USART_Cmd(USART2, ENABLE);
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值