HK32F103 用DMA配合串口空闲中断接收不定长数据

先初始化串口,开启串口时钟,DMA时钟,这里用的是DMA1  然后开启串口的读取中断。

  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;
  DMA_InitTypeDef DMA_InitStructure;
	
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  	// 开启DMA时钟  	// 开启DMA时钟
  RCC_APB2PeriphClockCmd(DEBUGx_USART_RX_GPIO_CLK, ENABLE);

  /* 使能 UART 时钟 */
  RCC_APB1PeriphClockCmd(DEBUGx_USART_CLK, ENABLE);
/* 配置Tx引脚为复用功能  */
	GPIO_InitStructure.GPIO_Pin = DEBUGx_USART_TX_PIN; //PA.3
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
	GPIO_Init(DEBUGx_USART_TX_GPIO_PORT, &GPIO_InitStructure);
   
	//  PA.2
	GPIO_InitStructure.GPIO_Pin = DEBUGx_USART_RX_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_Init(DEBUGx_USART_RX_GPIO_PORT, &GPIO_InitStructure);  

/* 配置串DEBUG_USART 模式 */
  USART_InitStructure.USART_BaudRate = DEBUGx_USART_BAUDRATE;
  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(DEBUGx_USART, &USART_InitStructure); 

DMA_DeInit(DMA1_Channel6);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART2->DR;				 //DMA外设地址
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_data.USART_BUFF;			 //DMA 存储器0地址
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;   							 //外设到存储器模式
  DMA_InitStructure.DMA_BufferSize = USART2_TEMP_LEN;												 //数据传输量 
  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_VeryHigh;									 //高等优先级
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;	
	
  DMA_Init(DMA1_Channel6, &DMA_InitStructure);	//初始化DMA Stream

	USART_ITConfig(DEBUGx_USART, USART_IT_RXNE, ENABLE);//开启相关中断
	USART_DMACmd(DEBUGx_USART,USART_DMAReq_Rx,ENABLE);
  USART_Cmd(DEBUGx_USART, ENABLE);
	USART_ClearFlag(DEBUGx_USART, USART_FLAG_TC);

DMA的串口数据流映射表 DMA1和DMA2

串口中断里面开启空闲中断

void USART2_IRQHandler(void)
{
	if(USART_GetITStatus(USART2,USART_IT_IDLE)!=RESET) //空闲中断触发
	{		
		//接收数据
  	usart2_receive();                              //取出接收数据包并处理函数
		USART_ReceiveData(USART2);   //清除空闲中断标志位(接收函数有清标志位的作用)
		USART_ITConfig(USART2, USART_IT_IDLE, DISABLE);   //关闭空闲中断
		USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);    //开启读取中断
	}
	else if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET) //空闲中断触发
	{
		usart2_receive(); 
		USART_ReceiveData(USART2); //清空标志		
	}else
	{
		USART_ReceiveData(USART2);   //清除空闲中断标志位(接收函数有清标志位的作用)
		USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);   //开启空闲中断
		USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
	}
}

接收串口数据函数

void usart2_receive(void)
{
	uint16_t buff_length;
	
	buff_length=DMA_GetCurrDataCounter(DMA1_Channel6);/* 获取接收到的数据长度 单位为字节*/
	DMA_Cmd(DMA1_Channel6, DISABLE);  					   /* 暂时关闭dma,数据尚未处理 */ 
	USART2_data.USART_LEN = USART2_TEMP_LEN -(u16)buff_length;        					 /* 获取数据长度 */
	DMA_ClearFlag(DMA1_FLAG_TC6);  /* 清DMA标志位 */         
	DMA_SetCurrDataCounter(DMA1_Channel6,USART2_TEMP_LEN);/* 重新赋值计数值,必须大于等于最大可能接收到的数据帧数目 */	
	
//	usart2_RX_data[RX2]=USART2_data;
	USART2_task(&USART2_data);
	
	DMA_Cmd(DMA1_Channel6, ENABLE);      				  /*打开DMA*/
}

第一次激活DMA

DMA_Cmd(DMA1_Channel6, DISABLE); 
DMA_SetCurrDataCounter(DMA1_Channel6,USART3_TEMP_LEN);	
DMA_Cmd(DMA1_Channel6, ENABLE);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值