STM32
直播中

辛太励

8年用户 1161经验值
擅长:20153
私信 关注
[问答]

如何使用stm32CubeMX生成代码?

如何使用STM32CubeMX生成代码?

回帖(1)

王颖

2021-11-16 11:18:36
stm32f103芯片的串口一直使用DMA+空闲中断,现在使用stm32h7芯片,打算也使用相同的方法
芯片型号:stm32h743
串口:USART2
代码生成:stm32CubeMX
第一步:使用stm32CubeMX生成代码

第二步:添加自己代码


1.发生空闲中断需要reset DMA重新开始接收数据


HAL_StatusTypeDef HAL_UART_DMAStopRx(UART_HandleTypeDef *huart)
{
  /* Stop UART DMA Rx request if ongoing */
  if ((huart->RxState == HAL_UART_STATE_BUSY_RX) &&
      (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)))
  {
    CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);


    /* Abort the UART DMA Rx channel */
    if(huart->hdmarx != NULL)
    {
      HAL_DMA_Abort(huart->hdmarx);
    }


    //UART_EndRxTransfer(huart);
    /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
        CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
        CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);


        /* At end of Rx process, restore huart->RxState to Ready */
        huart->RxState = HAL_UART_STATE_READY;
  }


  return HAL_OK;
}


串口空闲中断


/**
  * @brief This function handles UART4 global interrupt.
  */
void USART2_IRQHandler(void)
{
        uint32_t _len_dmarev;
        uint32_t isrflags;
        uint32_t cr1its;
        BaseType_t xHigherPriorityTaskWoken;


       
        HAL_UART_IRQHandler(&UART2_Handler);
  
        isrflags   = READ_REG(UART2_Handler.Instance->ISR);
        cr1its     = READ_REG(UART2_Handler.Instance->CR1);


        if(((isrflags & USART_ISR_IDLE) != RESET) && ((cr1its & USART_CR1_IDLEIE) != RESET))
        {
                __HAL_UART_CLEAR_IDLEFLAG(&UART2_Handler);


                _len_dmarev = DMA_BUFFER_LENGTH -                                         __HAL_DMA_GET_COUNTER(UART2_Handler.hdmarx);


                if(_len_dmarev)
                {
                  //停止DMA
                  HAL_UART_DMAStopRx(&UART2_Handler);
                //这个地方非常关键,DMA访问的ram,但是CPU访问的是cache,使用下面函数使ram和cache一致
                 SCB_InvalidateDCache_by_Addr((uint32_t *)dma_rx_buf, DMA_BUFFER_LENGTH);
                 
                 xQueueSendToBackFromISR(Keyboard_Queue,(void*)&uart_to_keyboard_msg,&xHigherPriorityTaskWoken);
                 
                 portYIELD_FROM_ISR(xHigherPriorityTaskWoken);


                  HAL_UART_Receive_DMA(&UART2_Handler, dma_rx_buf, DMA_BUFFER_LENGTH);
                  __HAL_UART_DISABLE_IT(&UART2_Handler, UART_IT_ERR);
                  __HAL_UART_DISABLE_IT(&UART2_Handler, UART_IT_PE);
                }
          else
          {
                  READ_REG(UART2_Handler.Instance->RDR);
                  __HAL_UART_CLEAR_OREFLAG(&UART2_Handler);
          }


  }


}




unsigned int KeyboardRs485TxFrame(uint8_t * buffer,uint32_t len)
{
UINT16 i;


//拷贝数据到DMA buffer
for(i = 0; i < len; i++)
{
        dma_tx_buf = buffer;
}


//使发送RAM和cache一致
SCB_InvalidateDCache_by_Addr((uint32_t *)dma_tx_buf, DMA_BUFFER_LENGTH);
HAL_UART_Transmit_DMA(&UART2_Handler, dma_tx_buf, len);
return 0;


}


还有一点需要特别注意:DMA访问的是0x24000000以后区域,定义的发送和接收DMA buffer 一定要在这个区域
可使用下面的编译指令:
ALIGN_32BYTES(attribute((section (".RAM_D2"))) uint8_t dma_rx_buf[DMA_BUFFER_LENGTH]) ;
ALIGN_32BYTES(attribute((section (".RAM_D2"))) uint8_t dma_tx_buf[DMA_BUFFER_LENGTH]);
举报

更多回帖

×
20
完善资料,
赚取积分