外观
十二、PWM输出实验
PWM基础知识
什么是PWM
PWM(Pulse-width modulation)是脉冲宽度调制的缩写。脉冲宽度调制是一种模拟信号电平数字编码方法。脉冲宽度调制PWM是通过将有效的电信号分散成离散形式从而来降低电信号所传递的平均功率的一种方式。所以根据面积等效法则,可以通过对改变脉冲的时间宽度,来等效的获得所需要合成的相应幅值和频率的波形。
GD32PWM介绍
前面我们介绍了GD32E230C8T6一共有7个定时器,可以分为六种类型,高级定时器0、通用定时器(L0)2、通用定时器(L2)13、通用定时器(L3)14、通用定时器(L4)15/16和基本定时器5。
而PWM功能就是在定时器的基础上实现的,但不是所有的定时器都支持PWM输出功能。
从《GD32E230用户手册》上可以了解到:
- 高级定时器拥有4个PWM通道;
- 通用定时器L0拥有4个PWM通道
- 通用定时器L2拥有1个PWM通道;
- 通用定时器L3拥有2个PWM通道;
- 通用定时器L4拥有1个PWM通道;
- 基本定时器没有PWM通道。
每一个PWM通道都对应单片机的一个管脚,这个引脚不是唯一固定的,可能有一个或者两个管脚都对应同一个通道。比如说TIMER14_CH0对应PA2和PB14,就是说PA2和PB14管脚都可以配置为定时器的通道0,我们在使用的时候可以任选其一进行配置。
PWM基本参数
PWM是脉冲宽度调制,具有两个非常重要的参数:频率和占空比。
- 频率:PWM的频率是整个周期的倒数。
- 占空比:占空比是指一个周期内高电平所占的比例。
控制方法
控制方式就是对逆变电路开关器件的通断进行控制,使输出端得到一系列幅值相等但宽度不一致的脉冲,用这些脉冲来代替正弦波或所需要的波形。也就是在输出波形的半个周期中产生多个脉冲,使个脉冲的等值电压为正弦波形,所获得的输出平滑且低次谐波少。按一定的规则对各脉冲的宽度进行调制,即可改变电路输出电压的大小,也可改变输出频率。
PWM应用原理图
底板使用2*2.54排针接口将PWM信号(PA2)进行引出,方便使用示波器进行测量。
PWM输出
项目介绍
通过本次实验,实现引脚PA2输出占空比50%频率为1kHz的方波。
配置流程
一般使用定时器PWM功能,都需要有以下几个步骤:
- 配置通道引脚GPIO;
- 配置定时器;
- 配置输出结构体;
- 配置定时器输出通道;
- 配置定时器输出通道占空比;
- 定时器自动重载使能。
配置通道引脚GPIO
从上方原理介绍已经了解到,PWM信号通过PA2进行输出,通过查找《GD32E230数据手册》可以看到PA2对应定时器14通道0;
这里选择PA2的复用功能AF0模式进行映射。
使用GPIO引脚功能以及定时器功能,需要打开其时钟,然后对GPIO引脚进行配置,使其映射到AF0模式下:
C
//使能时钟
rcu_periph_clock_enable(RCU_GPIOA);
//使能定时器14时钟
rcu_periph_clock_enable(RCU_TIMER14);
//GPIO复用模式设置--PA2-TIMER14_CH0
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_2);
//输出类型设置
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_2);
//复用模式0
gpio_af_set(GPIOA, GPIO_AF_0, GPIO_PIN_2);
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
配置定时器
PWM输出依赖定时器,所以需要对定时器进行配置,但是PWM输出并不需要使用到定时器中断功能,所以无需配置中断。
- 在配置定时器前,在函数最前方定义定时器参数结构体:
- 在配置参数前,先对定时器以及定时器参数结构体进行初始化,确保其在初始状态。
C
//定时器初始化参数结构体
timer_parameter_struct timer_initpara;
1
2
2
C
//复位定时器14
timer_deinit(TIMER14);
//初始化定时器结构体参数
timer_struct_para_init(&timer_initpara);
1
2
3
4
5
2
3
4
5
配置定时器参数,注意参数设置:
要求输出1KHz,系统时钟为72MHz(72_000_000);
预分频器参数为(71+1),定时器频率为(1_000_000);
周期设置为1000-1;
C
timer_initpara.prescaler = 71; //预分频器参数
timer_initpara.alignedmode = TIMER_COUNTER_EDGE; //边沿对齐
timer_initpara.counterdirection = TIMER_COUNTER_UP; //向上计数
timer_initpara.period = 999; //周期
timer_initpara.clockdivision = TIMER_CKDIV_DIV1; //时钟分频
timer_initpara.repetitioncounter = 0; //重装载值
timer_init(TIMER14, &timer_initpara);
1
2
3
4
5
6
7
2
3
4
5
6
7
自此,定时器参数设置完成。
配置输出结构体
要使用定时器的PWM功能就是用定时器的输出功能,PWM输出的相关参数通过定时器通道输出参数结构体进行配置。
- outputstate: 通道输出状态(打开或关闭)
- outputnstate: 通道互补输出状态(打开或关闭)互补是指定时器的两个通道在波形输出上完全相反,形成互补,常用与H桥驱动电路上,这里无需打开;
- ocpolarity: 输出极性,也就是配置为低电平有效还是高电平有效,通常配合PWM模式使用
- ocnpolarity: 互补输出极性
- ocidlestate: 空闲状态通道输出
- ocnidlestate: 空闲状态互补通道输出
在配置输出状态前,先在函数最前方对输出参数结构体进行定义;
在使用先进行初始化,确保其在初始状态;
C
//定时器输出参数结构体
timer_oc_parameter_struct timer_ocinitpara;
1
2
2
C
//初始化定时器通道输出参数结构体
timer_channel_output_struct_para_init(&timer_ocinitpara);
timer_ocinitpara.outputstate = TIMER_CCX_ENABLE; //输出状态,主输出通道开启
timer_ocinitpara.outputnstate = TIMER_CCXN_DISABLE; //互补输出状态关闭
timer_ocinitpara.ocpolarity = TIMER_OC_POLARITY_HIGH; //输出极性为高
timer_ocinitpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH; //互补输出极性为高
timer_ocinitpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW; //空闲状态通道输出低
timer_ocinitpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; //空闲状态互补通道输出低
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
配置定时器输出通道
配置好输出通道参数后,需要将该参数传入定时器对应通道中,
该函数有三个参数:参数1是定时器外设、参数2是对应通道号、参数3是通道配置结构体。
C
//通道输出配置
timer_channel_output_config(TIMER14, TIMER_CH_0, &timer_ocinitpara);
1
2
2
配置定时器输出通道占空比
这里对第三个参数比较值进行说明,
pulse--比较值参数,使用它来于计数器进行比较,加上周期最大值是1000,比较值设置为500,那么就是有一半的时间是低于比较值的,一半的时间是高于比较值的,形成两个区间,配合PWM模式也就变成了占空比设置。
C
//输出比较值
timer_channel_output_pulse_value_config(TIMER14, TIMER_CH_0, 500);
1
2
2
定时器通道输出模式设置,这里重点介绍第三个参数:
定时器通道作为PWM输出模式时,主要设置为PWM模式0或PWM模式1;
**PWM模式0:当计数器值小于比较值时,输出无效空闲电平,大于比较值时,输出有效电平;
PWM模式1:当计数器值小于比较值时,输出有效电平,大于比较值时,输出无效空闲电平; **
C
//定时器通道输出模式设置
timer_channel_output_mode_config(TIMER14, TIMER_CH_0, TIMER_OC_MODE_PWM0);
1
2
2
在输出通道配置完成后,需要对未使用的模式进行关闭,并使能自动重装载寄存器,这样才可以使定时器在一次计数完成后自动开始下一次计数;
C
//影子模式输出关闭
timer_channel_output_shadow_config(TIMER14, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE);
//使能自动重装载
timer_auto_reload_shadow_enable(TIMER14);
1
2
3
4
2
3
4
最后,对定时器通道以及定时器进行使能,打开总开关。
C
//配置定时器为主要输出函数,所有通道使能
timer_primary_output_config(TIMER14, ENABLE);
//使能定时器
timer_enable(TIMER14);
1
2
3
4
5
2
3
4
5
自此,定时器PWM输出全部配置完成。
资料下载
工程代码可前往gitee下载资料包,简易数字示波器资料包
注意事项
PWM输出无效
定时器通道输出默认是关闭的,若没打开通道仅使能定时器,会发现没有任何效果。