目录
硬件知识
一、定时器的基本概念
二、定时器参数配置
函数库知识
一、定时器开启函数
二、定时中断回调函数
代码编写
一、一灯闪烁(500ms)
二、两灯闪烁(300ms,1000ms)
硬件知识
一、定时器
①定时器概念
- stm32系列芯片中有三种定时器:
- 基础,通用,高级
- 三种定时器均能定时中断
- 基础定时器无法进行pwm输出
- stmf103有四个定时器,TIM1为高级定时器,其他为通用定时器
- 本工程着眼于定时中断,因此要配置TIM2
②定时器原理
- 单片机是如何计算时间的
- 单片机内含晶振,晶振是一种通电后以一定频率不断振荡的电子器件
- 每振荡一次电路就会发生一次改变,即运行一条程序
- stm32里的晶振都是72MHZ,不知道为什么
- 故stm32一秒内会运行72M条程序
- 单片机内含晶振,晶振是一种通电后以一定频率不断振荡的电子器件
- 大多数定时器内用了一16位存储计数值
- 在向上计数模式中,计数值为0
- 1s振荡72MHZ,故计数值1s增加72M
- 反过来,若运行了72M次程序,则过了1s
- 向下计数也差不多
- 在向上计数模式中,计数值为0
二、定时器配置
先开启TIM2的时钟源
参数设置才是重点
- Prescaler:分频系数
- 刚刚不是说1s运行72M次么,这个频率太高了
- 分频就是将系统时钟频率做除法
- 要减去1,不知道为什么,到时候再说吧
- 现在的TIM2频率 = 72M / 7200 = 10 000
- 即1s运行10k次
- 刚刚不是说1s运行72M次么,这个频率太高了
- Period:计数周期
- 计数值达到一个特定值后,进行一次中断,这个就是计数周期
- 一般默认是16位存满了,就记录周期满一次
- 0~65535
- 我们这里设置周期为5000
- 即计数值满5000,就进行一次中断
- 因为现在频率是10k,因此1s内会循环2次周期,中断两次
- 计数值达到一个特定值后,进行一次中断,这个就是计数周期
- 一些无关量
- 计数模式向上没什么好说的
- 内部时钟分频
- 前面都分过了,这里就不分了
- 最后那个使能有手就行
函数库知识
一、定时器开启函数
来自“stm32f1xx_hal_tim.c”
- HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim);
- 这个不细讲,就像掐秒表一样,意思就是开始计时
- 先不管那么多,记住用法就好
例
HAL_TIM_Base_Start_IT(&htim2);
二、定时中断回调函数
还是点开官方例程
函数用法也就差不多
想用就复制
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/*定时结束后做点什么吧*/
}
记得搞一下两个函数的模板
代码编写
一、一灯闪烁(500ms)
①初始化参数上面算过了
开启定时中断
②复制函数
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim2);
/* USER CODE END 2 */
/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/*定时结束后做点什么吧*/
Red_Toggle() ;
}
/* USER CODE END 4 */
二、两灯闪烁(300ms,1000ms)
①中断周期计算
先设分频系数72
- 现在的TIM2频率 = 72M / 72 = 1000 000
- 即1s运行1M次
令Period = 1000
现在周期为1ms
那么Prescaler= 72 *100
Period = 1000*3
很容易就是300ms周期了
那么Prescaler= 72 *100
Period = 1000*10
②开中断
③写代码
启动就不说了
这是模仿外部中断写的
/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/*定时结束后做点什么吧*/
if(htim->Instance ==TIM2){
Red_Toggle() ;
}
if(htim->Instance ==TIM3){
Green_Toggle() ;
}
}
/* USER CODE END 4 */
一些宏定义补充
#define Red GPIO_PIN_1
#define Green GPIO_PIN_5
#define Green_On() HAL_GPIO_Writein(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);
#define Green_Off() HAL_GPIO_Writein(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
#define Green_Toggle() HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
#define Red_On() HAL_GPIO_Writein(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);
#define Red_Off() HAL_GPIO_Writein(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);
#define Red_Toggle() HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_1);
补充:如何写一个pwm输出
一、初始化配置
①周期参数的设置
period设置为100
②pwm设置
添加图片注释,不超过 140 字(可选)
-
Pulse:占空比
-
这里我们设置80,那么功率 = 80/period = 80/100= 80%
-
Polarity:输出极性
-
结合上面,意思是80%的时间输出高电平
我们一共设置两个,到时候把LED1拆下来观察亮度
函数库知识 一、启动函数
模板记一下
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
二、占空比改变函数
__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, 0);
代码编写
呼吸灯
for(uint8_t i =0;i<=100;i++)
{
__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, i);
HAL_Delay(10);
}
for(uint8_t i =100;i>=100;i--)
{
__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, i);
HAL_Delay(10);
}