STM32WB55XX freertos 二值信号量+dma+idle 不定长串口接收 + dma传输完成中断

4 篇文章 0 订阅
4 篇文章 0 订阅

1、CUBE 配置

1.1硬件配置

在这里插入图片描述晶振配置
在这里插入图片描述系统时钟源配置 Tim1, systick给freertos用
在这里插入图片描述独立看门狗:预分频 32 喂狗超时 4095 个 分频后的周期数
在这里插入图片描述低功耗串口1 : 1、异步模式 2、开启全局中断
在这里插入图片描述低功耗串口1 : 添加 DMA
在这里插入图片描述时钟源选择

1.2 freertos 配置

添加串口任务
在这里插入图片描述
创建dma发送和接收的信号量
在这里插入图片描述

二、用户代码

如果使用信号量同步,要把使能空闲中断放在默认任务开头。
这样可以避免一种开机就死机的情况:
开启中断后串口在信号量初始化之前就收到一帧数据,
而在中断中释放的信号量还没有被创建。

void HalLpUartInit()
{
	if(HAL_OK != HAL_UART_Receive_DMA(&hlpuart1, g_lpUartRx.data, UART_RX_MAX))
		Error_Handler();
	__HAL_UART_ENABLE_IT(&hlpuart1, UART_IT_IDLE);
	__HAL_UART_ENABLE_IT(&hlpuart1, UART_FLAG_TC);
}
void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN StartDefaultTask */
  	HalLpUartInit();
	HAL_GPIO_TogglePin(GPIOA, LED_BLUE_Pin);
	osTimerStart(UI_TimerHandle, 500);
	//这里用printf会产生一个长度是0的空闲接收中断 后面打印正常
	//printf("Start Default Task!\r\n");
	LpUartTx(strlen("Start Default Task!\r\n"),(uint8_t *)"Start Default Task!\r\n");
	/* Infinite loop */
	for(;;)
	{
		HAL_IWDG_Refresh(&hiwdg);
		osDelay(1000);
	}
  /* USER CODE END StartDefaultTask */
}

串口任务

void LpUartTask(void *argument)
{
  /* USER CODE BEGIN LpUartTask */
  /* Infinite loop */
  for(;;)
  {
	  if(osOK == osSemaphoreAcquire(lpuartRxBinarySemHandle,osWaitForever))
	  {
		  printf("rx [%d]:",g_lpUartRx.size);
		  LpUartTx(g_lpUartRx.size, g_lpUartRx.data);
		  printf("\r\n");
	  }
  }
  /* USER CODE END LpUartTask */
}

dma发送

void LpUartTx(uint16_t len, uint8_t * buff)
{
	if(0 == len) 
		return;
	if(HAL_OK == osSemaphoreAcquire(lpuartTxBinarySemHandle,10))
		HAL_UART_Transmit_DMA(&hlpuart1, buff, len);
}

串口全局中断处理:1、空闲中断 2、DMA传输完成中断

void LPUART1_IRQHandler(void)
{
  /* USER CODE BEGIN LPUART1_IRQn 0 */
	uint32_t temp;
	uint32_t ret = taskENTER_CRITICAL_FROM_ISR();
    if(__HAL_UART_GET_FLAG(&hlpuart1,UART_FLAG_IDLE) != RESET)
    {
		HAL_UART_DMAStop(&hlpuart1);  
		temp = hlpuart1.hdmarx->Instance->CNDTR;  
		g_lpUartRx.size = UART_RX_MAX - temp;
		// starting uart dma rcv again
		HAL_UART_Receive_DMA(&hlpuart1, g_lpUartRx.data, UART_RX_MAX);  
		osSemaphoreRelease(lpuartRxBinarySemHandle);
		__HAL_UART_CLEAR_IDLEFLAG(&hlpuart1);
	}else if(__HAL_UART_GET_FLAG(&hlpuart1, UART_FLAG_TC) != RESET){
		osSemaphoreRelease(lpuartTxBinarySemHandle);
		__HAL_UART_CLEAR_TXFECF(&hlpuart1);
	}
  /* USER CODE END LPUART1_IRQn 0 */
  HAL_UART_IRQHandler(&hlpuart1);
  /* USER CODE BEGIN LPUART1_IRQn 1 */
	taskEXIT_CRITICAL_FROM_ISR(ret);
  /* USER CODE END LPUART1_IRQn 1 */
}

实验效果
在这里插入图片描述
(第一条打印用printf会产生接收长度为0的空闲中断,未找到原因)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值