本帖最后由 逍遥李 于 2015-12-27 18:57 编辑
呼吸灯很多人都玩过,大都使用PWM实现,如果LED管脚没有不是定时器通道怎么办?普通IO口如何实现呼吸灯效果?(循环方式不算啊,占用太多MCU时钟资源的也不算!)下面就是使用两个定时器来实现板子上LD1、LD2、LD3三个LED的呼吸灯效果的详细过程。
目的:
1、学习GPIO基本操作:置位、清零、翻转等函数。
2、学习定时器基本配置操作过程,学习定时器PWM输出配置。
3、学习定时器中断,中断回调函数的使用。
开发环境:cubemx 4.10+Keil V5.16
1)首先来看下F469Discovery板子上LED的硬件连接电路:
可以发现,这四个管脚都是没有PWM通道的
2)创建工程,打开定时器
说实话,看到这么多管脚,也是一头雾水,先不管它,打开TIM1和TIM2的时钟,并配置TIM1_CH1为PWM模式……
3)配置定时器
首先来看下时钟,默认16MHZ,不作修改
然后定时器1配置,预分频15,周期999
打开定时器1更新和输出比较中断
配置定时器2,预分频15,周期19999
打开定时器2全局中断
4)生成初始代码
注意选中图中小窗口……原因不多说……
5)打开工程后,进入tim.c中,找到下面这行代码:
移动到下面这个位置:
然后打开main.c,在用户变量定义区域增加下面这行代码:
这样还不够,继续定义两个变量,如下图
6)启动定时器1和定时器2
这三行代码一行不能少……,Base_Start_IT用于使能定时器溢出中断
7)为对比效果,主函数写个LD4的闪烁即可
HAL_Delay(500);
HAL_GPIO_TogglePin(GPIOK,GPIO_PIN_3);
8)呼吸灯相关代码:
前面说过,为了不占用太多MCU时钟资源,呼吸灯效果的实现是通过定时器中断回调函数来实现的,具体就是下面两个函数:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* NOTE : This function Should not be modified, when the callback is needed,
the __HAL_TIM_PeriodElapsedCallback could be implemented in the user file
*/
if(htim==&htim1)
{
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_6,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_4,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_5,GPIO_PIN_SET);
}
else if(htim==&htim2)
{
if((Pulse+Shift)>999)
Shift =-20;
else if((Pulse+Shift)<30)
Shift =20;
Pulse +=Shift;
sConfigOC.Pulse = Pulse;
HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
HAL_TIM_PWM_Start_IT(&htim1,TIM_CHANNEL_1);
}
else
;
}
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
/* NOTE : This function Should not be modified, when the callback is needed,
the __HAL_TIM_PWM_PulseFinishedCallback could be implemented in the user file
*/
if(htim==&htim1)
{
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_6,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_4,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_5,GPIO_PIN_RESET);
}
else
;
}
至此,整个工程就完成了,可以编译下载试下效果了~!
9)实际效果:
|