
找到原因了。但是没有全部解决。 对于我之前提出的问题,原因是:当产生了CC2中断,且正要进入程序段2时,此时发生了CC1中断。由于CC2IF是1,则TIM1_CC的中断悬停位不会被置一,此情况如下图所示: ![]() 然而当程序段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,即: ![]() 于是我采用了流水线指令隔离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硬件本身的问题? 这里附上我特意编写的测试工程、测试截图、和详细说明。 ![]() |
stm32f407无法配置定时器2为全部dma
STM32F103TBU6 封装是VFQFPN36 将PD0和PD1配置成CAN不成功是什么原因
串口DMA + 空闲中断收发 ?
F103RCT6芯片对AFIO->MAPR寄存器写入时出错
使用STM32捕获PWM时同时捕获2个通道时会出现捕获的频率值不准确的问题
WS2812B怎么显示任意字符 / 图案?
STM32F103RCT6 定位孔 镂空,会影响使用吗?
HAL库1.8.4在做破坏性测试的时候出现g_state永远为busy的情况导致串口通信发送卡死
L9663驱动开发
用rt_thread 环境编写,DAP-LINK 下载烧录,每一次空芯片下载之后就无法二次下载。求解
RE:【STM32F103疑问】定时器1比较输出产生2路脉冲
回复:【STM32F103疑问】定时器1比较输出产生2路脉冲
TIM1_CC1F是一个自己定义的标志位吗?这段代码是在中断中跑的,还是在其他函数中跑的。
对,TIM1_CC1F是一个位带定义,指向TIM1->SR的CC1F。这段代码是在中断里的。我那个工程是特意写出来可以直接测试用的。。要是方便的话可以帮忙看一下吗。。程序很短。
RE:【STM32F103疑问】定时器1比较输出产生2路脉冲
回复:【STM32F103疑问】定时器1比较输出产生2路脉冲
TIM1-SR只能由硬件产生,软件不能设置的。
一语道破梦中人啊~ 多谢。
那有什么办法完成对TIM1_SR同时的读和写吗。
因为我需要在将SR读取到内存变量TIM1_SR_mask中,然后再清零SR,然而在这两个操作之间,硬件仍然会改变SR的值,则TIM1_SR_mask不能如实的反应SR的正真状态。且第二句话又清零了SR,这样SR将无法被还原。