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

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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版