stm32f103使用串口DMA接收不定长数据

该程序实现了STM32F103RET6单片机上串口1、2、3、4的DMA自动接收功能,能够接收不定长数据并在数据接收完成后触发IDLE中断。在中断服务程序中,清除中断标志并获取接收数据长度。程序通过定义接收缓冲区大小和使用中断标志来管理接收过程,并提供了串口初始化和中断处理的详细代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本段程序主要是实现串口的DMA自动接收,可接收不定长数据,数据接收完成后,串口产生IDLE(空闲)中断,在中断函数中清除中断标志位,并获取接收 数据长度。
程序在STM32F103RET6单片机上测试成功,可实现串口1、串口2、串口3、串口4的DMA自动接收,串口5没有对应DMA,只能用接收中断接收。

//首先定义串口接收缓冲区大小
#define USART1_REC_LEN  			100  	//定义最大接收字节数 
#define USART2_REC_LEN  			100  	//定义最大接收字节数 
#define USART3_REC_LEN  			50  	//定义最大接收字节数 
#define UART4_REC_LEN  				50  	//定义最大接收字节数 
#define UART5_REC_LEN  				50   	//定义最大接收字节数 
#define EN_USART1_RX 			1		//使能(1)/禁止(0)串口1接收
#define EN_USART2_RX 			1		//使能(1)/禁止(0)串口1接收
#define EN_USART3_RX 			1		//使能(1)/禁止(0)串口1接收
#define EN_UART4_RX 			1		//使能(1)/禁止(0)串口1接收
#define EN_UART5_RX 			1		//使能(1)/禁止(0)串口1接收

//定义各个串口接收数组
u8 USART1_RX_BUF[USART1_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
u8 USART2_RX_BUF[USART2_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
u8 USART3_RX_BUF[USART3_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
u8 UART4_RX_BUF[UART4_REC_LEN];
u8 UART5_RX_BUF[UART5_REC_LEN];

//定义串口接收中断标志,为自定义标志,非必要,个人习惯,可自由使用
#define USART1_RX_FLAG		(0X0001<<0)
#define USART1_RX_IDEL_FLAG	(0X0001<<1)
#define USART2_RX_FLAG		(0X0001<<3)
#define USART2_RX_IDEL_FLAG	(0X0001<<4)
#define USART3_RX_FLAG		(0X0001<<6)
#define USART3_RX_IDEL_FLAG	(0X0001<<7)
#define UART4_RX_FLAG		(0X0001<<9)
#define UART4_RX_IDEL_FLAG	(0X0001<<10)
#define UART5_RX_FLAG		(0X0001<<12)
#define UART5_RX_IDEL_FLAG	(0X0001<<13)

以下是串口的初始化函数及接收中断函数,另外附上串口的几种发送函数


u16 USART_IT_STATUS;
u16 Head1=0,Head2=0,Head3=0,Tail1=0,Tail2=0,Tail3=0,Tail4=0,Tail5=0;

//初始化 串口1 
//bound:波特率
void Usart1_Init(u32 bound){
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	DMA_InitTypeDef DMA_InitStructure;
	
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);			//ENABLE clock
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟
 	USART_DeInit(USART1);  //复位串口1
	 //USART1_TX   PA.9
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9
   
    //USART1_RX	  PA.10
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PA10

   //Usart1 NVIC 配置

    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
  
   //USART 初始化设置

	USART_InitStructure.USART_BaudRate = bound;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	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(USART1, &USART_InitStructure); 					//初始化串口
    USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);				//开启空闲中断
    
	DMA_DeInit(DMA_USART1_RX);												//串口2接收DMA通道
	DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(USART1->DR);
	DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&USART1_RX_BUF[0];
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
	DMA_InitStructure.DMA_BufferSize = USART1_REC_LEN;
	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_Circular;
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA_USART1_RX,&DMA_InitStructure);     						//DMA1_Channel3 配置
	DMA_ITConfig(DMA_USART1_RX,DMA1_IT_TC1,DISABLE);						//DMA接收缓冲区满中断使能
	
	NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;  
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;  
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
	NVIC_Init(&NVIC_InitStructure);  

	USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);
    DMA_Cmd(DMA_USART1_RX,DISABLE);
	USART_Cmd(USART1,ENABLE);	

}


void USART1_IRQHandler(void)                	//串口1中断服务程序
{
	u8 res;
	if(USART_GetITStatus(USART1,USART_IT_IDLE)!=RESET)
	{
		/******************************/
		res = USART1->SR;
		res = USART1->DR;									//连续读写状态位与数据位,清除中断标志
		Tail1 = USART1_REC_LEN - DMA_GetCurrDataCounter(DMA_USART1_RX);	//获取接收到的数据长度
		
		/******************************/
		USART_IT_STATUS |= (USART1_RX_IDEL_FLAG);			//自定义标志位置位
	}
} 



void Usart2_Init(u32 baud)
{
	GPIO_InitTypeDef 	GPIO_InitStructure;
	USART_InitTypeDef 	USART_InitStructure;
	NVIC_InitTypeDef 	NVIC_InitStructure;
	DMA_InitTypeDef 	DMA_InitStructure;
	
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);			//ENABLE clock
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2|RCC_APB2Periph_GPIOA,ENABLE);
	USART_DeInit(USART2);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	//推挽复用输出
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	USART_InitStructure.USART_BaudRate = baud;
	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_ITConfig(USART2,USART_IT_IDLE,ENABLE);							//串口空闲中断

	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	
	DMA_DeInit(DMA1_Channel6);												//串口2接收DMA通道
	DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(USART2->DR);
	DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&USART2_RX_BUF[0];
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
	DMA_InitStructure.DMA_BufferSize = USART2_REC_LEN;
	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_Circular;
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA1_Channel6,&DMA_InitStructure);     						//DMA1_Channel3 配置
	DMA_ITConfig(DMA1_Channel6,DMA1_IT_TC1,DISABLE);						//DMA接收缓冲区满中断使能
	
	NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn;  
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;  
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
	NVIC_Init(&NVIC_InitStructure);  

	USART_DMACmd(USART2,USART_DMAReq_Rx,ENABLE);
    DMA_Cmd(DMA1_Channel6,DISABLE);
	USART_Cmd(USART2,ENABLE);	
}



void USART2_IRQHandler(void)                	//串口1中断服务程序
{
	u8 res;
	if(USART_GetITStatus(USART2,USART_IT_IDLE)!=RESET)
	{
		/******************************/
		res = USART2->SR;
		res = USART2->DR;												//连续读写状态位与数据位,清除中断标志
		Tail2 = USART2_REC_LEN - DMA_GetCurrDataCounter(DMA_USART2_RX);	//获取接收到的数据长度
		/******************************/
		USART_IT_STATUS |= (USART2_RX_IDEL_FLAG);						//自定义标志位置位
	}
} 

//串口3初始化
void Usart3_Init(u32 baud)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	DMA_InitTypeDef DMA_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);			//ENABLE clock
	USART_DeInit(USART3);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	USART_InitStructure.USART_BaudRate = baud;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_Init(USART3,&USART_InitStructure);
#if EN_USART3_RX   //如果使能了接收
	USART_ITConfig(USART3,USART_IT_IDLE,ENABLE);				//使能空闲中断
	
	NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
#endif	
	DMA_DeInit(DMA1_Channel3);
	DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(USART3->DR);
	DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&USART3_RX_BUF[0];
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
	DMA_InitStructure.DMA_BufferSize = USART3_REC_LEN;
	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_Circular;
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA1_Channel3,&DMA_InitStructure);     			//DMA1_Channel3 配置
	DMA_ITConfig(DMA1_Channel3,DMA_IT_TC,DISABLE);				//DMA接收缓冲区满中断使能
	
	NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel3_IRQn;  
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;  
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
	NVIC_Init(&NVIC_InitStructure);  

	USART_Cmd(USART3,ENABLE);	
	USART_DMACmd(USART3,USART_DMAReq_Rx,ENABLE);
    DMA_Cmd(DMA1_Channel3,ENABLE);
}


void USART3_IRQHandler(void)                	//串口1中断服务程序
{
	u8 res;
	if(USART_GetITStatus(USART3,USART_IT_IDLE)!=RESET)					//串口空闲中断
	{
		/******************************/
		res = USART3->SR;
		res = USART3->DR;												//连续读写状态位与数据位,清除中断标志
		Tail3 = USART3_REC_LEN - DMA_GetCurrDataCounter(DMA1_Channel3);	//获取接收到的数据长度
		/******************************/
		USART_IT_STATUS |= (USART3_RX_IDEL_FLAG);						//自定义标志位置位
		
	}
} 


void Uart4_Init(u32 baud)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	DMA_InitTypeDef DMA_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2,ENABLE);			//ENABLE clock
	USART_DeInit(UART4);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOC,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOC,&GPIO_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	USART_InitStructure.USART_BaudRate = baud;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_Init(UART4,&USART_InitStructure);
	USART_ITConfig(UART4,USART_IT_IDLE,ENABLE);								//串口空闲中断
	
	DMA_DeInit(DMA2_Channel3);												//串口4接收DMA通道
	DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(UART4->DR);
	DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&UART4_RX_BUF[0];
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
	DMA_InitStructure.DMA_BufferSize = UART4_REC_LEN;
	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_Circular;
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA2_Channel3,&DMA_InitStructure);     						//DMA1_Channel3 配置
	DMA_ITConfig(DMA2_Channel3,DMA1_IT_TC1,DISABLE);						//DMA接收缓冲区满中断使能
	
	NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel3_IRQn;  
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;  
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
	NVIC_Init(&NVIC_InitStructure);  

	USART_Cmd(UART4,ENABLE);	
	USART_DMACmd(UART4,USART_DMAReq_Rx,ENABLE);
    DMA_Cmd(DMA2_Channel3,ENABLE);
	
}


void UART4_IRQHandler(void)                	//串口1中断服务程序
{
	u8 res;
	if(USART_GetITStatus(UART4,USART_IT_IDLE)!=RESET)					//串口空闲中断
	{
		/******************************/
		res = UART4->SR;
		res = UART4->DR;												//连续读写状态位与数据位,清除中断标志
		Tail4 = UART4_REC_LEN - DMA_GetCurrDataCounter(DMA2_Channel3);	//获取接收到的数据长度
		/******************************/
		USART_IT_STATUS |= (UART4_RX_IDEL_FLAG);						//自定义标志位置位
	}
} 


void Uart5_Init(u32 baud)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);
	USART_DeInit(UART5);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOC,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOD,&GPIO_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	USART_InitStructure.USART_BaudRate = baud;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_Init(UART5,&USART_InitStructure);
	USART_ITConfig(UART5,USART_IT_RXNE,ENABLE);
	USART_ITConfig(UART5,USART_IT_IDLE,ENABLE);
	USART_Cmd(UART5,ENABLE);
}


#if EN_UART5_RX
void UART5_IRQHandler(void)                	//串口3中断服务程序
{
	u8 res;

	if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
	{
		USART_ClearITPendingBit(UART5, USART_IT_RXNE);
		res = USART_ReceiveData(UART5);
		UART5_RX_BUF[Tail5++] = res;
		USART_IT_STATUS |= (UART5_RX_FLAG);
		Tail5 %= UART5_REC_LEN;
		
	}
	if(USART_GetITStatus(UART5,USART_IT_IDLE)!=RESET)
	{
		/******************************/
		res = UART5->SR;
		res = UART5->DR;		//连续读写状态位与数据位,清除中断标志
		/******************************/
		USART_IT_STATUS |= (UART5_RX_IDEL_FLAG);
	}
} 
#endif	

//指定串口发送字节
void Usart_TxByte(USART_TypeDef *USARTx,u8 byte)
{
	USART_SendData(USARTx,byte);
	while(USART_GetFlagStatus(USARTx,USART_FLAG_TXE)==0){}
}
//指定串口发送字,高位在前,低位在后
void Usart_TxWord(USART_TypeDef *USARTx,u16 word)
{
	Usart_TxByte(USARTx,word>>8);
	Usart_TxByte(USARTx,word);
}
//指定串口发送双字,高位在前,低位在后
void Usart_TxU32(USART_TypeDef *USARTx,u32 Long)
{
	Usart_TxByte(USARTx,(Long&0xff000000)>>24);
	Usart_TxByte(USARTx,(Long&0x00ff0000)>>16);
	Usart_TxByte(USARTx,(Long&0x0000ff00)>>8);
	Usart_TxByte(USARTx,Long&0x000000ff);	
}

//指定串口发送字符串
void Usart_TxString(USART_TypeDef *USARTx,char *s)
{
	u8 i=0;
	while(s[i])
	{
		Usart_TxByte(USARTx,s[i]);
		i++;
	}
}

//指定串口发送数组a,长度为len
void Usart_TxByteArray(USART_TypeDef *USARTx,u8 *a,u16 len)
{
	u16 i=0;
	while(i<len)
	{
		Usart_TxByte(USARTx,a[i]);
		i++;
	}
}
void Usart_TxWordArray(USART_TypeDef *USARTx, u16 *a, u8 len)
{
	u8 i=0;
	while(i<len)
	{
		Usart_TxWord(USARTx,a[i]);
		i++;
	}
}

以上为串口初始化部分程序,程序基于正点原子模板改写,全部的项目代码电击此链接,免费下载串口DMA接收

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值