关于STM32多个定时器同时使用

憨厚的豌豆荚 2019-12-30 01:42:59
现在是用了两个定时器
TIM5用来发脉冲
TIM3是1ms的定时,每隔1ms去修改TIM5的ARR值,感觉设置的都正确,但是实际测试发的脉冲个数不对,
后来改成TIM3定时0.1ms,有改善,这样的到底要怎么处理呢?请问是什么原因呢?

TIM3的初始化
void MX_TIM3_Init(void)     // 1ms
{
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;
htim3.Instance = TIM3;
htim3.Init.Prescaler = 0;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 83999;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
__HAL_TIM_ENABLE(&htim3);
}


TIM5的初始化
/*  84M*/
void MX_TIM5_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;

htim5.Instance = TIM5;
htim5.Init.Prescaler = 0;
htim5.Init.CounterMode = TIM_COUNTERMODE_UP;
htim5.Init.Period = Tim5_CCR/init_speed-1;
htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
if (HAL_TIM_Base_Init(&htim5) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim5, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
__HAL_TIM_ENABLE(&htim5);
TIM5 ->CR1 |= 0x0080;

}


TIM3中断函数
void TIM3_IRQHandler(void)
{
CPU_IntDis(); //CPU_CRITICAL_ENTER;
OSIntEnter();
HAL_TIM_IRQHandler(&htim3);
TIM3->ARR = 83999;
{
if(speed_up1==1)
{
if(vx1<speed_max)
{
vx1 += (float)slope_val/1000;
if(vx1>speed_max)
{
vx1 = speed_max;
speed_up1 = 0;
}
timer5ARR = Tim5_CCR/vx1;
}
}
if(speed_down1==1)
{
if(vx1>cutoff_speed)
{
vx1 -= (float)slope_val/1000;
if(vx1<=cutoff_speed)
{
vx1 = cutoff_speed;
speed_down1 = 0;
MOTOR_mov_flag = 0;
}
timer5ARR = Tim5_CCR/vx1;
}
}
}
CPU_IntEn();
OSIntExit();
}


TIM5中断函数
void TIM5_IRQHandler(void)
{
CPU_IntDis(); //CPU_CRITICAL_ENTER;
OSIntEnter();
{
HAL_TIM_IRQHandler(&htim5);
TIM5->ARR = timer5ARR;
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_1);
turns_pulse_nums++;

if(MOTOR_mov_flag)
{
if(turns_pulse_nums>=distance_R*8)
{
MOTOR_mov_over = 1;
speed_down1 = 1;
MOTOR_mov_flag = 0;
}
}
}
CPU_IntEn();
OSIntExit();
}


...全文
7205 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_33787896 2021-05-21
  • 打赏
  • 举报
回复
STM32多定时同时中断,使用72M主频,确实很难调试,我项目里需要0.1ms,1ms,10ms三个定时器同时中断工作,很难搞定,0.1ms稳定,1ms和10ms定时器就经常被串扰,通过改变中断优先级没有改善,如果中断优先级设置不当,Main程序都不能工作,项目还要加上一路PWM,2路输入捕获和一路比较输出(相位可调),和6路16阶FIR滤波器,很难调试出来。之前用HCS12单片机(16位芯片,12M工作频率),已经实现上述功能。有STM32解决方案的专家欢迎联系。
憨厚的豌豆荚 2020-01-02
  • 打赏
  • 举报
回复
只是我的定时器配置错了,越界了
xuyaqi029 2019-12-30
  • 打赏
  • 举报
回复
引用 7 楼 bdjinger 的回复:
就是在main函数的while里面,根据计时标志,同时处理两个?我这是个多任务的,是不是可以单独在一个任务里加减速?
你可以试一下单独在一个任务里加减速。
xuyaqi029 2019-12-30
  • 打赏
  • 举报
回复
引用 11 楼 bdjinger 的回复:
引用 10 楼 xuyaqi029 的回复:
[quote=引用 8 楼 bdjinger 的回复:] [quote=引用 6 楼 xuyaqi029 的回复:]而且计算间隔完全可以10ms一次
另外我还是想问问像目前这样在定时器里面,究竟是什么原理不行呢?
是中断间隔太短,中断处理内容又太多,cpu没时间干别的。[/quote]就是说光进TIM3中断计算去了,没有来得及去发脉冲。可是我要是去任务里面计算的话,任务切换大概10ms,有时候会来不及。[/quote] 那就20ms算一次
憨厚的豌豆荚 2019-12-30
  • 打赏
  • 举报
回复
引用 10 楼 xuyaqi029 的回复:
引用 8 楼 bdjinger 的回复:
[quote=引用 6 楼 xuyaqi029 的回复:]而且计算间隔完全可以10ms一次
另外我还是想问问像目前这样在定时器里面,究竟是什么原理不行呢?
是中断间隔太短,中断处理内容又太多,cpu没时间干别的。[/quote]就是说光进TIM3中断计算去了,没有来得及去发脉冲。可是我要是去任务里面计算的话,任务切换大概10ms,有时候会来不及。
xuyaqi029 2019-12-30
  • 打赏
  • 举报
回复
引用 8 楼 bdjinger 的回复:
引用 6 楼 xuyaqi029 的回复:
而且计算间隔完全可以10ms一次
另外我还是想问问像目前这样在定时器里面,究竟是什么原理不行呢?
是中断间隔太短,中断处理内容又太多,cpu没时间干别的。
憨厚的豌豆荚 2019-12-30
  • 打赏
  • 举报
回复
引用 6 楼 xuyaqi029 的回复:
而且计算间隔完全可以10ms一次
就是在main函数的while里面,根据计时标志同时处理两个的加速?还有我这是多任务的,是不是可以在一个任务里面处理加减速?
憨厚的豌豆荚 2019-12-30
  • 打赏
  • 举报
回复
引用 6 楼 xuyaqi029 的回复:
而且计算间隔完全可以10ms一次
另外我还是想问问像目前这样在定时器里面,究竟是什么原理不行呢?
憨厚的豌豆荚 2019-12-30
  • 打赏
  • 举报
回复
就是在main函数的while里面,根据计时标志,同时处理两个?我这是个多任务的,是不是可以单独在一个任务里加减速?
xuyaqi029 2019-12-30
  • 打赏
  • 举报
回复
而且计算间隔完全可以10ms一次
xuyaqi029 2019-12-30
  • 打赏
  • 举报
回复
你不用在定时器(TIM3)中断里面计算ARR的值,在中断外用ms标志算,加减速对时间要求没那么严格。
憨厚的豌豆荚 2019-12-30
  • 打赏
  • 举报
回复
引用 3 楼 xuyaqi029 的回复:
你把你两路脉冲的要求说明一下。
其实就是给两个电机驱动的,最大频率是48K,占空比是50%,然后两个电机需要缓起缓停,所以在电机刚启动的时候脉冲频率是逐渐增加的,在电机需要停止时是逐渐停止的。然后一个电机的缓起和另一个电机的缓停是重合的。就是一个进行缓起的同时另一个开始缓停。 以前都是控制一个电机,弄个while循环写缓起缓停,但是现在两个的缓起缓停是重合,两个while肯定不行,就在一个定时器(TIM3)里面计算ARR的值,另外两个定时器(TIME2和TIME5)发脉冲 TIME3中断程序如下
void TIM3_IRQHandler(void)
{
    CPU_IntDis();   //CPU_CRITICAL_ENTER;
    OSIntEnter();
    HAL_TIM_IRQHandler(&htim3);
		TIM3->ARR = 8399;
//		if(sysclock_flag==1)
		{
			if(speed_up1==1)
			{		
				if(vx1<speed_max)
				{
					vx1 += (float)slope_val/10000;
					if(vx1>speed_max)
					{
							vx1 = speed_max;
							speed_up1 = 0;
					}
					timer5ARR = Tim5_CCR/vx1;		
				}		
			}	
			if(speed_down1==1)
			{
				if(vx1>cutoff_speed)
				{
					vx1 -= (float)slope_val/10000;
					if(turns_pulse_nums>=(distance*8))
					{
						speed_down1 = 0;				
					}
					if(vx1<=cutoff_speed)
					{
						vx1 = cutoff_speed;
						speed_down1 = 0;
					}
					timer5ARR = Tim5_CCR/vx1;	
				}				
			}
			if(speed_up2==1)
			{
				if(vx2<speed_max)
				{
					vx2 += (float)slope_val/10000;
					if(vx2>speed_max)
					{
							vx2 = speed_max;
							speed_up2 = 0;
					}
					timer4ARR = Tim4_CCR/vx2;		
				}				
			}
			if(speed_down2==1)
			{
				if(vx2>cutoff_speed)
				{
					vx2 -= (float)slope_val/10000;
					if(turns_pulse_nums2 >= distance*8)  
					{
						speed_down2 = 0;
					}
					if(vx2<=cutoff_speed)
					{
						vx2 = cutoff_speed;
						speed_down2 = 0;
					}
					timer4ARR = Tim4_CCR/vx2;	
				}	
			}
		}
    CPU_IntEn();
    OSIntExit();
}
xuyaqi029 2019-12-30
  • 打赏
  • 举报
回复
你把你两路脉冲的要求说明一下。
憨厚的豌豆荚 2019-12-30
  • 打赏
  • 举报
回复
引用 1 楼 xuyaqi029 的回复:
每隔1ms去修改TIM5的ARR值,中断是否太频繁,能否改改思路。
可是我后面改为每0.1ms修改了,反而觉得效果好很多,基本能实现我想要的功能了。 这样修改过于频繁的话,是会有什么影响吗? 要同时发两路脉冲,并且脉冲频率是变化的,目前还没有想到别的方案
xuyaqi029 2019-12-30
  • 打赏
  • 举报
回复
每隔1ms去修改TIM5的ARR值,中断是否太频繁,能否改改思路。

27,518

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧