OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4333|回复: 5

stm32F103 HAL库中串口空闲中断+DMA 无法进入中断

[复制链接]

1

主题

3

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2020-11-5
在线时间
15 小时
发表于 2021-1-28 19:08:59 | 显示全部楼层 |阅读模式
5金钱
新人在测试 HAL库中串口空闲中断+DMA 实现串口数据的不定长接收 时候,发现LED0不反转,即没办法进入USART1_IRQHandler
单独测试HAL_UART_Transmit(&huart1,(u8*)Read,8,0xffff)时候,发现可以正常收到数据

不知是初始化错误,还是中断代码有问题,麻烦各位大神提提建议


以下是程序,期望的功能是 通过串口调试助手向串口1发送不定长数据,将可以观察到数据返回,并打印出接收到数据的长度


int main()
{
      HAL_Init();
      Stm32_Clock_Init(RCC_PLL_MUL9);      
      delay_init(72);                       
    dma_init();
      LED_Init();
      uart_init(115200);  
      HAL_UART_Receive_DMA(&huart1, (uint8_t*)receive_buff, BUFFER_SIZE);
   
      HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USART1_IRQn);
    __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
    while(1)
    {
            
            //HAL_UART_Transmit(&huart1,(u8*)Read,8,0xffff);
            
            //HAL_Delay(500);
            
            
    }
}




UART_HandleTypeDef huart1; //UART¾ä±ú
DMA_HandleTypeDef hdma_usart1_rx;
extern uint8_t receive_buff[BUFFER_SIZE];  
u8 aRxBuffer[RXBUFFERSIZE];

//////////////////////////////////////////////////////////////////
#if 1
#pragma import(__use_no_semihosting)            
              
struct __FILE
{
    int handle;

};

FILE __stdout;      

void _sys_exit(int x)
{
    x = x;
}

int fputc(int ch, FILE *f)
{      
    while((USART1->SR&0X40)==0);
    USART1->DR = (u8) ch;      
    return ch;
}
#endif




#if EN_USART1_RX
void uart_init(u32 bound)
{

  USART_InitTypeDef USART_InitStructure;

  
    huart1.Instance=USART1;                       
    huart1.Init.BaudRate=bound;                    
    huart1.Init.WordLength=UART_WORDLENGTH_8B;   
    huart1.Init.StopBits=UART_STOPBITS_1;      
    huart1.Init.Parity=UART_PARITY_NONE;         
    huart1.Init.HwFlowCtl=UART_HWCONTROL_NONE;  
    huart1.Init.Mode=UART_MODE_TX_RX;            
    HAL_UART_Init(&huart1);                       
   
}

void dma_init(void)
{
   
    __HAL_RCC_DMA1_CLK_ENABLE();

  HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
   
   
}   

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{

    GPIO_InitTypeDef GPIO_Initure;
   
    if(huart->Instance==USART1)
    {
        __HAL_RCC_GPIOA_CLK_ENABLE();            
        __HAL_RCC_USART1_CLK_ENABLE();      
        __HAL_RCC_AFIO_CLK_ENABLE();
   
        GPIO_Initure.Pin=GPIO_PIN_9;            //PB10 TX
        GPIO_Initure.Mode=GPIO_MODE_AF_PP;      
        GPIO_Initure.Pull=GPIO_PULLUP;            
        GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(GPIOA,&GPIO_Initure);           

        GPIO_Initure.Pin=GPIO_PIN_10;            //PB11 RX
        GPIO_Initure.Mode=GPIO_MODE_AF_PP;        
        GPIO_Initure.Pull=GPIO_PULLUP;            
        GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(GPIOA,&GPIO_Initure);           
        
        hdma_usart1_rx.Instance = DMA1_Channel5;
    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.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_usart1_rx.Init.Mode = DMA_CIRCULAR;
    hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;

    __HAL_LINKDMA(huart, hdmarx, hdma_usart1_rx);
    }
}


void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)// 回调函数
{
    HAL_UART_DMAStop(&huart1);
   
    uint8_t data_length  = BUFFER_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);

    printf("Receive Data(length = %d): ",data_length);
    HAL_UART_Transmit(&huart1,receive_buff,data_length,0x200);
    printf("\r\n");

    memset(receive_buff,0,data_length);
    data_length = 0;
    HAL_UART_Receive_DMA(&huart1, (uint8_t*)receive_buff, BUFFER_SIZE);
}

void USART1_IRQHandler(UART_HandleTypeDef *huart)// 中断函数
{
   
  
    LED0=!LED0;
   

        if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))
        {
            __HAL_UART_CLEAR_IDLEFLAG(&huart1);
            printf("\r\nUART1 Idle IQR Detected\r\n");
            USAR_UART_IDLECallback(huart);
        }
   
}
#endif








最佳答案

查看完整内容[请看2#楼]

参考这个帖子:http://www.openedv.com/forum.php?mod=viewthread&tid=317086&extra=
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2021-1-28 19:09:00 | 显示全部楼层
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2020-11-5
在线时间
15 小时
 楼主| 发表于 2021-1-28 19:46:33 | 显示全部楼层
顶顶
回复

使用道具 举报

4

主题

87

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
250
金钱
250
注册时间
2019-5-11
在线时间
39 小时
发表于 2021-1-29 16:10:42 | 显示全部楼层
本帖最后由 ma3264175 于 2021-1-29 16:13 编辑

DMA的中断是单独的啊 怎么会进你的串口接收中断呢?你需要单独去配置DMA的中断,顺便说一句,DMA中断是在DMA完成之后才会响应的,而串口中断是 接收到一个字节就会响应。
DMA中断的 函数大概是 DMA1_ChanneX_IRQHandler  X-为CH
回复

使用道具 举报

9

主题

219

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1434
金钱
1434
注册时间
2020-5-12
在线时间
394 小时
发表于 2021-1-29 22:21:22 | 显示全部楼层
串口初始化有问题,还有只是用串口dma接受的话,可以不用dma中断
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2020-11-5
在线时间
15 小时
 楼主| 发表于 2021-1-31 23:11:16 | 显示全部楼层
Acuity 发表于 2021-1-28 19:09
参考这个帖子:http://www.openedv.com/forum.php?mod=viewthread&tid=317086&extra=

谢谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-10 10:22

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表