用STM32F103C8T6的定时器与PWM控制LED灯亮灭(HAL库方式)
用STM32F103C8T6的定时器与PWM控制LED灯亮灭(HAL库方式)
本文将详细介绍如何使用STM32F103C8T6微控制器的定时器和PWM功能来控制LED灯的亮灭。通过两个具体的实验案例,读者将学习到如何使用STM32CubeMX配置开发环境,并通过HAL库实现定时器中断和PWM输出。
定时器与PWM基础
定时器
STM32F103系列微控制器共有8个定时器TIM1~TIM8,其中:
- TIM6, TIM7是基本定时器
- TIM2, TIM3, TIM4, TIM5是通用定时器
- TIM1, TIM8是高级定时器
本次实验将使用通用定时器TIM2~TIM5。这些定时器具有以下功能:
- 定时
- 测量输入信号的脉冲长度(输入捕获)
- 输出所需波形(输出比较、产生PWM、单脉冲输出等)
PWM
脉冲宽度调制(PWM)是一种通过控制脉冲宽度(占空比)来实现对模拟信号进行控制的技术。STM32的每个通用定时器都有4个独立的通道(TIMx_CH1~TIMx_CH4),可以用于:
- 输入捕获
- 输出比较
- PWM输出
- 单脉冲模式输出
在PWM的一个周期内,定时器从0开始向上计数:
- 在0-t1时间段,定时器计数器TIMx_CNT值小于TIMx_CCRx值,输出低电平
- 在t1-t2时间段,定时器计数器TIMx_CNT值大于TIMx_CCRx值,输出高电平
- 当定时器计数器的值TIMx_CNT达到ARR时,定时器溢出,重新从0开始向上计数,如此循环。
开发环境搭建
使用STM32CubeMX进行开发环境搭建的具体步骤可参考链接:https://blog.csdn.net/cqjtu_pengzifu/article/details/139183353
实验一:定时器控制LED亮灭
实验说明
本次实验选择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(内部时钟),设置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) 中添加以下代码:
// 开启定时器TIM3中断
HAL_TIM_Base_Start_IT(&htim3);
// TIM3的中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == htim3.Instance)
{
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
}
}
实验结果
将一个LED接在开发板的A5接口上,正极接至正极槽,负极接至开发板A5接口。代码编译完成后,点击“下载”,将代码载入STM32单片机中运行。运行结果如下:
在Logic Analyzer中添加A5端口并设置为位显示,运行,得如下波形图:第一个周期内0 ~ 1s为高电平1,1 ~ 2s为低电平0;以2s为一个周期如此循环。
实验二:PWM控制LED呼吸灯
实验说明
本次实验选择定时器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。
- 在Counter Settings中设置Prescaler(预分频器)为71,设置Counter Mode(计数模式)为Up,Counter Period(计数周期)为499,auto-reload preload为Enable,定时器溢出频率为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) 中添加以下代码:
// 定义占空比变量
uint16_t pwmVal=0;
// 开启定时器TIM3中断
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
// 主循环中调整占空比
while (pwmVal<500)
{
pwmVal++;
__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, pwmVal);
HAL_Delay(1);
}
while (pwmVal)
{
pwmVal--;
__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, pwmVal);
HAL_Delay(1);
}
HAL_Delay(200);
实验结果
将一个LED接在开发板的A6接口上,正极接至正极槽,负极接至开发板A6接口。代码编译完成后,点击“下载”,将代码载入STM32单片机中运行。运行结果如下:
在Logic Analyzer中添加A6端口并设置为位显示,运行,得如下波形图:
总结
本次实验学习了定时器和PWM的原理及应用。通过使用定时器PWM模式对输出的控制可以使LED实现呼吸效果,并控制其时间及亮度。