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

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
萌新上路,希望各位大大出手相助
疯de_恒 回答时间: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

查看全部评分

wolfgang 回答时间: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管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版