串口DMA接收

目录

01-仅接受一个数据

02-感悟


超级失败之作,文章好乱,去看我的新文章吧

DMA简述与使用实例-CSDN博客

失败原因:只关注了表面而不关注哪怕一丢丢深层的东西,所以写的东西没有意义

01-仅接受一个数据

思路:每次直接是一个数据,然后在通过在定时器中调用处理函数获取信息

以后修改内容:太零散了现在,要整理以下

打开中断

打开dma

修改串口号,直接塞进去

#define  huart_use_dma  huart3

#define UART1_PACK_SIZE			255	

coordinate_t coordinate_0;
//UART3单次接收到的数据长度(BYTEs)
uint16_t uart1_rx_size;
//UART3接收成功标志位
uint8_t uart1_rx_cplt_flag;
//UART3接收缓冲区
uint8_t uart1_rx_buf[UART1_PACK_SIZE];

  找到此函数,直接塞进去 

这是DMA服务函数,接收到数据回到这里面处理,若是接收到一阵数据(不再接收),就将里面的标志位置1,之后自定义的处理函数就可以在定时器终端中处理了。

/**
  * @brief This function handles USART3 global interrupt / USART3 wake-up interrupt through EXTI line 28.
  */
void USART3_IRQHandler(void)
{
  /* USER CODE BEGIN USART3_IRQn 0 */
	extern uint8_t uart1_rx_buf[UART1_PACK_SIZE];//16Byte
  extern uint16_t uart1_rx_size;
  extern uint8_t uart1_rx_cplt_flag;
	
  uint32_t tmp_flag = 0;
	uint32_t temp;
	tmp_flag =__HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE); //获取IDLE标志位
	if((tmp_flag != RESET))//idle标志被置位
	{ 
			__HAL_UART_CLEAR_IDLEFLAG(&huart3);//清除标志位
			
			HAL_UART_DMAStop(&huart3);
			temp  =  __HAL_DMA_GET_COUNTER(&hdma_usart3_rx);// 获取DMA中未传输的数据个数   
			uart1_rx_size =  sizeof(uart1_rx_buf) - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数
			uart1_rx_cplt_flag = 1;	// 接受完成标志位置1	
	}	
  /* USER CODE END USART3_IRQn 0 */
  HAL_UART_IRQHandler(&huart3);
  /* USER CODE BEGIN USART3_IRQn 1 */

  /* USER CODE END USART3_IRQn 1 */
}

直接塞进去

在while前调用

//UART3 中断接收使能
void uart1_dma_receive_enable(void)
{
			__HAL_UART_ENABLE_IT(&huart_use_dma, UART_IT_IDLE); //使能IDLE
			HAL_UART_Receive_DMA(&huart_use_dma,uart1_rx_buf, UART1_PACK_SIZE);
}

重新编写协议,塞进去就行

写处理函数

//UART1 接收数据处理函数
uint8_t uart1_receiveData_parse(void)
{
		uint8_t ret = 1;
		//如果接收到数据包
		if(uart1_rx_cplt_flag)
		{
				if(uart1_rx_buf[0] == 0x55 && uart1_rx_buf[1] == 0x52)
			//if(uart1_rx_buf[0] == 0x55)
				{
						//数据包通过校验
						ret = 0;
						//分析数据包
						coordinate_data_parse(&coordinate_0, uart1_rx_buf);
						//HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_7);
						HAL_GPIO_TogglePin(LED5_GPIO_Port,LED5_Pin);
				}
//				else if(uart1_rx_buf[0] == 0x55 && uart1_rx_buf[1] == 0x52)
//				{
//				}
				//清空数据包与标志位
				memset(uart1_rx_buf, 0, UART1_PACK_SIZE);
				uart1_rx_cplt_flag = 0;
				uart1_rx_size = 0;
				//重新打开DMA接收
				HAL_UART_Receive_DMA(&huart_use_dma,uart1_rx_buf, UART1_PACK_SIZE);
				//解包串口数据
				//coordinate_data_parse(&coordinate_0, uart1_rx_buf);
					
		}
		return ret;
}

在定时器中调用处理函数

02-感悟

在接受完一帧数据后,服务函数会将其置一,此时定时器中断中自定义的数据处理函数就可以进入了。但若是通过协议接收的数据,一帧应该分为若干次帧头,所以接受完数据应该注意一下,不能简单判断第0,1位,

解决方案1:

在处理函数中,将每一个数组每一位都读一遍,这样每个帧头都会会被发现,而不会被忽视

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值