STM32高级定时器TIM1TIM8中断设置提醒

最近要用STM32F103RCT6的TIM8做输入捕获,网上不好找到可以直接搬运的代码,然后就移植TIM2的输入捕获做,然后一直遇到匪夷所思的问题!

出现的问题就是,在主函数进入while循环前配置好TIM8之后,进入主函数循环点灯测试,发现程序运行几百次循环后就自动停止了,感觉是跑飞了。一般程序跑飞很多情况下都是中断的部分没设置好,我也排查了问题出现的原因,基本确定就是中断的问题。

这里还有个情况值得提出来,但是我到现在也不知道原因所在:
就是 TIM_ICInitTypeDef TIM_ICInitStructure;
这个句柄放在哪的问题,正点的源码里面把这个放在了捕获定时器配置的函数外,说这个是全局变量,不放在外面的话也许会有问题。测试的时候在内在外确实不一样,放在函数里的话,程序运行几百次循环后就跑飞了,开始跑飞的时刻是固定的;放在函数外的话,大概是运行几千次循环后跑飞,开始跑飞的时刻也是固定的,就是比刚才晚了一会发生。
根据发生的时间,我大致计算了一下程序运行几百次循环后就跑飞对应发生的是什么情况,就是定时器发生更新中断的时刻。如果是因为中断配置的问题导致这种跑飞,那句柄写在外面为什么会推迟跑飞的时间呢?毕竟定时器计时又不会变。

上面这个问题留给有经验的人来解答,下面我说说经过检查后确定出中断配置哪里有问题。
原因就是高级定时器TIM1和TIM8配置时的一些宏定义和函数名有所不同,比如看这张图
在这里插入图片描述
我们可以发现,对于通用定时器TIM2TIM3,中断函数就只有类似TIMx_IRQn这样一个整体的;而对于高级定时器TIM1,对应于不同类型的中断,都有对应的中断服务函数,反而没有TIM1_IRQn,TIM8_IRQn这个东西。

在进行高级定时器的中断配置的时候,需要把不同中断类型分开配置,像这样

NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_IRQn;  //TIM8更新中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
NVIC_Init(&NVIC_InitStructure);  

NVIC_InitStructure.NVIC_IRQChannel =TIM8_CC_IRQn ;  //TIM8捕获中断
NVIC_Init(&NVIC_InitStructure);   

中断服务函数也要分开来写,函数名也一定要对应

void TIM8_CC_IRQHandler(void)   
{  
 if((TIM8CH3_CAPTURE_STA&0X80)==0)
{
if (TIM_GetITStatus(TIM8, TIM_IT_CC3) != RESET) 
	{	
		if(TIM8CH3_CAPTURE_STA&0X40)				
		{	  			
			TIM8CH3_CAPTURE_STA|=0X80;		
			TIM8CH3_CAPTURE_VAL=TIM_GetCapture3(TIM8);
	   		TIM_OC3PolarityConfig(TIM8,TIM_ICPolarity_Rising); 
		}else  							
		{
			TIM8CH3_CAPTURE_STA=0;			
			TIM8CH3_CAPTURE_VAL=0;
 			TIM_SetCounter(TIM8,0);
			TIM8CH3_CAPTURE_STA|=0X40;		
	   		TIM_OC3PolarityConfig(TIM8,TIM_ICPolarity_Falling);		
		}		    
	}
}
TIM_ClearITPendingBit(TIM8, TIM_IT_CC3);
}

void TIM8_UP_IRQHandler(void)  
{	if((TIM8CH3_CAPTURE_STA&0X80)==0)
{
if(TIM_GetITStatus(TIM8, TIM_IT_Update) != RESET)
{
		if(TIM8CH3_CAPTURE_STA&0X40)
		{
			if((TIM8CH3_CAPTURE_STA&0X3F)==0X3F)
			{
				TIM8CH3_CAPTURE_STA|=0X80;
				TIM8CH3_CAPTURE_VAL=0XFFFF;
			}else TIM8CH3_CAPTURE_STA++;
		}	
}	 
}	
	TIM_ClearITPendingBit(TIM8, TIM_IT_Update);
 }	

这样问题就解决了。从通用定时器移植过来的时候血泪教训

  • 15
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是stm32f103c8t6高级定时器TIM1定时中断示例代码: ``` #include "stm32f10x.h" void TIM1_UP_IRQHandler(void) { if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET) { // 在这里编写中断处理程序 TIM_ClearITPendingBit(TIM1, TIM_IT_Update); } } int main(void) { // 初始化TIM1 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); TIM_TimeBaseStructure.TIM_Period = 1000 - 1; // 计数器自动重装值 TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; // 时钟预分频数 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟分割 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 计数器计数模式 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE); // 允许更新中断 TIM_Cmd(TIM1, ENABLE); // 使能TIM1 // 初始化NVIC NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); while (1) { // 在这里编写主程序 } } ``` 该代码演示了如何使用stm32f103c8t6的高级定时器TIM1进行定时中断。在中断处理程序中,可以编写需要定时执行的代码。在主程序中,可以编写需要一直执行的代码。需要注意的是,该代码仅供学习,如果需要应用到实际项目中,需要根据具体需求进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值