stm32f1定时器Timer
定时器分类
这篇文章主要讲解基本定时器,通用定时器和高级定时器
基本定时器
在F1中基本定时器为TIM6/TIM7。
主要特性:16位递增计数器,16位预分频器。在计数器溢出时会产生中断/DMA请求。
TIM6/TIM7寄存器
TIMx_CR1寄存器(16位)
位7:ARPE自动重装载预装载使能。
0:TIMx_ARR寄存器没有缓冲
1:TIMx_ARR寄存器有缓冲
位0:CEN计数器使能
0:关闭计数器
1:使能计数器
TIMx_DIER寄存器(16位)
位8:UDE更新DMA请求使能
0:禁止更新DMA请求
1:使能更新DMA请求
位0:UIE:更新中断使能
0:禁止更新中断
1:使能更新中断
TIMx_SR寄存器(16位)
位0:UIF
0:没有产生更新中断
1:产生更新中断,下述情况下由硬件设置该位。
计数器TIMx_CNT寄存器
TIMx_PSC
用于设置预分频系数,PSC的数值被传送到实际的预分频寄存器中。
TIMx_ARR自动重装载寄存器
存储的是Timer计时器的最大值。
定时器中断实验配置步骤
typedef struct
{
TIM_TypeDef *Instance; /* 外设寄存器基地址如TIM6 */
TIM_Base_InitTypeDef Init; /* 定时器初始化结构体*/
...
}TIM_HandleTypeDef;
typedef struct
{
uint32_t Prescaler; /* 预分频系数 */
uint32_t CounterMode; /* 计数模式 */
uint32_t Period; /* 自动重载值 ARR */
uint32_t ClockDivision; /* 时钟分频因子 */
uint32_t RepetitionCounter; /* 重复计数器寄存器的值 */
uint32_t AutoReloadPreload; /* 自动重载预装载使能 */
} TIM_Base_InitTypeDef;
实验:使用TIM6定时器控制LED灯的亮灭
btim.c
通用定时器简介(F1为例)
通用定时器:TIM2/3/4/5
主要特性:
16位递增、递减、中心对齐计数器(计数值:0~65535)
16位预分频器(分频系数:1~65536)
可用于触发DAC、ADC
在更新事件、触发事件、输入捕获、输出比较时,会产生中断/DMA请求
4个独立通道,可用于:输入捕获、输出比较、输出PWM、单脉冲模式
使用外部信号控制定时器且可实现多个定时器互连的同步电路
支持编码器和霍尔传感器电路等
通用定时器框图
通用定时器PWM输出实验
CCR1为一个数,他是与计时器当前的数字进行比较
通用定时器输出PWM原理。
当CNT < CCRx,IO输出0
当CNT >= CCRx,IO输出
通用定时器PWM输出实验配置步骤
通用定时器PWM实验—控制LED0亮度程度
gtim.c代码
TIM_HandleTypeDef g_timx_pwm_chy_handle;
/* 通用定时器PWM输出初始化函数*/
void gtim_timx_pwm_chy_init(uint16_t arr, uint16_t psc)
{
TIM_OC_InitTypeDef timx_oc_pwm_chy;
g_timx_pwm_chy_handle.Instance = TIM3;
g_timx_pwm_chy_handle.Init.Prescaler = psc;
g_timx_pwm_chy_handle.Init.Period = arr;
g_timx_pwm_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP;
HAL_TIM_PWM_Init(&g_timx_pwm_chy_handle);
timx_oc_pwm_chy.OCMode = TIM_OCMODE_PWM1;//pwm模式1,CNT<CCRx,输出有效电平
timx_oc_pwm_chy.Pulse = arr / 2;
timx_oc_pwm_chy.OCPolarity = TIM_OCPOLARITY_LOW;//设置为低电平有效
//配置PWM模式,比较值,输出极性等。
HAL_TIM_PWM_ConfigChannel(&g_timx_pwm_chy_handle, &timx_oc_pwm_chy, TIM_CHANNEL_2);
//使能输出并启动计数器,使用输出通道2
HAL_TIM_PWM_Start(&g_timx_pwm_chy_handle, TIM_CHANNEL_2);
}
/* 定时器输出PWM_MSP初始化函数*/
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM3)
{
GPIO_InitTypeDef gpio_init_struct;
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_TIM3_CLK_ENABLE();
gpio_init_struct.Pin = GPIO_PIN_5;
gpio_init_struct.Mode = GPIO_MODE_AF_PP; /* 推挽复用 */
gpio_init_struct.Pull = GPIO_PULLUP; /* 输入上拉 */
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /*高速 */
HAL_GPIO_Init(GPIOB, &gpio_init_struct);
//打开重映射时钟
__HAL_RCC_AFIO_CLK_ENABLE();
//使用复用重映射功能,操作寄存器AFIO_MAPR,位10:11将CH2复用到PB5
__HAL_AFIO_REMAP_TIM3_PARTIAL();
}
}
main.c
extern TIM_HandleTypeDef g_timx_pwm_chy_handle; /*定时器x句柄 */
int main(void)
{
uint16_t ledrpwmval = 0;
uint8_t dir = 1;
HAL_Init(); /* */
sys_stm32_clock_init(RCC_PLL_MUL9); /* */
delay_init(72); /* */
led_init(); /* */
gtim_timx_pwm_chy_init(500 - 1, 72 - 1);
while(1)
{
delay_ms(10);
if (dir)ledrpwmval++; /* dir==1 ledrpwmvalµÝÔö */
else ledrpwmval--; /* dir==0 ledrpwmvalµÝ¼õ */
if (ledrpwmval > 300)dir = 0; /* ledrpwmvalµ½´ï300ºó£¬·½ÏòΪµÝ¼õ */
if (ledrpwmval == 0)dir = 1; /* ledrpwmvalµÝ¼õµ½0ºó£¬·½Ïò¸ÄΪµÝÔö */
/* 修改与CCR的值,这样就会改变PWM输出波形的占空比 */
__HAL_TIM_SET_COMPARE(&g_timx_pwm_chy_handle, TIM_CHANNEL_2, ledrpwmval);
}
}
通用定时器输入捕获实验
通用定时器输入捕获脉宽测量原理。
输入捕获实验配置步骤
编程实战:通过定时器5通道1来捕获高电平脉宽时间,通过串口打印出来
这个实验有点难噢。有与Timer这部分比较难,这个部分剩下的实验和高级定时器暂时不学习,等自己基础更加扎实之后再回过头学习。