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的空闲中断,未找到原因)