本文实践:实现通过TIM14_CH1输出PWM,外部显示为呼吸灯。
通用定时器简介
拥有TIM2~TIM5、TIM9~TIM14 一共10个定时器,具有4路独立通道,可用于输入捕获、输出比
较,同时包含了基本定时去的所有功能。
通用定时器的结构框图
主从模式触发
触发信号
概念:可以理解为某器件在接收到某个信号后,此信号可以触发本器件的一些功能。
在STM32中触发信号分为两大类:TRGI 和 TRGO,即触发输入信号和触发输出信号。
TRGO:定时器输出给其它定时器或外设的信号。可以理解为主模式触发信号。
TRGI : 可以理解为从外部引入到定时器中的信号。可以理解为从模式触发信号。
触发输入信号
第⼀类:TI1F_ED/TI1FP1/TI2FP2,来自输⼊通道1或通道2的触发信号,连接到从模式控制器,从而控制计数器的工作。
第⼆类:来自外部触发脚[ETR]的信号经过处理后,连接到从模式控制器。
第三类:来自其他定时器的触发信号,通过内部线路连接到从模式控制器
从模式控制器
复位模式:当有效触发信号出现时,将会复位计数器,并产生更新事件。向上计数的将会复位到0,向下计数的将会复位到ARR的值。
门控模式:定时器根据触发输⼊信号的电平来启动或停止计数器的计数。
触发模式:当有效触发输⼊信号出现时,会将本来处于未使能状态的计数器使能激活,让计数器开始计数
外部时钟模式1: 由所选触发信号 (TRGI) 的上升沿提供计数器时钟。
小结:
(1)不论来自本定时器外部的哪⼀类触发输入信号,它们有个共同特点,就是都要经过触发
输入选择器而连接到从模式控制器,从而使得计数器的工作受到从模式控制器的控制或影响。(2)从模式控制器可以对定时器作如下操控:对计数器复位、启动或停止计数动作、使能计数器、通过触发信号为计数器提供时钟源。
触发输出信号
触发输出信号是定时器自身产生的,它的产生途径如下:
1.定时器更新事件
2.定时器的输入捕获和输出比较事件
3.复位
4.使能
5.更新: 选择更新事件作为触发输出 (TRGO)。例如,主定时器可用作从定时器的预分频器。
时钟源选择
内部时钟(CK_INT):类似于基本定时器时钟。
外部时钟模式1:TIx
外部时钟模式2:ETR
内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器。
外部时钟模式1
外部时钟源信号 (来自于芯片外部)---> IO口 --->TIMx_CH1 /TIMx_CH2(外部模式1时钟源信号只能从CH1和 CH2输入定时器)
外部时钟模式2
外部时钟源信号 --->IO口 --->TIMx_ETR
内部输入触发
内部触发输⼊是使用一个定时器作为另一个定时器的预分频器,即实现定时器的级联。
如图示例:
输出比较
捕获/比较寄存器
捕获比较寄存器也存在影子寄存器。当有上升沿到来时,IC1PS信号就会触发输入捕获事件发生器。计数器的值就会被锁存到捕获/比较影子寄存器里。 当 CCR1 寄存器没有被进行读操作的时候,捕获/比较影子寄存器里的值就会锁存到 CCR1 寄存。
输出模式选择寄存器
结构框图
工作原理
PWM模式1:
向上计数:CNT<CCR时,REF置有效电平,CNT≥CCR时,REF置无效电平
向下计数:CNT>CCR时,REF置无效电平,CNT≤CCR时,REF置有效电平
PWM模式2:
向上计数:CNT<CCR时,REF置无效电平,CNT≥CCR时,REF置有效电平
向下计数:CNT>CCR时,REF置有效电平,CNT≤CCR时,REF置无效电平
示例如图(PWM模式1):
PWM简介
PWM(Pulse Width Modulation)脉冲宽度调制。控制⼀个周期中高低电平的比重。我们将高电平
占整个周期的比重称为占空比。脉冲宽度调制说到底就是调节占空比。
以上图中的PWM模式1举例:
当CNT值小于CCR时,IO输出高电平。当CNT值大于CCR时,IO输出低电平。当CNT和ARR的
值相等时,重新归零,然后重新向上计数,依次循环。
那么,改变CCR的值就可以改变PWM输出的占空比,改变ARR的值,就可以改变PWM的输出
频率。
PWM频率:Freq = CK_PSC / (PSC + 1) / (ARR + 1)
PWM占空比:Duty = CCR/(ARR + 1)
开发步骤
第⼀步:查看原理图,找到TIM14的输出通道复用在哪个IO引脚上
第⼆步:开启时钟
TIM14的时钟 和 GPIOF的时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE); //开启定时器的时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);//开启GPIOF的时钟
第三步:配置GPIOF
将GPIOF的Pin_9复⽤为TIM14的输出通道
第四步:初始化TIM14的时基单元,设置预分频值和重装值
TIM_TiMmeBaseInit();
第五步:使能ARR 和 CCR
TIM_OC1PreloadConfig(TIM14,TIM_OCPreload_Enable); //使能比较/捕获预装载寄存器 CCR1
TIM_ARRPreloadConfig(TIM14,ENABLE); //ARR 使能
第六步:使能TIM
TIM_Cmd(TIM14,ENABLE);
第七步:实现PWM控制函数
通过TIM_SetCompare1();函数来改变RCC的值,达到调节PWM的效果。
代码如下:
#include "stm32f4xx.h" // Device header
int main(void)
{
/*开启定时器的时钟*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);
/*开启GPIOF的时钟*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
/*初始化GPIO结构体*/
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStruct.GPIO_Speed = GPIO_High_Speed;
GPIO_Init(GPIOF,&GPIO_InitStruct);
GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14); //IO14口的复用
/*初始化时基单元*/
TIM_TimeBaseInitTypeDef TIM_TimeInitStruct;
TIM_TimeInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//时钟分割 输入捕获需要用到的
TIM_TimeInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeInitStruct.TIM_Period = 899;
TIM_TimeInitStruct.TIM_Prescaler = 8399;
TIM_TimeBaseInit(TIM14,&TIM_TimeInitStruct);
/*初始化输出比较配置*/
TIM_OCInitTypeDef TIM_OC1InitStruct;
TIM_OC1InitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OC1InitStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OC1InitStruct.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性高 REF有效时输出高电平
TIM_OC1Init(TIM14,&TIM_OC1InitStruct);
/*使能比较/捕获预装载寄存器CCR1*/
TIM_OC1PreloadConfig(TIM14,TIM_OCPreload_Enable);
/*ARR 使能*/
TIM_ARRPreloadConfig(TIM14,ENABLE);
/*定时器使能*/
TIM_Cmd(TIM14,ENABLE);
uint8_t i;
while (1)
{
for(i=0; i <= 200; i++)
{
TIM_SetCompare1(TIM14,i);
}
for(i=0; i<= 200; i++)
{
TIM_SetCompare1(TIM14,200-i);
}
}
}