用STM32F103C8T6的定时器与PWM控制LED灯亮灭(HAL库方式)【STM32开发板】【STM32CubeMX】
关于定时器与PWM
定时器
STM32F103一共有8个定时器TIM1~TIM8,其中TIM6, TIM7是基本定时器,TIM2, TIM3, TIM4, TIM5是通用定时器,TIM1, TIM8是高级定时器。
本次实验使用通用定时器。TIM2、TIM3、TIM4、TIM5为STM32的4个独立的16位通用定时器,具有定时、测量输入信号的脉冲长度(输入捕获)、输出所需波形(输出比较、产生PWM、单脉冲输出等)等功能。
通用定时器内部结构框图如下。
PWM
脉冲宽度调制(Pulse width modulation,PWM)是一种利用脉冲宽度即占空比实现对模拟信号进行控制的技术,即是对模拟信号电平进行数字表示的方法。
STM32的每个通用定时器都有独立的4个通道TIMx_CH1~TIMx_CH4,可以用来作为:输入捕获、输出比较、PWM输出、单脉冲模式输出等。STM32的定时器除了TIM6和TIM7(基本定时器)之外,其他的定时器都可以产生PWM输出。其中,高级定时器TIM1、TIM8可同时产生7路PWM输出;通用定时器可同时产生4路PWM输出。
在PWM的一个周期内,定时器从0开始向上计数,在0-t1时间段,定时器计数器TIMx_CNT值小于TIMx_CCRx值,输出低电平;在t1-t2时间段,定时器计数器TIMx_CNT值大于TIMx_CCRx值,输出高电平;当定时器计数器的值TIMx_CNT达到ARR时,定时器溢出,重新从0开始向上计数,如此循环。
HAL库方式的开发环境搭建——STM32CubeMX
见链接:https://blog.csdn.net/cqjtu_pengzifu/article/details/139183353
实验一:用STM32F103的 Tim2~Tim5其一定时器的某一个通道pin(与GPIOx管脚复用)连接一个LED,用定时器计数方式控制LED以2s的频率周期性地亮-灭。
实验说明
本次实验选择PA5为输出端口,默认输出电平为低;选择定时器TIM3。
在STM32CubeMX中建立并配置项目
点击 “File” -> “New Project”,选择芯片STM32F103C8,点击 “Start Project” 即建立项目。
在Pinout & Configuration界面中,点击System Core→GPIO设置端口。点击PA5端口,选择GPIO_Output即将PA5端口设置为输出,再将此端口的默认输出电平设置为低,如下图。
点击SYS,选择Debug(调试)类型为Serial Wire(串行线)。
点击RCC,选择High Speed Clock(高速时钟)模式为Crystal/Ceramic Resonator(晶振)。
点击Timers→TIM3,勾选Internal Clock(内部时钟),点击下方的Parameter Settings,设置Prescaler(预分频器)为36000-1,设置Counter Mode(计数模式)为Up,Counter Period(计数周期)为2000-1,auto-reload preload为Enable,如下图,则定时器TIM3精确定时1s。
点击下方的NVIC Settings,勾选TIM3 global interrupt,如下图。
在Clock Configuration界面中,设置PLL Source Mux为HSE,设置System Clock Mux为PLLCLK,并按下图标记设置数值。
在Project Manager界面中,设置好项目名、项目位置,选择IDE为MDK-ARM(版本选择电脑上安装的版本),选择在网上下载并安装好的固件库。
点击Code Generator,选择 “Copy only the necessary library files”,勾选 “Generate peripheral initialization as a pair of ‘.c/.h’ files per peripheral”。
最后,点击 “Generate Code”,即可创建Keil项目并打开。
在Keil中编写程序和配置项目
在主函数 (main.c) 中的/*USER CODE BEGIN2 */和/*USER CODE END2 */之间添加开启定时器TIM3中断的程序:
HAL_TIM_Base_Start_IT(&htim3); //启动定时器TIM3定时中断
在主函数 (main.c) 中的/*USER CODE BEGIN4 */和/*USER CODE END4 */之间添加TIM3的中断回调函数:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == htim3.Instance)
{ HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
}
}
STM32开发板实现
将一个LED接在开发板的A5接口上,具体做法是将正极(长管脚)接至正极槽,负极(短管脚)接至开发板A5接口所接在的一槽。
代码在Keil中编译完成后,点击“下载”,即可将代码载入STM32单片机中并开始运行。运行结果如下。
Keil波形图
在Logic Analyzer中添加A5端口并设置为位显示,运行,得如下波形图:第一个周期内0 ~ 1s为高电平1,1 ~ 2s为低电平0;以2s为一个周期如此循环。
实验二:采用定时器PWM模式,让 LED 以呼吸灯方式渐亮渐灭,周期为1~2秒,自己调整占空比变化到一个满意效果。
实验说明
本次实验选择定时器TIM3,通道1。TIM3通道1对应的端口为PA6。默认CH电平为低。
在STM32CubeMX中建立并配置项目
点击 “File” -> “New Project”,选择芯片STM32F103C8,点击 “Start Project” 即建立项目。
在Pinout & Configuration界面中,点击System Core→SYS,选择Debug(调试)类型为Serial Wire(串行线)。
点击RCC,选择High Speed Clock(高速时钟)模式为Crystal/Ceramic Resonator(晶振)。
点击Timers→TIM3,勾选Internal Clock(内部时钟),选择Channel1(通道1)为PWM Generation CH1。点击下方的Parameter Settings,在Counter Settings中设置Prescaler(预分频器)为71,设置Counter Mode(计数模式)为Up,Counter Period(计数周期)为499,auto-reload preload为Enable,如下图,则定时器溢出频率,即PWM的周期,就是 72MHz/(71+1)/(499+1) = 2kHz。
在PWM Generation Channel 1中设置Output compare preload为Enable,CH Polarity为Low,如下图。
点击下方的NVIC Settings,勾选TIM3 global interrupt。
在Clock Configuration界面中,设置PLL Source Mux为HSE,设置System Clock Mux为PLLCLK,并按下图标记设置数值。
在Project Manager界面中,设置好项目名、项目位置,选择IDE为MDK-ARM(版本选择电脑上安装的版本),选择在网上下载并安装好的固件库。
点击Code Generator,选择 “Copy only the necessary library files”,勾选 “Generate peripheral initialization as a pair of ‘.c/.h’ files per peripheral”。
最后,点击 “Generate Code”,即可创建Keil项目并打开。
在Keil中编写程序和配置项目
在主函数 (main.c) 中的/*USER CODE BEGIN1 */和/*USER CODE END1 */之间定义一个占空比变量:
uint16_t pwmVal=0; //PWM占空比
在主函数 (main.c) 中的/*USER CODE BEGIN2 */和/*USER CODE END2 */之间添加开启定时器TIM3中断的程序:
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
在 while(1) 循环内/*USER CODE BEGIN3 */和/*USER CODE END3 */之间写入以下程序:
while (pwmVal<500)
{
pwmVal++;
__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, pwmVal); //修改比较值,修改占空比
// TIM3->CCR1 = pwmVal; 与上方相同
HAL_Delay(1);
}
while (pwmVal)
{
pwmVal--;
__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, pwmVal); //修改比较值,修改占空比
// TIM3->CCR1 = pwmVal; 与上方相同
HAL_Delay(1);
}
HAL_Delay(200);
STM32开发板实现
将一个LED接在开发板的A6接口上,具体做法是将正极(长管脚)接至正极槽,负极(短管脚)接至开发板A6接口所接在的一槽。
代码在Keil中编译完成后,点击“下载”,即可将代码载入STM32单片机中并开始运行。运行结果如下。
Keil波形图
在Logic Analyzer中添加A6端口并设置为位显示,运行,得如下波形图:
总结
本次实验学习了定时器和PWM的原理及应用。通过使用定时器PWM模式对输出的控制可以使LED实现呼吸效果,并控制其时间及亮度。
参考资料
https://blog.csdn.net/Morzart/article/details/134123197
https://blog.csdn.net/weixin_52345779/article/details/135313203