GD32450i-EVAL学习笔记 8 - Timer & PWM

21 篇文章 37 订阅

目录

1. 定时器时钟设定

2. GPIO初始化

​3. 定时器Timer初始化

3.1 使能RCU

3.2 设置分频比

3.3 设置计数方式

3.3.1 向上计数

3.3.2 向下计数

3.3.3 中央对齐

3.4 设置时钟分频

3.5 设置自动重载值

4. 通道设定

4.1 通道枚举

4.2 输出捕获初始化

4.2.1 通道控制寄存器TIMERx_CHCTL0和TIMERx_CHCTL1

4.2.2 通道控制寄存器2 (TIMERx_CHCTL2)

4.2.3  影子寄存器

5. 设置占空比


GD32F450最多有14组Timer,这些定时器分成5种类型。

 定时器的常规作用是测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和 PWM)等

1. 定时器时钟设定

定时器的时钟源包括APB1和APB2,每个定时器根据芯片设定链接到不同APB,然后由时钟配置寄存器 1 (RCU_CFG1)的TIMERSEL位决定是APB频率的2倍还是4倍,但是这个频率不能超过AHB(最大200MHz)。

 为了程序的简单性,可以设置每个Timer的频率都为最大值200MHz。

2. GPIO初始化

PWM需要对应TIMER的通道管脚上,可以查看Datasheet的管脚定义,例如官方例程中用到的PB10,对应TIMER1的CH2。

3. 定时器Timer初始化

3.1 使能RCU

rcu_periph_clock_enable(RCU_TIMERx);
rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);

x的范围0-13。

3.2 设置分频比

timer_initpara.prescaler = SystemCoreClock / clk - 1;

这里的配置是当前面设置的定时器时钟为SystemCoreClock的情况(这里就是对应AHB的频率2,000,000Hz)。clk是频率,比如clk为10,000(1MHz,表示定时器每1us计数一次),presaler = 199。

3.3 设置计数方式

计数方式分为向上计数、向下计数、中央对齐三种方式。这3种方式由控制寄存器 0 (TIMERx_CTL0) 的CAM[1:0]和DIR选择。

默认采用向上计数。

3.3.1 向上计数

计数器从0计数到自动加载值,然后重新从0开始计数并且产生一个计数器溢出事件。

CAM[1:0] = 0b00,DIR = 0即

timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection  = TIMER_COUNTER_UP;

3.3.2 向下计数

计数器从自动装入的值开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器溢出事件。

CAM[1:0] = 0b00,DIR = 1即

timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection  = TIMER_COUNTER_DOWN;

3.3.3 中央对齐

计数器从0开始计数到自动装入的值 - 1,然后向下计数到1,然后再从0开始重新计数。中央对齐只用在通道设置为输出的情况。

溢出事件有3种方式,由CAM[1:0]决定

#define TIMER_COUNTER_CENTER_DOWN           CTL0_CAM(1)
#define TIMER_COUNTER_CENTER_UP             CTL0_CAM(2)
#define TIMER_COUNTER_CENTER_BOTH           CTL0_CAM(3)
timer_initpara.counterdirection  = TIMER_COUNTER_CENTER_DOWN;
中央对齐向下计数置 1 模式:只有在向下计数时才会产生溢出事件。
timer_initpara.counterdirection  = TIMER_COUNTER_CENTER_UP;
中央对齐向上计数置 1 模式:只有在向上计数时才会产生溢出事件。
timer_initpara.counterdirection  = TIMER_COUNTER_CENTER_BOTH;
中央对齐上下计数置 1 模式:在向上和向下计数时都会产生溢出事件。

3.4 设置时钟分频

设置定时器时钟 (TIMER_CK) 与死区时间和采样时钟 (DTS) 之间的分频系数,死区发生器和数字滤波器会用到 DTS 时间。
timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
默认DIV1,即 f DTS =f TIMER_CK。

3.5 设置自动重载值

timer_initpara.period = period;

4. 通道设定

并不是所有定时器有通道,每个定时器最多4路通道。定时器0和7属于高级定时器,常用于PWM控制电机。一共有32个通道,枚举如下:

enum
{
    HW_TIMER_CH_0 = 0,  //TIMER0_CH0:PE9/PA8
    HW_TIMER_CH_1,      //TIMER0_CH1:PE11/PA9
    HW_TIMER_CH_2,      //TIMER0_CH2:PE13/PA10
    HW_TIMER_CH_3,      //TIMER0_CH3:PE14/PA11
    HW_TIMER_CH_4,      //TIMER1_CH0:PA0/PA5/PA15/PB8
    HW_TIMER_CH_5,      //TIMER1_CH1:PA1/PB3/PB9
    HW_TIMER_CH_6,      //TIMER1_CH2:PA2/PB10
    HW_TIMER_CH_7,      //TIMER1_CH3:PA3/PB2/PB11
    HW_TIMER_CH_8,      //TIMER2_CH0:PA6/PC6/PB4
    HW_TIMER_CH_9,      //TIMER2_CH1:PA7/PC7/PB5
    HW_TIMER_CH_10,     //TIMER2_CH2:PB0/PC8
    HW_TIMER_CH_11,     //TIMER2_CH3:PB1/PC9
    HW_TIMER_CH_12,     //TIMER3_CH0:PD12/PB6
    HW_TIMER_CH_13,     //TIMER3_CH1:PD13/PB7
    HW_TIMER_CH_14,     //TIMER3_CH2:PD14/PB8
    HW_TIMER_CH_15,     //TIMER3_CH3:PD15/PB9
    HW_TIMER_CH_16,     //TIMER4_CH0:PA0/PH10
    HW_TIMER_CH_17,     //TIMER4_CH1:PA1/PH11
    HW_TIMER_CH_18,     //TIMER4_CH2:PA2/PH12
    HW_TIMER_CH_19,     //TIMER4_CH3:PA3/PI0
    HW_TIMER_CH_20,     //TIMER7_CH0:PC6/PI5
    HW_TIMER_CH_21,     //TIMER7_CH1:PC7/PI6
    HW_TIMER_CH_22,     //TIMER7_CH2:PC8/PI7
    HW_TIMER_CH_23,     //TIMER7_CH3:PC9/PI2
    HW_TIMER_CH_24,     //TIMER8_CH0:PE5/PA2
    HW_TIMER_CH_25,     //TIMER8_CH1:PE6/PA3
    HW_TIMER_CH_26,     //TIMER9_CH0:PF6/PB8
    HW_TIMER_CH_27,     //TIMER10_CH0:PF7/PB9
    HW_TIMER_CH_28,     //TIMER11_CH0:PH6/PB14
    HW_TIMER_CH_29,     //TIMER11_CH1:PH9/PB15
    HW_TIMER_CH_30,     //TIMER12_CH0:PF8/PA6
    HW_TIMER_CH_31,     //TIMER13_CH0:PF9/PA7
    HW_TIMER_CH_MAX,
};

4.1 通道枚举

void timeGetCH(uint8_t chPort, uint8_t *timer, uint8_t *ch)
{
    switch(chPort)
    {
        case HW_TIMER_CH_0:
        case HW_TIMER_CH_1:
        case HW_TIMER_CH_2:
        case HW_TIMER_CH_3:
            *timer = HW_TIMER0;
            *ch = chPort - HW_TIMER_CH_0;
            break;
        case HW_TIMER_CH_4:
        case HW_TIMER_CH_5:
        case HW_TIMER_CH_6:
        case HW_TIMER_CH_7:
            *timer = HW_TIMER1;
            *ch = chPort - HW_TIMER_CH_4;
            break;
        case HW_TIMER_CH_8:
        case HW_TIMER_CH_9:
        case HW_TIMER_CH_10:
        case HW_TIMER_CH_11:
            *timer = HW_TIMER2;
            *ch = chPort - HW_TIMER_CH_8;
            break;
        case HW_TIMER_CH_12:
        case HW_TIMER_CH_13:
        case HW_TIMER_CH_14:
        case HW_TIMER_CH_15:
            *timer = HW_TIMER3;
            *ch = chPort - HW_TIMER_CH_12;
            break;
        case HW_TIMER_CH_16:
        case HW_TIMER_CH_17:
        case HW_TIMER_CH_18:
        case HW_TIMER_CH_19:
            *timer = HW_TIMER4;
            *ch = chPort - HW_TIMER_CH_16;
            break;
        case HW_TIMER_CH_20:
        case HW_TIMER_CH_21:
        case HW_TIMER_CH_22:
        case HW_TIMER_CH_23:
            *timer = HW_TIMER7;
            *ch = chPort - HW_TIMER_CH_20;
            break;
        case HW_TIMER_CH_24:
        case HW_TIMER_CH_25:
            *timer = HW_TIMER8;
            *ch = chPort - HW_TIMER_CH_24;
            break;
        case HW_TIMER_CH_26:
            *timer = HW_TIMER9;
            *ch = chPort - HW_TIMER_CH_26;
            break;
        case HW_TIMER_CH_27:
            *timer = HW_TIMER10;
            *ch = chPort - HW_TIMER_CH_27;
            break;
        case HW_TIMER_CH_28:
        case HW_TIMER_CH_29:
            *timer = HW_TIMER11;
            *ch = chPort - HW_TIMER_CH_28;
            break;
        case HW_TIMER_CH_30:
            *timer = HW_TIMER12;
            *ch = chPort - HW_TIMER_CH_30;
            break;
        case HW_TIMER_CH_31:
            *timer = HW_TIMER13;
            *ch = chPort - HW_TIMER_CH_31;
            break;
        default:
            *timer = HW_TIMER_MAX;
            break;
    }
}

4.2 输出捕获初始化

PWM用到的是Timer的输出捕获功能,输出捕获功能可以支持2种PWM模式,PWM0和PWM1。而根据计数模式也可以分为两种PWM 波:EAPWM(边沿对齐PWM)和CAPWM(中央对齐
PWM)。

 

4.2.1 通道控制寄存器TIMERx_CHCTL0和TIMERx_CHCTL1

这2个寄存器分通道输出还是输入。每8个位对应一个通道,上面的定义是输出的配置,下面的是输入的配置。
CHxMS[1:0]: 通道I/O模式选择, 0b00配置为输出,其他值是输入。
CHxCOMFEN: 输出比较快速使能。为0时通道输出最小延时为5个时钟周期,为1时是3个时钟周期
CHxCOMSEN: 输出比较影子寄存器使能。
CHxCOMCTL[2:0]: 110:PWM 模式0。111:PWM 模式1。
CHxCOMCEN: 输出比较清0使能。当此位被置1,当检测到ETIF输入高电平时,O0CPRE参考信号被清0。

4.2.2 通道控制寄存器2 (TIMERx_CHCTL2)

每4位控制一个通道,注意通道3没有互补输出。
CHxEN: 通道使能
CHxP: 通道极性。0表示高电平有效;1表示低电平有效
CHxNEN: 互补输出使能。
CHxNP: 互补通道极性,同CHxP。

4.2.3  影子寄存器

设置影子寄存器后,用户设定的值->寄存器->影子寄存器->work,未设置的情况下,用户设定的值->寄存器->work,这样影子寄存器起到缓冲的作用。

    timer_ocintpara.ocpolarity  = TIMER_OC_POLARITY_HIGH;
    timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
    timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
    timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
    timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
    timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
    timer_channel_output_config(timer, ch, &timer_ocintpara);
    
    timer_channel_output_pulse_value_config(timer, ch, 0);
    timer_channel_output_mode_config(timer, ch, TIMER_OC_MODE_PWM0);
    timer_channel_output_shadow_config(timer,ch, TIMER_OC_SHADOW_DISABLE);
    timer_auto_reload_shadow_enable(timer);
    /* TIMERx enable */
    timer_enable(timer);

5. 设置占空比

*((uint32_t *)&TIMER_CH0CV(timer) + ch) = ((TIMER_CAR(timer) + 1) * duty) / 100;

占空比的值从0到100。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值