hal库+rtos的串口空闲中断+DMA接收 分享

2019-07-20 01:01发布

hal库初学感觉好多没有标准库顺手,这个弄了一天,为了避免少走弯路,分享给大家。
基于F407,串口1,数据发送到串口,串口利用dma接收后产生中断,然后通过消息队列方式在线程中取出并再通过串口1返回。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
9条回答
绿洲
1楼-- · 2019-07-20 01:26
我的为什么不能进入空闲中断啊,无操作系统

/* USART3 init function */
void USART3_UART_Init(uint32_t bound)
{

  huart3.Instance = USART3;
  huart3.Init.BaudRate = bound;  //115200
  huart3.Init.WordLength = UART_WORDLENGTH_8B;
  huart3.Init.StopBits = UART_STOPBITS_1;
  huart3.Init.Parity = UART_PARITY_NONE;
  huart3.Init.Mode = UART_MODE_TX_RX;
  huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart3.Init.OverSampling = UART_OVERSAMPLING_16;
  HAL_UART_Init(&huart3);
  __HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);
}


void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  if(huart->Instance==USART3)
  {
  /* USER CODE BEGIN USART3_MspInit 0 */

  /* USER CODE END USART3_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_GPIOC_CLK_ENABLE();                        //使能GPIOC时钟
    __USART3_CLK_ENABLE();
  
    /**USART3 GPIO Configuration   
    PC10     ------> USART3_TX
    PC11     ------> USART3_RX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /* Peripheral interrupt init*/
    HAL_NVIC_SetPriority(USART3_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USART3_IRQn);
  /* USER CODE BEGIN USART3_MspInit 1 */

  /* USER CODE END USART3_MspInit 1 */
  }

}


void MYDMA_Config(DMA_Stream_TypeDef *DMA_Streamx,uint32_t chx)
{
        if((uint32_t)DMA_Streamx>(uint32_t)DMA2)//得到当前stream是属于DMA2还是DMA1
        {
        __HAL_RCC_DMA2_CLK_ENABLE();//DMA2时钟使能       
        }else
        {
        __HAL_RCC_DMA1_CLK_ENABLE();//DMA1时钟使能
        }

  /* DMA interrupt init */
  HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
  
  /* Peripheral DMA init*/
  hdma_usart3_rx.Instance = DMA_Streamx;                             //数据流选择
  hdma_usart3_rx.Init.Channel = chx;                                 //通道选择
  hdma_usart3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;              //存储器到外设
  hdma_usart3_rx.Init.PeriphInc = DMA_PINC_DISABLE;                  //外设非增量模式
  hdma_usart3_rx.Init.MemInc = DMA_MINC_ENABLE;                      //存储器增量模式
  hdma_usart3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;     //外设数据长度:8位
  hdma_usart3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;        //存储器数据长度:8位
  hdma_usart3_rx.Init.Mode = DMA_CIRCULAR;                           //外设循环模式
  hdma_usart3_rx.Init.Priority = DMA_PRIORITY_LOW;                   //低优先级
  hdma_usart3_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;               
  hdma_usart3_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;      
  hdma_usart3_rx.Init.MemBurst = DMA_MBURST_SINGLE;                  //存储器突发单次传输
  hdma_usart3_rx.Init.PeriphBurst = DMA_PBURST_SINGLE;               //外设突发单次传输
  HAL_DMA_DeInit(&hdma_usart3_rx);
  HAL_DMA_Init(&hdma_usart3_rx);

  __HAL_LINKDMA(&huart3,hdmarx,hdma_usart3_rx);  
  HAL_UART_Receive_DMA(&huart3,rx_buffer,BUFFER_SIZE);
}


void USART3_IRQHandler(void)
{
  /* USER CODE BEGIN USART3_IRQn 0 */
  uint32_t tmp_flag = 0;
        uint32_t temp;
  tmp_flag =  __HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE);
        if((tmp_flag != RESET))
  {
                        __HAL_UART_CLEAR_IDLEFLAG(&huart3);
                        temp = huart3.Instance->SR;  
                        temp = huart3.Instance->DR;
                        HAL_UART_DMAStop(&huart3);
                        temp  = hdma_usart3_rx.Instance->NDTR;
                        rx_len =  BUFFER_SIZE - temp;
                  recv_end_flag = 1;
                        HAL_UART_Receive_DMA(&huart3,rx_buffer,BUFFER_SIZE);
               
  }
绿洲
2楼-- · 2019-07-20 02:37
 精彩回答 2  元偷偷看……
zhen8838
3楼-- · 2019-07-20 02:48
 精彩回答 2  元偷偷看……
绿洲
4楼-- · 2019-07-20 04:52
zhen8838 发表于 2017-7-7 12:11
你要不先试试把我的程序初始化的部分拿去修改修改

初始化没啥问题啊
我是用串口助手给单片机随便发个东西就进入 USART3_IRQHandler(void)
然后__HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE)这个函数读取不到标志位

然后程序不停进入 USART3_IRQHandler 中断服务函数,继续检测不到__HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE)又退出中断服务函数,不停循环
zhen8838
5楼-- · 2019-07-20 08:30
绿洲 发表于 2017-7-7 15:01
初始化没啥问题啊
我是用串口助手给单片机随便发个东西就进入 USART3_IRQHandler(void)
然后__HAL_UART ...

是不是你的dma要设置为单次模式,不能设置为循环模式
正点原子
6楼-- · 2019-07-20 12:16
 精彩回答 2  元偷偷看……

一周热门 更多>