hal库学习笔记(四):定时中断与pwm输出

目录

硬件知识

一、定时器的基本概念

二、定时器参数配置

函数库知识

一、定时器开启函数

二、定时中断回调函数

代码编写

一、一灯闪烁(500ms)

二、两灯闪烁(300ms,1000ms)

硬件知识

一、定时器

①定时器概念

  • stm32系列芯片中有三种定时器:
    • 基础,通用,高级
    • 三种定时器均能定时中断
    • 基础定时器无法进行pwm输出

  • stmf103有四个定时器,TIM1为高级定时器,其他为通用定时器
    • 本工程着眼于定时中断,因此要配置TIM2

②定时器原理

  • 单片机是如何计算时间的
    • 单片机内含晶振,晶振是一种通电后以一定频率不断振荡的电子器件
      • 每振荡一次电路就会发生一次改变,即运行一条程序
    • stm32里的晶振都是72MHZ,不知道为什么
      • 故stm32一秒内会运行72M条程序

  • 大多数定时器内用了一16位存储计数值
    • 在向上计数模式中,计数值为0
      • 1s振荡72MHZ,故计数值1s增加72M
      • 反过来,若运行了72M次程序,则过了1s
    • 向下计数也差不多

二、定时器配置

先开启TIM2的时钟源

参数设置才是重点 

  • Prescaler:分频系数
    • 刚刚不是说1s运行72M次么,这个频率太高了
      • 分频就是将系统时钟频率做除法
      • 要减去1,不知道为什么,到时候再说吧
    • 现在的TIM2频率 = 72M / 7200 = 10 000
      • 即1s运行10k次

  • 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);
}

  • 6
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值