![shequ.stmicroelectronics.cn](./template/st_v1/static/img/logo2.png)
找到原因了。但是没有全部解决。 对于我之前提出的问题,原因是:当产生了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硬件本身的问题? 这里附上我特意编写的测试工程、测试截图、和详细说明。 ![]() |
STM32F103单片机PWM问题
STTM32F105 使用freertos,系统起来后,无法进入HAL_PWR_EnterSTOPMode休眠
STM32F103C8T6单片机PWM引脚输出问题
根据STM32芯片丝印二维码怎么知道芯片信息
DMA和GPIO外部中断异常
请问各位前辈 , stm32cubeIDE 烧录报错Error! Failed to read target status 错误!读取目标器状态失败 ,需要怎么解决
stm32 usart+dma
stm32f103 usb iap
STM32F103 ADC利用DMA进行采样问题求解
各位大佬,那位知道stm32cubeied报:函数声明了未被调用警告怎么解决?(函数声明只是oled的显示功能)函数并没有语法错误
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将无法被还原。