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