目录
四、采用定时器PWM模式,让 LED 以呼吸灯方式渐亮渐灭,周期为1~2秒
一、定时器
1.定时器模块的功能
STM32定时器模块主要有计数、定时、输入捕获、输出比较这四个功能。其中:
计数:脉冲计数,使用使用微控制器内部的外部时钟(PCLK)来计数,是对固定周期的脉冲信号计数。
定时:时间控制,通过对微控制器内部的时钟脉冲进行计数实现定时功能。
输入捕获:对输入信号进行捕获,实现对脉冲的频率测量,可用于对外部输入信号脉冲宽度的测量,比如测量电机转速。
输出比较:将计数器计数值和设定值进行比较,根据比较结果输出不同电平,用于控制输出波形,比如直流电机的调速。
2.STM32定时器类别
STM32定时器主要分为基本定时器、通用定时器和高级定时器。
下面是STM32定时器的分类比较表:
定时器 | 基本定时器**(TIM6、TIM7)** | 通用定时器**TIMx(x=2~5)** | 高级定时器**(TIM1、TIM8)** |
---|---|---|---|
计数器类型 | 16**位,向上** | 16**位,向上、向下、向上/向下** | 16**位,向上、向下、向上/向下** |
预分频系数 | 1**~65535之间的任意数** | 1**~65535之间的任意数** | 1**~65535之间的任意数** |
输入**/捕获通道** | 无 | 四个独立通道:输入捕获、输出比较、**PWM生成、单脉冲模式输出** | 四个独立通道:输入捕获、输出比较、**PWM生成、单脉冲模式输出** |
产生中断**/DMA** | 可以 | 可以 | 可以 |
刹车(电机控制) | 无 | 无 | 可以 |
3.通用定时器
STM32通用定时器TIMx(x=2,3,4,5)主要由时钟源、时钟单元、捕获和比较通道等构成,核心是可编程预分频驱动的16位自动装载计数器。
(1)时钟源
当定时器使用内部时钟时,定时器的时钟源统称为TIMxCLK。TIMxCLK的系统默认的时钟频率为72MHz,但其时钟来源并不相同。
定时器TIM2~TIM7挂接在APB1上定时器TIM1和TIM8挂接在APB2上。
若外部晶振的频率为8MHz,则系统默认的时钟频率为72MHz
APB1预分频器的分频系数设置为2,则PCLK1=36MHz;
APB2预分频系数设置为1,则PCLK2=72MHz,TIM1和TIM8的时钟频率TIMxCLK=72MHz;
Cortex系统时钟由AHB时钟(HCLK)8分频得到,即SysTick的频率为9MHz。
(2)预分频器PSC
可以以1~65535之间的任意数值对时钟源CK_PSC的时钟频率进行分频,输出CK_CNT脉冲供计数器CNT进行计数。
(3)计数器CNT
TIMxCNT是一个16位的寄存器,计数范围为1~65535,可以向上计数、向下计数或向下向上双向计数。
要得到想要的计数值,需要对输入时钟频率进行分频。
当计数值达到设定值时,便产生溢出事件,溢出时产生中断或DMA请求,然后再由自动装载寄存器进行重新加载或更新。
计数器溢出中断属于软件中断,执行相应的定时器中断服务程序。
(4)自动装载寄存器ARR
定时器的定时时间主要取决于定时周期和预分频因子,计算公式为:定时时间=(ARR+1)×(预分频值PSC+1)/输入时钟频率或 T=(TIM_Period +1)*(TIM_Prescaler +1)/TIMxCLK这里ARR+1是因为计数器都是从0开始计数的。
二、PWM
PWM是一种利用脉冲宽度即占空比实现对模拟信号进行控制的技术,即是对模拟信号电平进行数字表示的方法。
1.工作原理
STM32的定时器除了TIM6和TIM7,其他定时器都可以用来产生PWM输出。
通用定时器能同时产生多达4路的PWM输出。
STM32中每个定时器有4个输入通道:TIMx_CH1~TIMx_CH4;每个通道对应1个捕获/比较寄存器TIMx_CRRx,将寄存器值和计数器值相比较,通过比较结果输出高低电平,从而得到PWM信号。
在PWM的一个周期内,定时器从0开始向上计数,在0-t1时间段,定时器计数器TIMx_CNT值小于TIMx_CCRx值,输出低电平;
在t1-t2时间段,定时器计数器TIMx_CNT值大于TIMx_CCRx值,输出高电平;
当定时器计数器的值TIMx_CNT达到ARR时,定时器溢出,重新从0开始向上计数,如此循环。
2.PWM标准外设库输出配置
首先配置PWM输出通道,开启TIM3时钟:
STM32规定了具体的引脚作为PWM输出引脚,选择不同的引脚时,还必须使用重定向功能(Remap)
定时器TIM1的引脚复用功能映像:
复用功能 | TIM1_REMAP[1:0] = 00**(没有重映像)** | TIM1_REMAP[1:0] = 01**(部分重映像)** | TIM1_REMAP**[1:0] = 11(完全重映像)** (1) |
---|---|---|---|
TIM1_ETR | PA12 | PE7 | |
TIM1_CH1 | PA8 | PE9 | |
TIM1__CH2 | PA9 | PE11 | |
TIM1_CH3 | PA10 | PE13 | |
TIM1_CH4 | PA11 | PE14 | |
TIM1_BKIN | PB12(2) | PA6 | PE15 |
TIM1_CH1N | PB13(2) | PA7 | PE8 |
TIM1_CH2N | PB14(2) | PB0 | PE10 |
TIM1_CH3N | PB15(2) | PB1 | PE12 |
定时器TIM2的引脚复用功能映像:
复用功能 | TIM2_REMAP**[1:0]=00(没有重映像)** | TIM1_REMAP**[1:0]=01(部分重映像)** | TIM1_REMAP[1:0]=10 (**部分重映像)** (1) | TIM1_REMAP[1:0]=11**(完全重映像)** (1) |
---|---|---|---|---|
TIM2_CH1_ETR**(2)** | PA0 | PA15 | PA0 | PA15 |
TIM2_CH2 | PA1 | PB3 | PA1 | PB3 |
TIM2_CH3 | PA2 | PB10 | ||
TIM2_CH4 | PA3 | PB11 |
定时器TIM3的引脚复用功能映像:
复用功能 | TIM3_REMAP[1:0] = 00**(没有重映像)** | TIM3_REMAP[1:0] = 10**(部分重映像)** | TIM3_REMAP[1:0] = 11**(完全重映像)** (1) |
---|---|---|---|
TIM3_CH1 | PA6 | PB4 | PC6 |
TIM3_CH2 | PA7 | PB5 | PC7 |
TIM3_CH3 | PB0 | PC8 | |
TIM3_CH4 | PB1 | PC9 |
三、用定时器计数方式,控制LED以2s的频率周期性亮灭
使用STM32F103的 Tim2~Tim5其一定时器的某一个通道pin(与GPIOx管脚复用,见下图),连接一个LED,用定时器计数方式,控制LED以2s的频率周期性地亮-灭。
1.STM32Cube配置
(1)GPIO配置
(2)RCC配置
(3)SYS配置
(4)TIM2配置
(5)Clock配置
(6)项目配置
2.KEil代码编写
添加了如下代码:
HAL_TIM_Base_Start_IT(&htim2);
添加如下代码:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
static unsigned char ledState = 0;
if (htim == (&htim2))
{
if (ledState == 0)
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
else
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
ledState = !ledState;
}
}
3.实验结果
四、采用定时器PWM模式,让 LED 以呼吸灯方式渐亮渐灭,周期为1~2秒
接上,采用定时器PWM模式,让 LED 以呼吸灯方式渐亮渐灭,周期为1~2秒,自己调整占空比变化到一个满意效果;使用Keil虚拟示波器,观察 PWM输出波形。
1.STM32Cube配置
(1)RCC配置
(2)SYS配置
(3)TIM3配置
(4)GPIO配置
2.KEil代码编写
在main.c中对应位置添加下面的代码:
/* USER CODE BEGIN 1 */
uint16_t pwmVal=0; //PWM占空比
uint8_t dir=1;
/* USER CODE END 1 */
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
/* USER CODE END 2 */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
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);
}
/* USER CODE END 3 */
3.程序烧录及实验结果
4.KEil波形图查看
波形图如下: