0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

CKS32F4xx系列产品Timer的基本使用方法-比较输出

jf_pJlTbmA9 来源:中科芯MCU 作者:中科芯MCU 2023-11-09 17:39 次阅读

比较输出简介

比较输出可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形,简称脉宽调制,这也是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制,PWM原理如下图所示:

wKgaomUDxhGAJEC7AAELqU4EPN8177.jpg

图中,我们假定定时器工作在向上计数PWM模式,且当CNT时,输出0,当CNT>=CCRx时输出1。那么就可以得到如上的 PWM,示意图:当CNT值小于CCRx的时候,IO输出低电平(0),当CNT值大于等于CCRx的时候,IO输出高电平(1),当CNT达到ARR值的时候,重新归零,然后重新向上计数,依次循环。改变CCRx的值,就可以改变PWM输出的占空比,改变ARR的值,就可以改变PWM输出的频率,这就是 PWM输出的原理。

CKS32F4的定时器除了TIM6和7。其他的定时器都可以用来产生PWM输出。其中高级定时器TIM1和TIM8可以同时产生多达7路的PWM输出。而通用定时器也能同时产生多达4路的PWM输出。这里仅使用TIM14的CH1产生一路PWM输出。要使CKS32F4的通用定时器TIMx 产生PWM输出,除了上一章介绍的寄存器外,我们还会用到3个寄存器,来控制PWM的。这三个寄存器分别是:

捕获/比较模式寄存器(TIMx_CCMR1/2)、捕获/比较使能寄存器(TIMx_CCER)、捕获/比较寄存器(TIMx_CCR1~4)。对于捕获/比较模式寄存器(TIMx_CCMR1/2),该寄存器一般有2个:TIMx _CCMR1和TIMx _CCMR2,不过TIM14只有一个。TIMx_CCMR1控制CH1和2,而TIMx_CCMR2控制CH3和4。以下我们将以TIM14为例进行介绍。TIM14_CCMR1寄存器各位描述如下图所示:

wKgZomUDxhOAGkumAABi1CxeMXs081.png

该寄存器的有些位在不同模式下,功能不一样,所以在图中,我们把寄存器分了2层,上面一层对应输出而下面的则对应输入。关于该寄存器的详细说明,请参考《CKS32F4xx

中文参考手册》这里我们需要说明的是模式设置位 OC1M,此部分由3位组成。总共可以配置成7种模式,我们使用的是PWM模式,所以这3位必须设置为110/111。

这两种PWM模式的区别就是输出电平的极性相反。另外CC1S用于设置通道的方向(输入/输 出)默认设置为0,就是设置通道作为输出使用。注意:这里是因为我们的TIM14只有1个通道,所以才只有第八位有效,高八位无效,其他有多个通道的定时器,高八位也是有效的,具体请参考《CKS32F4xvx 中文参考手册》对应定时器的寄存器描述。

接下来,我们介绍TIM14的捕获/比较使能寄存器(TIM14_CCER),该寄存器控制着各个输入输出通道的开关。该寄存器的各位描述如下图所示:

wKgaomUDxhSAPgmCAAA3tzqmR3Q277.png

该寄存器比较简单,我们这里只用到了CC1E位,该位是输入/捕获1输出使能位,要想PWM从IO口输出,这个位必须设置为1,所以我们需要设置该位为1。因为TIM14只有1个通道,所以才只有低四位有效,如果是其他定时器,该寄存器的其他位也可能有效。

最后,我们介绍一下捕获/比较寄存器(TIMx_CCR1~4),该寄存器总共有4个,对应4 个通道CH1~4。不过TIM14只有一个,即:TIM14_CCR1,该寄存器的各位描述如下图所示:

wKgaomUDxhaAUgHOAAJ4UVzVKjM916.png

在输出模式下,该寄存器的值与CNT的值比较,根据比较结果产生相应动作。利用这点,我们通过修改这个寄存器的值,就可以控制 PWM 的输出脉宽了。

如果是通用定时器,则配置以上三个寄存器就够了,但是如果是高级定时器,则还需要配置:刹车和死区寄存器(TIMx_BDTR),该寄存器各位描述如下图所示:

wKgZomUDxhiAJ24VAAHOScs8rPw049.png

该寄存器,我们只需要关注最高位:MOE位,要想高级定时器的PWM正常输出,则必须设置MOE位为1,否则不会有输出。注意:通用定时器不需要配置这个。其他位我们这里就不详细介绍了。

PWM实际跟上一章节一样使用的是定时器的功能,所以相关的函数设置同样在库函数文件 CKS32f4xx_tim.h和CKS32f4xx_tim.c文件中。

1)开启TIM14和GPIO时钟,配置PF9选择复用功能AF9(TIM14)输出

要使用TIM14,我们必须先开启TIM14的时钟,这点相信大家看了这么多代码,应该明白了。这里我们还要配置PF9为复用(AF9)输出,才可以实现TIM14_CH1的PWM经过PF9输出。库函数使能 TIM14时钟的方法是:

wKgaomUDxhmAHMeCAAAuzCxvmy0469.png

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);//>>TIM14时钟使能

这在前面章节已经提到过。当然,这里我们还要使能GPIOF的时钟。然后我们要配置PF9引脚映射至AF9,复用为定时器14,调用的函数为:

GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14);//>>GPIOF9复用为定时器14

这个方法跟我们串口实验讲解一样,调用的同一个函数,最后设置PF9为复用功能输出这里我们只列出GPIO初始化为复用功能的一行代码:

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;//>>复用功能

这里还需要说明一下,对于定时器通道的引脚关系,大家可以查看CKS32F4对应的数据手册,比如我们PWM实验,我们使用的是定时器14的通道1,对应的引脚PF9可以从数据手册表中查看:

2)初始化TIM14,设置TIM14的ARR和PSC等参数

在开启了TIM14的时钟之后,我们要设置ARR和 PSC两个寄存器的值来控制输出PWM的周期。这在库函数是通过TIM_TimeBaseInit函数实现的,在上一节定时器中断章节我们已经有讲解,这里就不详细讲解,调用的格式为:

TIM_TimeBaseStructure.TIM_Period=arr;//设置自动重装载值
TIM_TimeBaseStructure.TIM_Prescaler=psc;//设置预分频值
TIM_TimeBaseStructure.TIM_ClockDivision=0;//设置时钟分割:TDTS=Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数模式
TIM_TimeBaseInit(TIM3, TIM_TimeBaseStructure);//根据指定的参数初始化TIMx

3)设置TIM14_CH1的PWM模式,使能TIM14的 CH1输出

设置TIM14_CH1为PWM模式(默认是冻结的)通过配置TIM14_CCMR1的相关位来控制TIM14_CH1的模式。在库函数中,PWM通道设置是通过函数 TIM_OC1Init()~TIM_OC4Init()来设置的,不同的通道的设置函数不一样,这里我们使用的是通道1,所以使用的函数是TIM_OC1Init()。

voidTIM_OC1Init(TIM_TypeDef*TIMx,TIM_OCInitTypeDef*TIM_OCInitStruct);

这种初始化格式大家学到这里应该也熟悉了,所以我们直接来看看结构体TIM_OCInitTypeDef的定义:

TIM_TimeBaseStructure.TIM_Period=arr;//设置自动重装载值
typedefstruct
{
uint16_tTIM_OCMode;
uint16_tTIM_OutputState;
uint16_tTIM_OutputNState;*/
uint16_tTIM_Pulse;
uint16_tTIM_OCPolarity;
uint16_tTIM_OCNPolarity;
uint16_tTIM_OCIdleState;
uint16_tTIM_OCNIdleState;
}TIM_OCInitTypeDef;

这里我们讲解一下与我们要求相关的几个成员变量:参数TIM_OCMode设置模式是PWM还是输出比较,这里我们是PWM模式。

参数TIM_OutputState用来设置比较输出使能,也就是使能PWM输出到端口

参数TIM_OCPolarity用来设置极性是高还是低。其他的参数TIM_OutputNState,TIM_OCNPolarity,TIM_OCIdleState和 TIM_OCNIdleState是高级定时器才用到的。要实现我们上面提到的场景,方法是:

TIM_OCInitTypeDefTIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//>>选择模式PWM
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//>>比较输出使能
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;//>>输出极性低
TIM_OC1Init(TIM14, TIM_OCInitStructure);//>>根据指定的参数初始化外设TIM14OC1

4)使能TIM14

在完成以上设置了之后,我们需要使能TIM14。使能TIM14的方法前面已经讲解过:

TIM_Cmd(TIM14,ENABLE);//>>使能TIM14

5)修改TIM14_CCR1来控制占空比

最后,在经过以上设置之后,PWM其实已经开始输出了,只是其占空比和频率都是固定的,而我们通过修改TIM14_CCR1则可以控制 CH1的输出占空比。在库函数中,修改TIM14_CCR1占空比的函数是:

voidTIM_SetCompare1(TIM_TypeDef*TIMx,uint16_tCompare2);

理所当然,对于其他通道,分别有一个函数名字,函数格式为TIM_SetComparex(x=1,2,3,4)。

通过以上5个步骤,我们就可以控制TIM14的CH1输出PWM波了。这里特别提醒一下大家,高级定时器虽然和通用定时器类似,但是高级定时器要想输出PWM,必须还要设置一个MOE位(TIMx_BDTR 的第15位),以使能主输出,否则不会输出PWM。库函数设置的函数为:

voidTIM_CtrlPWMOutputs(TIM_TypeDef*TIMx,FunctionalStateNewState)

代码示例

TIM3时钟来自于APB1域,我们通过APB1总线下的时钟使能函数来使能TIM3的时钟。调用的函数是:

//>>TIM14PWM部分初始化
//>>PWM输出初始化
//>>arr:自动重装值psc:时钟预分频数
voidTIM14_PWM_Init(u32arr,u32psc)
{
GPIO_InitTypeDefGPIO_InitStructure;
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
TIM_OCInitTypeDefTIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);//TIM14时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);//使能PORTF时钟
GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14);//GF9复用为TIM14
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//GPIOF9
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
//速度50MHz
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽复用输出
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOF, GPIO_InitStructure);//初始化PF9
TIM_TimeBaseStructure.TIM_Prescaler=psc;//定时器分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数模式
TIM_TimeBaseStructure.TIM_Period=arr;//自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM14, TIM_TimeBaseStructure);
//初始化定时器14//初始化TIM14Channel1PWM模式
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//PWM调制模式1
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//比较输出使能
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;//输出极性低
TIM_OC1Init(TIM14, TIM_OCInitStructure);//初始化外设TIM14OC1
TIM_OC1PreloadConfig(TIM14,TIM_OCPreload_Enable);//使能预装载寄存器
TIM_ARRPreloadConfig(TIM14,ENABLE);//ARPE使能
TIM_Cmd(TIM14,ENABLE);//使能TIM14
TIM_SetCompare1(TIM14,300);//>>设置pwm的占空比为300/500=60%
}

此部分代码包含了上面介绍的PWM输出设置的前5个步骤。这里我们关于TIM14的设置就不再说了。接下来,我们看看主程序里面的main函数如下:

intmain(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//>>设置系统中断优先级分组2
delay_init(168);//>>初始化延时函数
TIM14_PWM_Init(500-1,84-1);//>>定时器时钟为84M,分频系数为84,所以计数频率
//>>为84M/84=1Mhz,重装载值500,所以PWM频率为1M/500=2Khz.
while(1)
{
}
}

这里,我们先设置好了NVIC终端优先级,然后初始化延时函数和timer,在timer的初始化参数中我们把PWM的频率设置成2K,将占空比设置成60%,完成PWM输出设置。

来源:中科芯MCU

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • mcu
    mcu
    +关注

    关注

    146

    文章

    17152

    浏览量

    351262
  • 定时器
    +关注

    关注

    23

    文章

    3249

    浏览量

    114842
  • Timer
    +关注

    关注

    1

    文章

    64

    浏览量

    12790
收藏 人收藏

    评论

    相关推荐

    MCU微课堂|CKS32F4xx系列产品时钟配置

    ,并且高时钟频率将导致功耗增加、抗电磁干扰能力变弱,因此,CKS32F4xx系列产品内部具备多个时钟源。本文将对CKS32F4xx系列产品时钟组成进行分析,并讲解该系统单片机的时钟的配
    发表于 12-12 10:17 844次阅读

    CKS32F4xx系列产品NVIC中断优先级管理单元讲解

    本课将为大家讲解CKS32F4xx系列产品的中断优先级管理单元NVIC。CM4内核共支持256个中断,其中包含了16个内核中断和240个外部中断,具有256级可编程中断设置。但CKS32F4x
    的头像 发表于 02-06 14:52 1186次阅读

    CKS32F4xx系列产品串口DMA传输

    在上一讲,我们讲过CKS32F4xx系列的6个串口都支持DMA传输。因此本节我们对CKS32F4xx系列的DMA进行介绍,同时利用DMA对串口数据进行传输。
    的头像 发表于 04-10 11:18 1046次阅读

    CKS32F4xx系列产品的定时器使用-基本特征和定时操作

    这一课我们将介绍CKS32F4XX系列产品的定时器使用,CKS32F4XX的定时器功能十分强大,包含2个高级控制定时器,8个普通定时器,2个基础定时器,以及两个看门狗定时器和一个系统定时器,总共15个定时器之多。关于定时器部分内
    的头像 发表于 05-19 09:18 908次阅读
    <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列产品</b>的定时器使用-基本特征和定时操作

    CKS32F4xx系列RNG功能设置

      MCU 微课堂 CKS32F4xx 系 列RNG功能 随机数发生器简介     CKS32F4xx系列自带了硬件随机数发生器(RNG),RNG处理器是一个以连续模拟噪声为基础的随机数发生器,在
    的头像 发表于 09-08 10:01 611次阅读
    <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>RNG功能设置

    CKS32F4xx系列DAC功能

    CKS32F4xx系列DAC功能
    的头像 发表于 11-06 16:56 854次阅读
    <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>DAC功能

    CKS32F4xx系列ADC多通道DMA电压采集

    CKS32F4xx系列ADC多通道DMA电压采集
    的头像 发表于 11-06 16:53 1105次阅读

    CKS32F4xx系列ADC单通道电压采集

    CKS32F4xx系列ADC单通道电压采集
    的头像 发表于 11-06 16:54 993次阅读
    <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>ADC单通道电压采集

    CKS32F4xx系列低功耗模式SLEEP模式

    CKS32F4xx系列低功耗模式SLEEP模式
    的头像 发表于 11-06 16:59 682次阅读
    <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>低功耗模式SLEEP模式

    CKS32F4xx系列低功耗模式STOP模式

    CKS32F4xx系列低功耗模式STOP模式
    的头像 发表于 11-06 17:08 628次阅读
    <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>低功耗模式STOP模式

    CKS32F4xx系列产品Timer的基本使用方法-定时器脉冲计数

    CKS32F4xx系列产品Timer的基本使用方法-定时器脉冲计数
    的头像 发表于 11-09 17:38 1078次阅读
    <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列产品</b><b class='flag-5'>Timer</b>的基本<b class='flag-5'>使用方法</b>-定时器脉冲计数

    CKS32F4xx系列产品Timer的基本使用方法-定时操作

    CKS32F4xx系列产品Timer的基本使用方法-定时操作
    的头像 发表于 11-09 17:41 623次阅读
    <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列产品</b><b class='flag-5'>Timer</b>的基本<b class='flag-5'>使用方法</b>-定时操作

    MCU微课堂 | CKS32F4xx系列产品SPI通信

    MCU微课堂 | CKS32F4xx系列产品SPI通信
    的头像 发表于 10-24 17:12 709次阅读
    MCU微课堂 | <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列产品</b>SPI通信

    MCU微课堂 | CKS32F4xx系列产品GPIO口配置

    MCU微课堂 | CKS32F4xx系列产品GPIO口配置
    的头像 发表于 10-24 15:14 788次阅读
    MCU微课堂 | <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列产品</b>GPIO口配置

    CKS32F4xx系列FSMC功能简介

    本课讲为大家讲解CKS32F4xx系列产品的FSMC应用实例,FSMC全称是Flexible Static Memory Controller,读作灵活的静态存储控制器,顾名思义,MCU可以通过FSMC扩展静态内存
    的头像 发表于 04-14 15:06 953次阅读
    <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>FSMC功能简介