OpenEdv-开源电子网

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

STM32 串口接收中断与外部中断的优先级问题

[复制链接]

3

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
168
金钱
168
注册时间
2017-5-6
在线时间
44 小时
发表于 2019-12-18 12:50:57 | 显示全部楼层 |阅读模式
1金钱
硬件:STM32F103C8T6,外部中断4链接MPU6050模块的INT引脚,每5ms触发一次中断;串口2连接上位机,接收PC下发的控制指令。
需求:要求串口2的接收中断优先级高于外部中断4的优先级
代码:
1)STM32CubeMX中设置NVIC Group = 3 即 3 bits for pre-emption priority 1 bits for subpriority
2)串口2中断设置:
  • HAL_NVIC_SetPriority(USART2_IRQn, 1, 0);

[color=rgb(51, 102, 153) !important]复制代码



3) 外部中断4设置:
  • HAL_NVIC_SetPriority(EXTI4_IRQn, 3, 0);

[color=rgb(51, 102, 153) !important]复制代码

4)串口接收中断回调函数如下。作为测试,串口中断2的接收回调函数中,将接收到的字符有通过UART3发送出去。
  • void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  • {
  •         UNUSED(huart);
  •         if(huart->Instance == USART2)
  •         {
  •                 HAL_UART_Transmit(&huart3 , &aRxBuffer, 1, 0xFFFF);    //接收到的字符通过UART3回显
  •         }
  •         HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);   //再次开启uart2接收中断
  • }

[color=rgb(51, 102, 153) !important]复制代码

观察到的现象和问题:
1) 单独使能外部中断4,外部中断4工作正常
2) 单独使能串口2中断,串口2接收中断工作正常。PC连续下发多条指令都能正常接收并回显。
3) 同时使能外部中断4,串口2中断,发现:外部中断4仍能正常工作。但串口2接收中断仅能接收并回显开始的几个字符数据(长度随机)。后续再发送到串口2的字符均没进入接收中断,更没回显了。
4)出现3)中的状况后,再次disable掉外部中断4,仅保留串口中断,其它不变。此时串口中断又工作正常了。             5) 使能外部中断4。同时尝试设置UART3的抢占优先级低于UART2的抢占优先级,或不使能UART3的中断,现象都与3)中的相同。


    按前面的代码设置,串口2的抢占优先级是1,是高于外部中断4的抢占优先级3的。外部中断4应该不会影响串口2的中断。
   但观察的现象实际相反,请大家帮忙看看哪里弄错了。


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2019-12-19 01:41:17 | 显示全部楼层
感觉应该是你的中断分组设置没成功才对,继续看或者仿真调试下,看看结果
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

3

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
168
金钱
168
注册时间
2017-5-6
在线时间
44 小时
 楼主| 发表于 2019-12-19 13:45:20 | 显示全部楼层
正点原子 发表于 2019-12-19 01:41
感觉应该是你的中断分组设置没成功才对,继续看或者仿真调试下,看看结果

我也怀疑过是这个问题,用CubeMX生成的代码,直接在下面两个函数中设置的:
  1. HAL_NVIC_SetPriority(USART2_IRQn, 1, 0);
  2. HAL_NVIC_SetPriority(EXTI4_IRQn, 3, 1);
复制代码


函数 HAL_NVIC_SetPriority()的原型在 stm32f1xx_hal_cortex.c 文件中定义,相关片段如下。视乎没有设置分组???
  1. void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
  2. {
  3.   uint32_t prioritygroup = 0x00U;
  4.   
  5.   /* Check the parameters */
  6.   assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
  7.   assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
  8.   
  9.   prioritygroup = NVIC_GetPriorityGrouping();
  10.   
  11.   NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
  12. }

  13. // core_cm3.h
  14. #define NVIC_SetPriorityGrouping    __NVIC_SetPriorityGrouping
  15. #define NVIC_GetPriorityGrouping    __NVIC_GetPriorityGrouping

  16. #define NVIC_SetPriority            __NVIC_SetPriority

  17. __STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void)
  18. {
  19.   return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos));
  20. }

  21. __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
  22. {
  23.   if ((int32_t)(IRQn) >= 0)
  24.   {
  25.     NVIC->IP[((uint32_t)IRQn)]               = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
  26.   }
  27.   else
  28.   {
  29.     SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
  30.   }
  31. }

  32. __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
  33. {
  34.   uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);   /* only values 0..7 are used          */
  35.   uint32_t PreemptPriorityBits;
  36.   uint32_t SubPriorityBits;

  37.   PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
  38.   SubPriorityBits     = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));

  39.   return (
  40.            ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
  41.            ((SubPriority     & (uint32_t)((1UL << (SubPriorityBits    )) - 1UL)))
  42.          );
  43. }
复制代码


回复

使用道具 举报

3

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
168
金钱
168
注册时间
2017-5-6
在线时间
44 小时
 楼主| 发表于 2019-12-19 13:46:43 | 显示全部楼层
pkokoc 发表于 2019-12-19 13:45
我也怀疑过是这个问题,用CubeMX生成的代码,直接在下面两个函数中设置的:

有个默认的分组
uint32_t prioritygroup = 0x00U;
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2019-12-20 02:36:36 | 显示全部楼层
pkokoc 发表于 2019-12-19 13:46
有个默认的分组
uint32_t prioritygroup = 0x00U;

我靠,现在都是cube?
搞不定的时候,建议试试我们例程先吧
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

3

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
168
金钱
168
注册时间
2017-5-6
在线时间
44 小时
 楼主| 发表于 2019-12-20 12:12:10 | 显示全部楼层
正点原子 发表于 2019-12-20 02:36
我靠,现在都是cube?
搞不定的时候,建议试试我们例程先吧

初始化完成后,用下面的函数可获得当前的优先级分组。经测试,优先级分组设置是正确的,没有问题
  1. NVIC_GetPriorityGrouping()
复制代码
回复

使用道具 举报

3

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
168
金钱
168
注册时间
2017-5-6
在线时间
44 小时
 楼主| 发表于 2019-12-22 12:29:58 | 显示全部楼层
将UART2接收中断改为UART3接收中断,问题依旧。
看来还是中断设置的问题,还要进一步查找原因
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-21 07:58

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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