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

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

[复制链接]
pkoko 提问时间:2019-12-18 11:37 /
硬件: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中断设置:
  1. HAL_NVIC_SetPriority(USART2_IRQn, 1, 0);
复制代码


3) 外部中断4设置:
  1. HAL_NVIC_SetPriority(EXTI4_IRQn, 3, 0);
复制代码
4)串口接收中断回调函数如下。作为测试,串口中断2的接收回调函数中,将接收到的字符有通过UART3发送出去。
  1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  2. {
  3.         UNUSED(huart);
  4.         
  5.         if(huart->Instance == USART2)
  6.         {
  7.                 HAL_UART_Transmit(&huart3 , &aRxBuffer, 1, 0xFFFF);    //接收到的字符通过UART3回显
  8.         }        
  9.         HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);   //再次开启uart2接收中断
  10. }
复制代码
观察到的现象和问题:
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的中断。
   但观察的现象实际相反,请大家帮忙看看哪里弄错了。






收藏 评论19 发布时间:2019-12-18 11:37

举报

19个回答
pkoko 回答时间:2019-12-20 00:32:11
mylovemcu 发表于 2019-12-19 08:31
你检查一下  是不是抢占优先级和响应优先级设置反了  现在实际设置的是响应优先级??
最好把响应优先级也 ...

1、抢占优先级,子优先级都是通过下面HAL_NVIC_SetPriority()这个函数设置的。该函数的代码如下(ST的原版代码),其中第2个参数就是抢占优先级,第3个参数是子优先级。CubeMX自动生成的代码就是这个函数设置,应该没有有错。
2、同时,也尝试了把UART2的优先级设置为 HAL_NVIC_SetPriority(USART2_IRQn, 1, 0);  把外部中断4优先级设置为 HAL_NVIC_SetPriority(EXTI4_IRQn, 3, 1);  这样无论如何,UART2的优先级都是高于外部中断4的。但是现象仍然依旧。
3、我使用的是STM32F103C8T6最小系统。为排除芯片问题,换了另一个最小系统模块。表现完全相同。应该不是芯片的问题。4、接下来考虑换一个UART试试,待测试后报告结果。

  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. }
复制代码

pkoko 回答时间:2019-12-18 21:09:22
tanic 发表于 2019-12-18 15:06
USART3只用了发送不需要接收,所以usart3中断无所谓。外部IO中断当然不会影响USART2。
问题原因在于USART2 ...

将UART2接收中断回调函数改为如下内容,把接收到的字节直接放到buffer中,然后在main()函数中回显。故障现象同上。感觉问题不在你说的这里。通过本次试验,更证实在同时使能外部4,UART2中断的时候,UART2并没有进入接收中断。
  1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  2. {
  3.         UNUSED(huart);
  4.         
  5.         if(huart->Instance == USART2)
  6.         {
  7.             tmp_buffer[tmp_count++] = aRxBuffer;   、//接收到的字节放入buffer
  8.         }        
  9.         HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);   //再次开启uart2接收中断
  10. }
复制代码

pkoko 回答时间:2019-12-18 21:23:08
tanic 发表于 2019-12-18 15:06
USART3只用了发送不需要接收,所以usart3中断无所谓。外部IO中断当然不会影响USART2。
问题原因在于USART2 ...

    将UART2接收回调函数改为如下内容。中断接收到的字节直接放到buffer中。在main()函数中进行回显。故障现象与上面的相同,并未发生改变。
     这个试验跟进一步观察到并证实,在同时使能外部中断4,UART2中断的时候,并未进入UART2的接收中断。
   
  1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  2. {
  3.         UNUSED(huart);
  4.        
  5.         if(huart->Instance == USART2)
  6.         {
  7.             tmp_buffer[tmp_count++] = aRxBuffer;   、//接收到的字节放入buffer
  8.         }       
  9.         HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);   //再次开启uart2接收中断
  10. }
复制代码
奏奏奏 回答时间:2019-12-18 11:50:41
这种情况下只能设置同样的中断优先级,自己另外用软件处理使串口2优先级高
举例,比如说进入串口中断2后立即关闭外部中断4,串口中断2运行结束后再打开外部中断4
类似这样的处理来解决。
pkoko 回答时间:2019-12-18 11:55:28
奏奏奏 发表于 2019-12-18 11:50
这种情况下只能设置同样的中断优先级,自己另外用软件处理使串口2优先级高
举例,比如说进入串口中断2后立 ...

谢谢回复。是一种思路,我试试看。
不过我希望的是外部中断一直进行。当通过串口下发数据时,能自动中断外部中断。
mylovemcu 回答时间:2019-12-18 14:00:33
将两种中断同时使能的情况下,外部中断4的中断先断开(不是禁止中断),硬件上断开INT引脚,再进行试验,看一下串口2工作正常不  
如果正常  问题出在优先级上  
如果还是不正常  那就是引脚配置有问题  查一下
个人认为第二种可能性大一些  也可以仿真查一下问题
tanic 回答时间:2019-12-18 15:06:01
USART3只用了发送不需要接收,所以usart3中断无所谓。外部IO中断当然不会影响USART2。
问题原因在于USART2接收中断不断触发,USART3发送会被新的USART2接收中断打断,huart3句柄内部的buffer内容被修改,导致丢失数据。huart3是全局变量,HAL_UART_Transmit不可重入
pkoko 回答时间:2019-12-18 22:10:21
mylovemcu 发表于 2019-12-18 14:00
将两种中断同时使能的情况下,外部中断4的中断先断开(不是禁止中断),硬件上断开INT引脚,再进行试验,看 ...

测试了,情况如下:
    软件上同时使能外部中断4、UART2中断。硬件上断开INT引脚,即外部中断4实际上无触发信号输入,未实际产生中断。此时UART2能正常进入中断,可正常接收。
    总结这几种情况:在同时使能外部中断4、UART2中断。设置UART2抢占中断优先级高于外部中断4优先级。低优先级的外部中断4工作正常,高优先级的UART2反倒不正常???
   与你讲的第一种情况相同,问题还是出在中断上。
mylovemcu 回答时间:2019-12-19 08:31:15
pkoko 发表于 2019-12-18 22:10
测试了,情况如下:
    软件上同时使能外部中断4、UART2中断。硬件上断开INT引脚,即外部中断4实际上无 ...

你检查一下  是不是抢占优先级和响应优先级设置反了  现在实际设置的是响应优先级??
最好把响应优先级也设置不一样的  串口2设置高优先级
Ankky 回答时间:2019-12-19 15:23:51
这个很不科学,有可能是HAL库的Bug
爱电子辉辉 回答时间:2019-12-19 18:38:49
TIM图片20191219183612.png
楼主,你看,是不是这个原因,选择PA4的时候,串口2哪里出现了警告。。
pkoko 回答时间:2019-12-20 00:14:46
爱电子辉辉 发表于 2019-12-19 18:38
楼主,你看,是不是这个原因,选择PA4的时候,串口2哪里出现了警告。。
...

选择UART2,实际只使用了 PA2(USART2_TX)、PA3(USART2_RX)两个引脚。PA4引脚的功能之一是UART2_CK,当将PA4的功能设置为UART2_CK时,不会出现“黄色三角感叹号”。
而当将PA4重映射为其它功能时,比如GPIO_EXIT4 或 GPIO_input 都会出现这个提示。应该是正常的。
pkoko 回答时间:2019-12-22 12:27:30
pkoko 发表于 2019-12-20 00:32
1、抢占优先级,子优先级都是通过下面HAL_NVIC_SetPriority()这个函数设置的。该函数的代码如下(ST的原版 ...

将UART2接收中断改为UART3接收中断,问题依旧。
看来还是中断的问题。还要进一步找原因
radio2radio 回答时间:2019-12-22 15:16:51
我估计是,你MPU6050每5ms触发一次+传送大量数据(不知道你的I2C速度是多少?硬件I2C?),已经搞到CPU很繁忙,可以用示波器看一看你到底还有多少CPU的空闲时间。
可以试一试,把UART Rx 的缓存搞大一些,在每一次5ms的间隙里面检查一下UART缓存有没有收到的指令。
12下一页

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版