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

void NVIC_SetPendingIRQ (IRQn_t IRQn) 关于中断挂起函数

[复制链接]
ne93 提问时间:2018-3-5 18:52 /
芯片型号:STM32F103RE操作系统:FREERTOS
问题描述:
1.编码器计数时,硬件计数器记满一个周期(目前设置为10),会在TIM2中产生一个中断,进行进位
2.实现方式,先获取了硬件定时器中的数,再获取周期中的数,返回两者相加的值。计数值函数如下:
  1. u32  CCounter::getCounter_u32()
  2. {
  3.         return _counterTotal + TIM_GetCounter((TIM_TypeDef*)_timer->getTimx());//自动截取低32位
  4. }
复制代码
3.存在问题,先获取个位数时(正好是9),再获取十位数时(此时正好产生了一个进位中断),导致十位进一而个位仍然是9,最终该值比期望值小9
解决方案:
1.不使用中断而改用查询的方式(因为这是公司的框架,希望尽量少的改动代码)
2.考虑使用临界区保护。但发现freertos中临界区的优先级比TIM2低,无法挂起中断
3.考虑使用STM32自带的中断挂起函数void NVIC_SetPendingIRQ (IRQn_t IRQn) ,但目前发现该函数操作的寄存器ISPR虽然是32位,但赋值时只能使用16位,无法挂起该中断(TIM2为28)

关于挂起中断,void NVIC_SetPendingIRQ (IRQn_t IRQn)
  1. /**
  2. * @brief  Set the pending bit for an external interrupt
  3. *
  4. * @param  IRQn    The number of the interrupt for set pending
  5. *
  6. * Set the pending bit for the specified interrupt.
  7. * The interrupt number cannot be a negative value.
  8. */
  9. static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
  10. {
  11.     NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */
  12. }
复制代码
关于读取该中断挂起的状态,static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
  1. /**
  2. * @brief  Read the interrupt pending bit for a device specific interrupt source
  3. *
  4. * @param  IRQn    The number of the device specifc interrupt
  5. * @return         1 = interrupt pending, 0 = interrupt not pending
  6. *
  7. * Read the pending register in NVIC and return 1 if its status is pending,
  8. * otherwise it returns 0
  9. */
  10. static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
  11. {
  12.     return ((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F))) ? 1 : 0)); /* Return 1 if pending else 0 */
复制代码
测试代码时,发现只能设置和读取16位以下的数(但TIM2是28),不是官方表示的32位。
希望各位大大帮忙给下建议




官方编程手册中关于ISPR寄存器的说明

官方编程手册中关于ISPR寄存器的说明

中断和异常向量1

中断和异常向量1

中断和异常向量2

中断和异常向量2
收藏 1 评论7 发布时间:2018-3-5 18:52

举报

7个回答
ne93 回答时间:2018-3-5 18:54:13
萌新上路,希望各位大大出手相助
す疯Ⅱ恒す 回答时间:2018-3-8 09:30:23
为什么会先获取个位再获取十位呢?直接一次性全部读出来不可以么?一个32位的数可以表示很大了。

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

feixiang20 回答时间:2018-3-8 09:54:58
一个32位的数却只有16位的权力,看看你设置的是不是对,看看获取位是不是异常,我觉得还是参数的问题

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

x5y4z3 回答时间:2018-3-8 10:03:36
前来学习,这问题之前也遇过,当时也只能搁着没解决。
之后就忙新的案子去了,也不再捣鼓这问题了!~
无薪税绵 回答时间:2018-3-8 14:45:28
修改一下,计数值函数 CCounter::getCounter_u32() 。

在获取硬件读数值后,TIM_GetCounter((TIM_TypeDef*)_timer->getTimx())
对该值做处理,如果<9,数值按正常累加。
如果>9数值先加9,再累加,不就可以了吗?

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

wolfgang2015 回答时间:2018-3-8 16:04:09
问题的原因应该是TIM2的中断优先级太低了,其他中断的优先级高于这个TIM2中断。如果不是精度要求,用FreeRTOS的软件中断吧。

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

hippop 回答时间:2018-4-22 22:48:19
有两个解决方法:
1、读取计数之前关中断,读取结束再打开
2、先读取十位,再读取硬件的个位
     if (个位 < 5)
     {
         重新读取一次十位;
     }

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版