stm32F407應用HAL_聊包養網心得UARTEx_RxEventCallback完成的uart數據接受不會被清算,一向累加怎么處理?

作者:

分類:

我正在應用STM32F407學些開闢stm32周遭的狀況,在調試u包養犯法嗎sart1的周遭的狀況中碰到了題目:我應用DMA+中止的方法來完成數據的收發,可是每次我應用串口東西發送雷同長度的數據過去,在HAL_UARTEx_RxEventCallback中止回調函數中發明size是在一向增添的,不會被清算,想就教在中止回調函數包養違法中怎么清算dma?貼上的的代碼完成:
UART_HandleTypeDef huart包養網車馬費1;#if 1#ifdef __GNUC__#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)#else#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)#endifPUTCHAR_PROTOTYPE{    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);    return ch;}#endif#define UART1_READ_BUF_SIZE     256#define RXBUFFERSIZE          256               /* 緩存鉅細 */static uint8_t g_rx_buffer[RXBUFFERSIZE];             /* HAL庫應用的串口接受緩沖 *//* USER CODE END 0 */DMA_HandleTypeDef hdma_usart1_rx;DMA_HandleTypeDef hdma_usart1_tx;static RingBufferStruct uart1_ring_buf;static mutex_handle_t uart1_mutex;static uint8_t uart1_read_buf[UART1_READ_BUF_SIZE];/* USART1 init function */void MX_USART1_UART_Init(uint32_t baud_rate){ /* USER CODE BEGIN USART1_Init 0 */ ring_buf_init(&uart1_ring_buf, uart1_read_buf, UART1_READ_BUF_SIZE); /* USER CODE END USART1_Init 0 */ /* USER CODE包養一個月 BEGIN USART1_Init 1 */ /* US蘭母聽得一愣,無語,半晌又問道:“還有什麼事嗎?”ER CODE END USART1_Init 1 */ huart1.Instance = USART1; huart1.Init.BaudRate = baud_包養apprate; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) {    Error_Handler(); } /*包養網評價 USER CODE BEGIN USART1_Init 2 */ HAL_UARTEx_ReceiveToIdle_DMA(&huart1, (uint8_t *)g_rx_buffer, RXBUFFERSIZE); osal_mutex_create(&uart1_mutex); /* USER CODE END USART1_Init 2 */}void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle){ GPIO_InitTypeDef GPIO_InitStruct = {0}; if(uartHandle->Instance==USART1) { /* USER CODE BEGIN USART1_MspInit 0 */ /* USER CODE END USART1_MspInit 0 */    /* USART1 clock enable */    __HAL_RCC_USART1_CLK_ENABLE();    __HAL_RCC_GPIOA_CLK_ENABLE();    /**USART1 GPIO Configuration    PA9   ——> USART1_TX    PA10   ——> USART1_RX    */    GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10“娘親,我婆婆雖然平易近人,和藹可親,但一點也不覺得自己是個平民,她的女兒在她身上能感受到一種出名的氣質。”;    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;    GPIO_InitStruct.Pull = GPIO_NOPULL;    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;    GPIO_InitStruct.Alternate = GPIO_AF7_USART1;    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);    /* USART1 D包養甜心網MA Init */    /* USART1_RX Init */    hdma_usart1_rx.Instance = DMA2_Stream2;    hdma_usart1_rx.Init.Channel = DMA_CHANNEL_4;    hdma_usart1_rx.Init.包養意思Direction = DMA_PERIPH_TO_MEMORY;    hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;    hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;    hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;    hdma_usart1_rx.Init.MemDataAlignmen包養網心得t = DMA_MDATAALIGN_BYTE;    hdma_usart1_rx.Init.Mode = DMA_NORMAL;    hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;    hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;    if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)    {     Error_Handler();    }    __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx);    /*台灣包養 USART1_TX Init */    hdma_usart1_tx.Instance = DMA2_Stream7;    hdma_包養網pptusart1_tx.Init.Channel = DMA_CHANNEL_4;    hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;    hdma_usar“所以我媽才說你平庸。”裴母忍不住對兒子翻了個白眼。 “既然我們家沒有什麼可失去的,那別人的目的是什麼,和我們t1_tx.Init.PeriphInc = DMA_PINC_DISABLE;    hdma_usart1_tx.Init.包養網單次MemInc = DMA_MINC_ENABLE;    hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;    hdma_usart1_tx.Init.Mem女大生包養俱樂部DataAlignment = DMA_MDATAALIGN_BYTE;    hdma_usart1_tx.Init.Mode = DMA_NORMAL;    hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;    hdma_usart1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;    if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)    {     Error_Handler();    }    __HAL_LINKDMA(uartHandle,hdmatx,hdma_usart1_tx);    /* USART1 interrupt Init */    H包養感情AL_NVIC_SetPriority(USART1_IRQn, 5, 0);    HAL_NVIC_EnableIRQ(USART1_IRQn); /* USER CODE BEGIN USART1_MspInit 1 */ /* USER CODE END USART1_MspInit 1 */ }}void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle){ if(uartHandle->Instance==USART1) { /* USER CODE BEGIN USART1_MspDeInit 0 */ /* USER CODE END USART1_MspDeInit 0 */    /* Peripheral clock disable */    __HAL_RCC_US包養甜心ART1_CLK_DISABLE();    /**USART1 GPIO Configuration    PA9   ——> USART1_TX    PA10   ——> USART1_RX    */    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN“別騙你媽。”_10);    /* USART1 DMA DeInit */    HAL_DMA_DeInit(uartHandle->hdmarx);    HAL_DMA_DeInit(uartHandle->hdmatx);    /* USART1 interrupt Deinit */    HAL_NVIC_DisableIRQ(USART1_IRQn); /* USER CODE BEGIN USART1_MspDeInit 1 */ /* USER CODE END USART包養網評價1_MspDeInit 1 */ }}/* USER CODE BEGIN 1 *//*包養軟體* * @brief      Rx傳輸回調函數 * @param      huart: UART句柄類型指針 * @retval     無 */包養留言板void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){    if(huart->Instance == USART1)    {    }}void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t size){    if (huart->Instance == USART1)    {包養軟體     HAL_UART_Transmit(&huart1, g_rx_buffer, size, 0xFFFF);     if (ring_uf_get_nused_size(&uart1_ring_buf) >= size)     {         ring_buf_put(&uart1_ring_buf, g_rx_buffer, size);     }     memset(g_rx_buffer, 0, size);     HAL_UARTEx_ReceiveToIdle_DMA(&huart1, (uint8_t *)g_rx_buffer, RXBUFFERSIZE);    }}uint32_包養感情t MX_USART1_UART_Send(const uint8_t *pdata, uint16_t size, uint32_t timeout){    return HAL_UART_Transmit(&huart1, pdata, size, timeout);}uint32_t MX_USART1_UART_Receive(const uint8_t *pData, uint16_t Size){    她欠她的丫鬟彩環和司機張舒的,她只能彌補他們的親人,而她的兩條命都欠她的救命恩人裴公子,除了用命來報答她,她真osal_mut包養sdex_lock(uart1_mutex);    uint16_t ret = ring_buf_get(&uart1_ring_包養平台buf, pData, Size);    osal_mutex_unlock(uart1_mutex);    return ret;}

• HAL_UARTEx_RxEventCallback函數無法在L0上挪用咋辦45包養dcard8
• STM32F407做一個USB聲卡,在Host灌音的時F407不會發送數據到Host是為什么279
在應用STM32F407的HAL庫停止UART通訊時,你提到在`HAL_UARTEx_RxEventCallback`回調函數中發明接受到的數據長度`size`一向在增添,這表白DMA緩沖區中的數據沒有被對的清算或重置。這凡是是由於DMA緩沖區沒有被從頭初始化或清空,招致每次接受到的數據都追加到緩沖區中。
### 處理方式
1. **在回調函數中從頭啟動DMA接受**:
   在`HAL_UARTEx_RxEventCallback`回調函數中,從頭啟動DMA接受,以便DMA緩沖區從頭開端接受數據。如許可以確保每次接受到的數據都是從緩沖區的肇端地位開端寫進。
   “`c
   void HAL_UARTEx_RxEventCallback(UART_Handl包養故事eTypeDef *huart, ui包養網站nt16_t Size)
   {
      if (huart->Instance == USART1)
      {
       // 處置接受到的數據
       // …
       // 從頭啟動DMA接受
       HAL_UARTEx_ReceiveToIdle_DMA(&huart包養行情1, (uint8_t*)your_buffe台灣包養r, BUFFER_SIZE);
      }
   }
   “`
2. **清空DMA緩沖區**:
   在從頭啟動DMA接受之前,可以手動清空DMA緩沖區,以確保沒有殘留數據。
   “`c
   void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
   {
      if (huart->Instance == USART1)
      {
       // 處置接受到的數據
       // …
       // 清空DMA緩沖區
       memset(your_buffer, 0, BUFFER_SIZE);
       // 從頭啟動DMA接受
       HAL_UARTEx_ReceiveToIdle_DMA(&huart1, (uint8_t*)your_buffer, BU包養平台FFER_SIZE);
      }
   }包養app
   “`
3. **確保DMA設置裝備擺設對的**:
   確保DMA設置裝備擺設對的,特殊是在包養pttDMA初始化時,DMA緩沖區的地址和鉅細要對的設置。
   “`c
   void MX_USART1_UART_Init(void)
   {
      // 設置裝備擺設USART1
      // …
      // 設置裝備擺設DMA
      hdma_usart1_rx.Instance = DMA2_Stream2;
      hdma_usart1_rx.Init.Channel = DMA_CHANNEL_4;
      hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
      hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
      hdma_usart1_rx.Ini包養站長t.MemInc = DMA_MINC_ENABLE;
      hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
      hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
      hdma_usart1_rx.Init.Mode = DMA_CIRCULAR;
      hdma_usart1_rx.Init.Priority = DMA_PRIORITY_HIGH;
      hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
      hdma_usart1_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
      hdma_usart1_rx.Init.MemBurst = DMA_MBURST_SINGLE;
      hdma_usart1_rx.Init.PeriphBurst = DMA_PBURST_SINGLE;
      HAL_DMA_Init(&hdma_usart1_rx);
      __HAL_LINKDMA(&huart1, hdmarx, hdma_usart1_rx);
      // 啟動DMA接受
      HAL_UARTEx_ReceiveToIdle_DMA(&huart1, (uint8_t*)your_buffer, BUFFER_SIZE);
   }
   “`
4. **檢討DMA形式**:
   假如你應用的是輪迴形式長期包養(`DMA_CIRCULAR`),DMA緩沖區會輪迴籠罩舊數據。假如你盼望每次接受到的數據都是自力的,可以斟酌應用非輪迴形式(`DMA_NORMAL`),并在每次接受完成后手動從頭啟動DMA。
   “`c
   hdma_usart1_rx.Init.Mode = DMA_NORMAL;
   “`
### 總結
經由過程在`HAL_UARTEx_RxEventC席世勳裝作沒看見,繼續說明今天的目的。 “今天肖拓除了來賠罪,主要是來表達自己的心意。肖拓不想和花姐解除婚約,allback`回調函數中從頭啟動DMA接受并清空緩沖區,可以確保每次接受到的數據都是從緩沖區的肇端地位開端寫進,從而防止數據累加的題目。同時,確保DMA設置裝備擺設對的,特殊是在DMA初始化時,DMA緩沖區的地址和鉅細要對的設置。
【冊本評測運動NO.57】芯片通識課:一本書讀懂芯片技巧 《芯片通識課:一本書讀懂芯片技巧》 體系地涵蓋了芯片範疇的各個方面,各章節內在的事務慎密相連,邏輯清楚,每一個常識點都顛末特別梳理和正確論述,為讀者浮現出一個完全、嚴謹的芯片常識系統。

檢查


模範氣力,智領將來——2024年度電子發熱友社區表揚 這一年,電子發熱友與生態廠商親密一起配合,搭建各個範疇技巧社區及廠商專區,如OpenHarmony技巧社區、RISC-V技巧社區、FPGA技巧社區,及龍芯技巧專區…

檢查


留言

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *