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

【STM32F103疑问】定时器1比较输出产生2路脉冲

[复制链接]
helixwmonkey 提问时间:2014-4-10 18:40 /
找到原因了。但是没有全部解决。
对于我之前提出的问题,原因是:当产生了CC2中断,且正要进入程序段2时,此时发生了CC1中断。由于CC2IF是1,则TIM1_CC的中断悬停位不会被置一,此情况如下图所示:

5.png
然而当程序段2执行后,CC2IF标志被清除,则此时来了CC1中断后,TIM1_CC的中断悬停位会被再次置一。这也是为什么从来不会进入test=5的断点。
参见我的程序:
void TIM1_CC_IRQHandler(void)
{
        vu8 test=1;
        //程序段1
        if (TIM1_CC1IF)
        {
                TIM1_CC1IF = 0;
                CCR_Mask_x += CCR_Acc_x;
                TIM1->CCR1 = CCR_Mask_x;
        }
        //程序段2:
        if (TIM1_CC2IF)
        {
                TIM1_CC2IF = 0;
                CCR_Mask_y += CCR_Acc_y;
                TIM1->CCR2 = CCR_Mask_y;
        }
        //程序段3:
        if (1==TIM1_CC1IF)//6clk
        {
                if (NVIC_GetPendingIRQ(TIM1_CC_IRQn))
                {
                        test = 2;        //说明发生了CC1中断,且硬件自动置1了Pending位。这个断点有40%的机会进入//3clk
                }
                if (!NVIC_GetPendingIRQ(TIM1_CC_IRQn))//22clk
                {
                        test = 3;        //说明发生了CC1中断,但是硬件没有置一Pending位。这个断点也有40%的机会进入
                }
        }
        //程序段4:
        if (test==1 && TIM1_CC1IF==1)
        {
                if (NVIC_GetPendingIRQ(TIM1_CC_IRQn))
                {        
                        test = 4;        //说明发生了CC1中断,且硬件置1了Pending位。这个断点有20%的机会进入
                }
                if (!NVIC_GetPendingIRQ(TIM1_CC_IRQn))
                {
                        test = 5;        //★令人同样奇怪的是,这个断点不会进入★
                }
        }
}
因此,需要采取的措施是:在进入中断,对各个CCxIF做判断之前,必须一次性把TIM1->SR读取到内存变量,然后清零SR,然后根据内存变量来判断。
于是产生了新的问题:
ISR中,第一步先要读取寄存器SR到内存变量,第二步写SR为0,其间仍然有可能硬件改变SR,即:
6.png
于是我采用了流水线指令隔离ISB + 互斥访问LDREX/STREX来保护:
void TIM1_CC_ISR(void)
{
        vu8 test=0;
        u32 TIM1_SR_mask;
__TRY_:
        TIM1_SR_mask = __LDREXH(&(TIM1->SR));
        __asm("isb");
        TIM1->SR = 1;
        if (__STREXH(0,&(TIM1->SR)))
        {
                goto __TRY_;
        }
于是出现的新问题是:即使我在LDREX和STREX之间手动添加一个测试语句TIM1->SR = 1;,STREX的执行总是成功的。
是我使用LDREX和STREX有误吗?
各位大虾求指点啊。。


=============================分割线,以下是之前发的问题,上面的问题解决的当前进度=========================
遇到一个很诡异的问题
问题描述:
芯片:STM32F103 ZET6
工程中使用TIM1的CCR1和CCR2作为输出比较模式(在TIM1_CNT和TIM1_CCRx匹配时翻转电平,并触发TIM1_CC_IRQHandler中断进行处理,即使用TIM1来输出两路不同频率的脉冲信号来控制电机)。
当一个CCR2匹配的中断到来时,进入该中断后,TIM1_CC的中断悬停位自动被硬件清零;(注意CCR1和CCR2共用一个TIM1_CC中断)
★此时又来了CCR1匹配中断,此时按照Cortex-M3技术规范,硬件应该再次置一TIM1_CC的中断悬停位;★
然而在实际使用中(使用Keil MDK, JLink连接芯片进行调试,且工程使用了DBGMCU_Config(DBGMCU_TIM1_STOP, ENABLE);来保证Core进入断点后Timer1停止运行),发现此种情况下,(称之为情况①,即——由CCR2触发了中断,在中断处理程序TIM1_CC_ISR中又发生了CCR1匹配中断),硬件有时可以自动置一TIM1_CC的中断悬停位,有时却不可以,从而导致了程序将错过一次CCR1匹配中断,在实际使用中是一个严重的问题。
在此请教的问题是:如何设置,才能在情况①下,能够让硬件一定置一TIM1_CC的中断悬停位,从而保证CCR1引起的中断能够使得本次中断结束后立即被执行?或者说,这是STM32硬件本身的问题?
这里附上我特意编写的测试工程、测试截图、和详细说明。
 
TestPrj.rar (276.92 KB, 下载次数: 27)
收藏 评论4 发布时间:2014-4-10 18:40

举报

4个回答
回答时间:2014-4-11 14:08:23

RE:【STM32F103疑问】定时器1比较输出产生2路脉冲

TIM1_CC1F是一个自己定义的标志位吗?这段代码是在中断中跑的,还是在其他函数中跑的。
helixwmonkey 回答时间:2014-4-11 15:42:29

回复:【STM32F103疑问】定时器1比较输出产生2路脉冲

回复第 2 楼 于2014-04-11 14:08:23发表:
TIM1_CC1F是一个自己定义的标志位吗?这段代码是在中断中跑的,还是在其他函数中跑的。
对,TIM1_CC1F是一个位带定义,指向TIM1->SR的CC1F。这段代码是在中断里的。我那个工程是特意写出来可以直接测试用的。。要是方便的话可以帮忙看一下吗。。程序很短。
 
回答时间:2014-4-12 11:38:37

RE:【STM32F103疑问】定时器1比较输出产生2路脉冲

TIM1-SR只能由硬件产生,软件不能设置的。
helixwmonkey 回答时间:2014-4-12 16:00:30

回复:【STM32F103疑问】定时器1比较输出产生2路脉冲

回复第 4 楼 于2014-04-12 11:38:37发表:
TIM1-SR只能由硬件产生,软件不能设置的。
 
一语道破梦中人啊~ 多谢。
那有什么办法完成对TIM1_SR同时的读和写吗。
因为我需要在将SR读取到内存变量TIM1_SR_mask中,然后再清零SR,然而在这两个操作之间,硬件仍然会改变SR的值,则TIM1_SR_mask不能如实的反应SR的正真状态。且第二句话又清零了SR,这样SR将无法被还原。
 

 

所属标签

相似问题

官网相关资源

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