你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32的dma usart (hal)第一次能收到数据,一次不能收到

[复制链接]
ZONGZI 提问时间:2017-5-2 09:49 /
UART_HandleTypeDef UartHandle;
static DMA_HandleTypeDef hdma_tx;
static DMA_HandleTypeDef hdma_rx;   
void USART1_DMA_int(u32 BaudRate)
{
    UartHandle.Instance      = USART1;
    UartHandle.Init.BaudRate     = BaudRate;
    UartHandle.Init.WordLength   = UART_WORDLENGTH_8B;
    UartHandle.Init.StopBits     = UART_STOPBITS_1;
    UartHandle.Init.Parity       = UART_PARITY_NONE;
    UartHandle.Init.HwFlowCtl    = UART_HWCONTROL_NONE;
    UartHandle.Init.Mode         = UART_MODE_TX_RX;
    UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;


    if(HAL_UART_Init(&UartHandle) != HAL_OK)
    {
    }

}

void
        HAL_UART_MspInit(UART_HandleTypeDef *huart)
{

  GPIO_InitTypeDef  GPIO_InitStruct;
          {
    /******Enable peripherals and GPIO Clocks ***/
    /* Enable GPIO TX/RX clock */
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /* Enable USART1 clock */
    __HAL_RCC_USART1_CLK_ENABLE();
    /* Enable DMA2 Clock*/
    __HAL_RCC_DMA2_CLK_ENABLE();
    /**** Configure peripheral GPIO *****/  
    /* UART TX GPIO pin configuration  */
    GPIO_InitStruct.Pin       = GPIO_PIN_9;
    GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_InitStruct.Speed     = GPIO_SPEED_FAST;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART1;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* UART RX GPIO pin configuration  */
    GPIO_InitStruct.Pin = GPIO_PIN_10;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART1;

    HAL_GPIO_Init(GPIOA , &GPIO_InitStruct);


    ////////////////////////configure the DMA///////////////
    hdma_tx.Instance                 = DMA2_Stream7;  
    hdma_tx.Init.Channel             = DMA_CHANNEL_4;
    hdma_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
    hdma_tx.Init.PeriphInc           = DMA_PINC_DISABLE;   
    hdma_tx.Init.MemInc              = DMA_MINC_ENABLE;
    hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
    hdma_tx.Init.Mode                = DMA_NORMAL;
    hdma_tx.Init.Priority            = DMA_PRIORITY_LOW;
    hdma_tx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
    hdma_tx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
    hdma_tx.Init.MemBurst            = DMA_MBURST_INC4;
    hdma_tx.Init.PeriphBurst         = DMA_PBURST_INC4;

    HAL_DMA_Init(&hdma_tx);   

    /* Associate the initialized DMA handle to the the UART handle */
    __HAL_LINKDMA(huart, hdmatx, hdma_tx);

    /* Configure the DMA handler for Transmission process */
    hdma_rx.Instance                 = DMA2_Stream5;
    hdma_rx.Init.Channel             = DMA_CHANNEL_4;
    hdma_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
    hdma_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
    hdma_rx.Init.MemInc              = DMA_MINC_ENABLE;
    hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
    hdma_rx.Init.Mode                = DMA_NORMAL;
    hdma_rx.Init.Priority            = DMA_PRIORITY_HIGH;
    hdma_rx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;         
    hdma_rx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
    hdma_rx.Init.MemBurst            = DMA_MBURST_INC4;
    hdma_rx.Init.PeriphBurst         = DMA_PBURST_INC4;
    HAL_DMA_Init(&hdma_rx);

    /* Associate the initialized DMA handle to the the UART handle */
    __HAL_LINKDMA(huart, hdmarx, hdma_rx);

    /*Configure the NVIC for DMA*/
    /* NVIC configuration for DMA transfer complete interrupt (USARTx_TX) */
    HAL_NVIC_SetPriority(DMA2_Stream7_IRQn, 0, 2);
    HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);

    /* NVIC configuration for DMA transfer complete interrupt (USARTx_RX) */
    HAL_NVIC_SetPriority(DMA2_Stream5_IRQn, 0, 2);   
    HAL_NVIC_EnableIRQ(DMA2_Stream5_IRQn);

    /* NVIC configuration for USART TC interrupt */
    HAL_NVIC_SetPriority(USART1_IRQn, 0, 1);
    HAL_NVIC_EnableIRQ(USART1_IRQn);

    __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_IDLE);
    HAL_UART_Receive_DMA(&UartHandle, (uint8_t *)Uart1_RX_buffer, 150);

        }



}

void DMA2_Stream5_IRQHandler(void)
{
  HAL_DMA_IRQHandler(UartHandle.hdmarx);
}


void DMA2_Stream7_IRQHandler(void)
{
  HAL_DMA_IRQHandler(UartHandle.hdmatx);
}

void USART1_IRQHandler(void)
{
        UART_HandleTypeDef *huart=&UartHandle;
          uint32_t rx_len;
          uint32_t temp;
          
        if((__HAL_UART_GET_FLAG(&UartHandle,UART_FLAG_IDLE) != RESET))
          {
                __HAL_UART_CLEAR_IDLEFLAG(&UartHandle);
                temp = UartHandle.Instance->SR;  
                temp = UartHandle.Instance->DR;
                HAL_UART_DMAStop(&UartHandle);
                temp =  150 - hdma_rx.Instance->NDTR;        
                printf("rx_len interrupt =%d\r\n",temp);
                UartData.UART1_RXD_Flag=1;
                asm("nop");
                __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_IDLE);
                huart->hdmarx->State = HAL_DMA_STATE_READY;
                HAL_UART_Receive_DMA(&UartHandle, Uart1_RX_buffer,150);

        }
        HAL_UART_IRQHandler(&UartHandle);
       
}


void USART1_DMA_send(uint16_t Size)
{
  if(UartData.UART1_Send_Flag== 0)
          delay_ms(20);
  UartData.UART1_Send_Flag= 0;//清零标记 表示这次次发送未完成
  HAL_UART_Transmit_DMA(&UartHandle, Uart1_Send_Buffer,Size);


}

/*DMA发送完成中断回调函数*/
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
        __HAL_DMA_DISABLE(huart->hdmatx);
        UartData.UART1_Send_Flag=1;        //发送完成

}
现在遇到了这样一个问题,我在串口调试助手发送一组数据,第一次,就是接受不到但是要进空闲中断,第二次就能接受到数据,第三次有不能还是能进空闲中断,第四次有正常,依次类推,单数就有问题,双数就正常!!!哪个遇到过,帮我看看这个,谢谢,!!!!!!

DDDD.png
收藏 2 评论9 发布时间:2017-5-2 09:49

举报

9个回答
ZONGZI 回答时间:2017-5-2 10:27:44
又没人帮帮忙,看看呗!!
ZONGZI 回答时间:2017-5-2 14:11:26
同样的配置方式在USART2上面,也是同样的效果,我怀疑是不是HAL库函数那里需要适当的修改呢?有没大神帮忙看看!!感激不尽!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!每次发送数据都能进入中断,但是收到的数据的个数确实0,下次又正常!一次异常,一次正常!!!!
奏奏奏 回答时间:2017-5-2 15:25:22
你的DMA2,一个分配的是串口的发送,一个分配的是串口的接收。
接收收到数据,发送收不到是正常的呀。
没毛病呀
你首先要理解DMA是怎么用的
比如说一个分配的是AD1的第一个通道,一个分配的是AD1的第二个通道,这样用的呀
ZONGZI 回答时间:2017-5-3 08:38:52
学习了,我试试!!!
ZONGZI 回答时间:2017-5-3 10:05:37
奏奏奏 发表于 2017-5-2 15:25
你的DMA2,一个分配的是串口的发送,一个分配的是串口的接收。
接收收到数据,发送收不到是正常的呀。
没毛 ...

不是这个原因把,我用LL库还是DMA2的5和7就行,但是用HAL库就配置不到位!!!其实我就想用新库!新库我觉得一定有他好的地方,可是没用好!!
ZONGZI 回答时间:2017-5-8 08:44:00
撑下去啊!!!请高手解答哦了,相互学习!!
any012 回答时间:2017-5-8 09:21:29
帮顶,请教下,如何使用LL库?
ZONGZI 回答时间:2017-5-9 13:36:21
any012 发表于 2017-5-8 09:21
帮顶,请教下,如何使用LL库?

你可以看下正点原子的探索者407开发板的DMA串口!!就是用LL库
ZONGZI 回答时间:2017-5-15 17:19:54
帖子已经沉下去了,,,唉22222222222222222222222222222222222222222222222222222

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版