STM32F407定时器的应用

本文介绍STM32F407定时器的基础配置与多种工作模式,包括自动重载寄存器、预分频器寄存器及计数器寄存器的功能。同时探讨了定时器在不同模式下的启动与停止方法,并详细说明了定时器在微型步进电机控制、PWM信号生成、输入捕获和编码器模式中的具体应用。

STM32F407定时器的应用

定时器基础常识

自动重载寄存器(TIMx_ARR)

自动重载寄存器是预装载的。对自动重载寄存器执行写入或读取操作时会访问预装载寄存 器。预装载寄存器的内容既可以直接传送到影子寄存器,也可以在每次发生更新事件 (UEV) 时传送到影子寄存器,这取决于 TIMx_CR1 寄存器中的自动重载预装载使能位 (ARPE)。当 计数器达到上溢值(或者在递减计数时达到下溢值)并且 TIMx_CR1 寄存器中的 UDIS 位为 0 时,将发送更新事件。该更新事件也可由软件产生。下文将针对各配置的更新事件的产生 进行详细介绍。

image-20211031103155568

预分频器寄存器(TIMx_PSC)

预分频器可对计数器时钟频率进行分频,分频系数介于 1 到 65536 之间。该预分频器基于16 位/32 位寄存器(TIMx_PSC 寄存器)所控制的 16 位计数器。由于该控制寄存器具有缓冲功能,因此预分频器可实现实时更改。而新的预分频比将在下一更新事件发生时被采用。

image-20211031103133894

计数器寄存器(TIMx_CNT)

依据定时器频率和预分频器的分频得到的频率计数,是定时器计时计数的体现。

 __HAL_TIM_GetCounter(&htim2);//获取计数器值
 __HAL_TIM_SetCounter(&htim2,0);//设置计数器值

定时器打开方式

轮询方式启动/停止

HAL_TIM_xxx_Start
HAL_TIM_xxx_Stop

中断方式启动/停止

HAL_TIM_xxx_Start_IT
HAL_TIM_xxx_Stop_IT

DMA方式启动/停止

HAL_TIM_xxx_Start_DMA
HAL_TIM_xxx_Stop_DMA

定时中断控制微型步进电机

image-20211031104554555

配置内部时钟源定时器,预分频系数71,重新装载值999,实现一微秒触发一次中断。

void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  GPIOx->ODR = PortVal;
}//利用一组io设置寄存器实现电机控制波形
//步进电机正反转数组1
uint16_t phasecw[4] ={0x0010,0x0020,0x0040,0x0080};// D-C-B-A   
uint16_t phaseccw[4]={0x0080,0x0040,0x0020,0x0010};// A-B-C-D.
int a=0,i=0,c=0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{ 
	if(htim->Instance == TIM2)
	{
		a++;
		if(flag==0)
    { 
			i=a%4;
			GPIO_Write(GPIOB,phasecw[i]); 	
		}
		else if(flag==1)
     {		 
	  	i=a%4;
			GPIO_Write(GPIOB,phasecw[i]); 		 
		 }
    if(i==3)c++;		
	}	
}//定时器中断回调函数
void Motor(int  FLAG,int speed)  
{  
  flag =FLAG;
	__HAL_TIM_SET_AUTORELOAD(&htim2,speed-1);
}//步进电机转速控制函数
void Motor_angle(int  FLAG,int angle,int speed)
{
  flag =FLAG;
	__HAL_TIM_SET_AUTORELOAD(&htim2,speed-1);
	int j;
  j=(int)(angle/0.70312);
	if(c>=j)
	{
  HAL_TIM_Base_Stop_IT(&htim2);
	  GPIO_Write(GPIOB,0x0000);  	
	}
}//电机旋转角度控制
  HAL_TIM_Base_Start_IT(&htim2);//以中断方式使能定时器2
  Motor(0,1500) ; //设置电机转速
  Motor_angle(0,90,3000);//指令电机正反转,转动角度,转动速度

PWM控制舵机

image-20211102113106985

输入捕获

捕获方波周期

image-20211102115608769

int value=0;
int value_old=0;
int value_e=0;

  HAL_TIM_IC_Start_IT (&htim2,TIM_CHANNEL_1);

	void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{	
	if(TIM2 == htim->Instance)
	{
		value=HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1); 
		value_e=value-value_old;
    value_old=value;
	}
}//不要忘记打开定时器的中断

捕获PWM占空比

image-20211102122559395

uint32_t capture_Buf[4] = {0};  //存放计数值
uint32_t capture_Buf0[4] = {0};  //存放计数值
uint8_t capture_Cnt[4] = {0}; //状态标志位
uint32_t high_time[4]; //高电平时间
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	
	if(TIM2 == htim->Instance)
	{
		switch(capture_Cnt[0])
		{
			case 1:
				capture_Buf[0] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//获取当前的捕获值.
				__HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);  //设置为下降沿捕获
				capture_Cnt[0]++;
				break;
			case 2:
				capture_Buf0[0] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//获取当前的捕获值.
				HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_1); //停止捕获   或者: __HAL_TIM_DISABLE(&htim5);
				capture_Cnt[0]++;    
		}
	}
}

HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);

  switch (capture_Cnt[0])
		{
	case 0:
		capture_Cnt[0]++;
		__HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
		HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);	//启动输入捕获       或者: __HAL_TIM_ENABLE(&htim5);
		break;
	case 3:
		high_time[0] = capture_Buf0[0]- capture_Buf[0];    //高电平时间
							
		capture_Cnt[0]= 0;  //清空标志位
		break;	
    }

编码器模式

image-20211102123913446

int DirectionA=0,CaptureNumberA=0;
int CaptureNumberA_old=0;
float  speed=0;
int a=0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{ 
	if(htim->Instance == TIM2)
	{	
	DirectionA = __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim1); 
  CaptureNumberA=__HAL_TIM_GET_COUNTER(&htim1)+a*65536;		
	if(fabs((CaptureNumberA-CaptureNumberA_old)/20.0)<3000)speed=fabs((CaptureNumberA-CaptureNumberA_old)/20.0);
	CaptureNumberA_old=CaptureNumberA;
	}
		if(htim->Instance == TIM1)
	{	
	a++;
	}
}
 HAL_TIM_Encoder_Start(&htim1, TIM_CHANNEL_ALL);//编码器模式使能定时器1
 HAL_TIM_Base_Start_IT(&htim2);	//定时器2配置每20毫秒触发中断采集数据
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值