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

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

计数器寄存器(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
定时中断控制微型步进电机

配置内部时钟源定时器,预分频系数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控制舵机

输入捕获
捕获方波周期

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占空比

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;
}
编码器模式

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

被折叠的 条评论
为什么被折叠?



