SRPWM 开发人员指南

文档版本

1.0

发布日期

2024-08-21

重要

版权所有 © 成都翌创微电子有限公司 2024。保留一切权利。 非经本公司书面许可,任何单位和个人不得擅自摘抄、复制本文档内容的部分或全部,并不得以任何形式传播。

模块简介

SRPWM介绍

PWM脉宽调制是电力电子应用中非常重要的一种控制技术。ET6000系列实时微控制器在SRPWM (Super Resolution PWM) 高精度PWM外设中提供了许多差异化功能,具备灵活的周期、相位以及死区调整;丰富的同步机制;具备高级的保护功能;支持高达ps级的高精度调制。本应用手册重点介绍一 些常规的应用,演示SRPWM的每项特性以及部分代码演示。本应用手册是根据ET6001芯片编写的,但是本应用手册中的内容也适用于ET6000系列,系列芯片间存在的差异点,具体参考其他文档。

主要特性

  • 支持输出12个通道共24路PWM

  • 每个通道输出2路PWM

  • 每个通道的2路PWM可配置为独立或互补关系

  • 支持多个定时单元

  • 12个16位定时单元,可任意配置为独立或主从关系(通过2路同步信号同步)

  • 每个通道均支持输入2路同步信号和输出2路同步信号

  • 支持高精度功能

  • 每个通道的周期、占空比以及死区可独立进行高精度调整

  • 高精度调整功能可旁路

  • 高精度可达156 ps(不同芯片可能有差异)

  • 支持丰富的比较事件

  • 每个通道4个主比较器和4个从比较器

  • 可配置1个周期内单次比较或多次比较

  • 可配置大于等于,小于等于、等于

  • 可作为同步信号输出

  • 支持丰富的波形生成事件PG(PWM Generate)

  • 每个通道支持22种事件生成PWM

  • 每个通道的2路PWM可独立配置波形生成事件

  • 支持突发发波模式

  • 支持丰富的保护机制

  • 支持异常信号预处理

  • 统计

  • 滤波

  • Blanking功能

  • 支持前级保护

  • 每个通道4路异常信号输入。

  • 多种保护模式:CBC模式、One-shot模式、立即封波模式

  • 保护起始结束时机可配

  • 多种保护动作:置0、置1、高阻、取反

  • 支持后级保护

  • 每个通道2路异常信号输入

  • 多种保护动作:不动作、置0、置1、高阻

  • 通道内和通道间的互斥保护

  • 互斥保护条件可配

  • 支持4路DMA

  • 12个通道共用4路DMA

  • 支持12路中断

  • 每路中断支持14种中断源,其中事件中断源支持24种中断事件

  • 支持连接到片内模拟外设

  • 提供12路信号给每一个ADC

  • 提供1路信号给每一个DAC

  • 提供1路信号给每一个ACMP

  • 支持广播更新寄存器功能

  • 全部通道或者任意指定通道同时配置

  • 支持关键参数寄存器多种加载模式

  • 立即加载模式

  • 通道间同步加载模式

  • 通道内影子加载模式

  • 支持广播更新:全部通道或者任意指定通道同时配置

本文将着重对该模块的前后级保护机制进行应用说明。

模块框图

整体框图

SPWM外设由多个PWM子模块组成,该芯片支持12组PWM组成SRPWM外设,具体如图,其中SRPWM0~11为12个PWM子模块。SRPWM COM模块为12个PWM模块的顶层公共处理模块,主要完成PWM模块间的同步互联,SRPWM0~11的公共配置,以及对外控制信号的输出选择和输入选择等功能。

008

子模块框图

PWM模块由多个子功能单元构成,如下图所示:

009

时基(TimeBase)

设置频率

时基(TB)子模块可以用于将PWM模块的频率设置为指定数字,例如400KHz。每个PWM模块内部都有一个时基计数器。默认情况下,该时基计数值不是实时上报的,当需要获取当前时基计数值时,需要通过事件锁存的方式将时基计数值锁存之后,才会上报。

PWM事件的频率(\(F_{PWM}\))由时基周期(TB_PRD)的值和时基计数器的模式共同决定。

时基计数器有两种计数模式:向上计数和向上向下双向计数(上下计数)。

对于向上计数模式:

\[T_{PWM}\ = \ TB\_ PRD\ \ast \ T_{TBCLK} \tag{1}\]
\[F_{PWM}\ = \ \frac{1}{T_{PWM}} \tag{2}\]

对于向上向下计数模式:

\[T_{PWM}\ = \ 2\ \ast \ TB\_ PRD\ \ast \ T_{TBCLK} \tag{3}\]
\[F_{PWM}\ = \ \frac{1}{T_{PWM}} \tag{4}\]

其中,\(T_{PWM}\ \)是PWM事件的周期,\(T_{TBCLK}\) 是PWM模块时基时钟的周期。该时基时钟是预分频选择之后的PWM时钟。该时钟决定时基计数器递增和递减的速率。

本应用指南中讨论的用例使用的是上下计数模式,400KHz。首先确定\(T_{PWM}\):

\[F_{PWM}\ = \ \frac{1}{T_{PWM}} \tag{5}\]
\[\]

T_{PWM} = frac{1}{400K} rightarrow 2.5mu s tag{6}

在知道\(T_{PWM}\ \)值之后,可以开始计算设置到TB_PRD寄存器的值:

\[TB\_ PRD\ = \ \frac{T_{PWM}\ }{2\ \ast \ T_{TBCLK}} \tag{7}\]

时基时钟正常情况下为200MHz,ET6001不支持模块的时钟预分频,仅能通过总线分频。需要注意的是,总线分频将会影响到其他外设的时钟。

\[T_{TBCLK}\ = \ \frac{1}{200M} \rightarrow \ 10ns \tag{8}\]

现在我们已经可以计算出TB_PRD的值了:

\[TB\_ PRD\ = \ \frac{T_{PWM}\ }{2\ \ast \ T_{TBCLK}}\ \rightarrow \ \frac{2.5\mu s\ \ }{10ns} = 125 \tag{9}\]

通过以上的参数设置,在使能PWM模块工作之后,时基计数器将会从0开始递增计数到125,然后再从125递减计数到0。

计数模式

ET6001提供了两种计数模式:向上计数(Up)和上下计数模式(UpDown)。

  • Up计数模式: 计数值到period周期值之后,重载到0继续执行。

  • UpDown计数模式: 即三角波模式,计数值递增到period-1后,从period递减,计数值递减到1之后,从0递增。

ET6001提供了两种比较模式可配:等于、大于等于或小于等于

  • 等于比较模式:当比较器的值等于时基计数器的值,产生比较事件

  • 大于等于模式:该模式仅在向上计数时有效,当时基计数器的值大于等于比较器值时,产生比较事件

  • 小于等于模式:该模式仅在向下计数时有效,当时基计数器的值小于等于比较器值时,产生比较事件

设置移相同步方案

在实际应用场景中,可能还涉及到PWM之间的相移。移相功能也是通过TB子模块实现的。 对于ET6001可以支持多种方案实现移相,以下介绍两种移相方案,总体思路大体一致,都是通过同步触发信号和时基相移值配合实现。

下面将以PWM1、PWM2、PWM3举例介绍方案的实现。周期值均为360,向上计数,同步信号到来时:向上计数,3个PWM模块之间的相移为120°。相移关系:PWM1 -> PWM2 -> PWM3。

由以上参数可知,实现三者之间相移为120°,也就是当PWM1的时基计数器为0时,PWM2的时基计数器为240,PWM3的时基计数器为120

方案一: 以TB_0PHASE寄存器为主,TB_SYNC寄存器的同步输入信号0为辅的方式

在ET6001中,PWM模块具备TB_0PHASE和TB_1PHASE两个相位寄存器,也对应了两个同步输入触发信号设置寄存器。本方案采用TB_0PHASE举例

TB_0PHASE是相位0寄存器,表示的是:当触发信号到来时,时基计数器按照该相位寄存器的值设置

配置步骤:

  1. 设置PWM的相位0寄存器

    • PWM1相位0设置为0

    • PWM2相位0设置为240

    • PWM3相位0设置为120

  2. 设置PWM的同步输入信号0

    • PWM1不做设置

    • PWM2选择同步输入信号0作为触发信号

    • PWM3选择同步输入信号0作为触发信号

  3. 设置输出到同步输入信号0的源

    • PWM1选择过零事件输出到同步输出信号0

    • PWM COM公共管理外设,选择PWM1的同步输出信号0输出到PWM2的同步输入信号0

    • PWM COM公共管理外设,选择PWM1的同步输出信号0输出到PWM3的同步输入信号0

方案二: 以TB_SYNC寄存器的同步输入信号0为主,TB_xPHASE寄存器为辅的方式

TB_0PHASE寄存器为辅的意思是,3个PWM的该寄存器值均不做修改,默认为0。主要在同步信号上做处理

配置步骤:

  1. 设置PWM的同步输入信号

    • PWM1不做设置

    • PWM2选择同步输入信号0作为触发信号

    • PWM3选择同步输入信号1作为触发信号

  2. 设置输出到同步输入信号的源

    • PWM1选择从比较器A向上事件输出到同步输出信号0;选择从比较器B向上事件输出到同步输出信号1

    • PWM COM公共管理外设,选择PWM1的同步输出信号0输出到PWM2的同步输入信号0

    • PWM COM公共管理外设,选择PWM1的同步输出信号1输出到PWM3的同步输入信号1

  3. 设置PWM1的比较事件值

    • PWM1的从比较器A设置为120

    • PWM1的从比较器B设置为240

以上两个方案从不同角度实现了三者之间的相移,在实际应用时可以灵活的选择不同方案组合。三个外设的相移推荐使用方案二,该方案从配置和原理理解上会更简单; 而方案一适合多模块之间的相移设置。方案二在相位换算上会绕一些,配合图形更易理解。

计数器比较(CMP)和波形生成(PG)

主比较器和从比较器

ET6001配备了4个主比较器和4个从比较器。

主从比较器的区别:主比较器支持更多的功能,而从比较器有部分功能是不支持的。所以,一般情况下,建议采用主比较器进行配置。

比较器可以产生多个比较事件。主比较器支持产生4个向上和4个向下的比较事件;从比较器同样支持4个向上和4个向下的比较器事件

这里比较器事件产生的详细说明,可以参考对应的用户手册,用户手册可以在官网下载

比较配置值可以在工作过程中实时更新,且更新时刻可以同步于指定的触发事件。在下图中,定时器配置为向上计数模式,主比较器比较条件配置为大于等于比较配置值,图中给出了不同更新场景下的比较事件脉冲产生情况:

010

上图中cmp_old和cmp_new分别对应比较配置值的老值和新值,update是指新配置值更新时刻,垂直方向的箭头是指产生比较事件脉冲出现的时刻。

下图与上图更新场景相同,但比较条件配置为等于时,场景b)在当前PWM周期内无法产生向上比较脉冲,因为场景b)中新配置值更新时刻,定时计数值已大于比较配置值。类似的情形也适用于向下计数方向。

011

由于4个从比较器只支持等于条件产生比较事件,因此比较事件产生的方式配置为大于等于还是等于条件产生时,并不影响从比较事件的产生。

ET6000系列的主从比较器还支持配置在向上或者向下方向是否仅产生一次比较脉冲,或者产生多次比较脉冲。

PG子模块介绍

PG(PWM Generate)子模块为PWM波形生成模块,也可以理解为动作矩阵模块。

ET6000系列的PG模块支持丰富的动作事件,不同的动作事件对应4种动作类型。通过不同的动作事件对应不同的动作,构成动作矩阵,从而组合出不同的PWM波形。

以ET6001为例,6001支持多达22种动作事件,同时还可以响应软件事件强制产生PWM波。对于动作事件,还支持动作优先级可配置:即在一个可配时间内,如果多个动作事件同时发生,只响应优先级高的事件。其中软件强制事件优先级最高,具体的优先级排序参考用户手册。

需要注意的是,在实际应用场景中,PG模块的软件强制事件和PREP/PSTP模块一样是可以用来做封波处理的,但是模块链路排布中,PG模块相对于PSTP模块靠前,所以封波会有一定的延迟。

下图为举例PG模块的应用。从下图可以看出,

A路:

  • cmp_up[2]比较器C向上事件发生时,产生置1动作

  • prd周期事件发生时,产生置0动作

B路:

  • cmp_up[3]比较器D向上事件发生时,产生置1动作

  • prd周期事件发生时,产生置0动作

012

计算占空比

占空比的计算和定时器计数模式、PG模块等相关,下面以一种配置方式进行举例说明

定时器采用UP计数模式,动作矩阵的配置为比较值A向上事件置0,过零事件置1

计算公式如下:

\[duty\ = \ cmp\ \ /\ \ prd\ \ast \ 100\%\]

如下图所示的波形

013

死区(DeadBand)

设置信号对

为了产生互补的波形,需要提前设置一对信号波形,为了将这对信号生成带死区的互补波形,则需要利用DB子模块。特别是在数字电源控制中,一般要求上下管的开关具有一定死区,在电平翻转时插入一定时间间隔避免上下管同时导通。虽然可以通过配置不同的比较值以实现死区调整,但是这种配置即不灵活,也不方便,所以接下来,我 们将采用DB子模块来构造死区波形

014

ET6001具备12组SRPWM,每一组SRPWM均具备A/B两路可输出的PWM。从死区子模块框图可以看出,它的本质其实就是几个开关组合。 S0a和s0b决定了最终输出波形的源信号:PWMa和PWMb。当我们希望生成的A/B路PWM输出具有相同的源信号,则将两个开关均设置为PWMa输入或者PWMb输入。相同的源可以更好地保障了硬件死区的可靠性。

S1a和S1b决定了是否产生上升沿延迟;

s2a和s2b决定了是否产生下降沿延迟;

S3a和s3b决定了是否采用沿延迟后的输出,来作为死区子模块的最终输出。

具体的死区时间就是rising edge delay模块的设置值乘上PWM模块主频。

Burst发波

Burst发波的介绍

Burst发波模块主要进行打嗝发波的控制,例如LLC轻载场景。

015

Burst发波模块位于死区模块调整输出之后,也就是说死区调整输出的PWM波信号可进一步进行打嗝发波处理,设置重复的打嗝周期(每个打嗝周期包含若干个PWM波周期),在每个打嗝周期内指定发送若干个周期的PWM波,其余时间则不发波。通过这种打嗝处理方式,可以达到斩波的效果

设置burst波形

具体发波模型如下:

016

即在M个发波周期内,有N个波不发,发送M-N个波;

M和N是可以配置的,同时支持配置N个波先发送或者先不发送,即N个波产生在M周期内的前部分还是后部分;

故障信号预处理模块(FPP)

FPP功能介绍

FPP是PWM外设用于接收外部信号的子模块;当然,也可以通过PWM COM这个顶层外设给PWM传入部分信号。PWM COM传入的信号主要用于同步处理,而FPP主要是用于对故障信号的处理。下图是FPP模块在PWM外设中的位置。

017

从图中可以看到,FPP模块仅接收来自XBAR外设传入的信号。需要注意的是,FPP模块的输入和输出在不同的芯片型号可能有部分区别。例如ET6001的FPP支持传入来自XBAR的6个并行信号,并将前4个信号输出到PG模块和PREP前级保护模块,将后2个信号输出到PSTP后级保护模块;但是对于ET6001 ,FPP支持传入来自XBAR的6个并行信号,并将6个信号输出到PG模块和PREP前级保护模块,不再将信号传入PSTP后级保护模块。

信号的处理

FPP模块可以对传入的信号进行预处理,包括上、下沿选择、blanking操作、锁存处理等,处理后产生Fault上升沿事件(fpp_fault_pos)、Fault实时事件(fpp_fault_real)和fault锁存事件(fpp_fault_latch)。其中上升沿事件可用于定时器时基同步、参数影 子加载和PG发波动作设置;实时事件和锁存事件可用于封波保护和中断产生。

通过XBAR传入的6个信号为并行关系,互不影响。关系如下图所示:

018

从图中可以看到,从XBAR传入的信号,根据信号顺序分成了0到5,每个信号传入对应序号的fault_proc_unit单元,通过单元之后,并行输出几类事件。单元0~3产生3类事件,单元4~5产生2类事件。

需要特别注意FPP的blanking功能,该功能可以被用作PCM峰值电流型的应用场景。Blanking功能是指产生一个数据处理有效区域,只处理该区域内出现的fault信号,在有效区域时段之外的fault信号将被抛弃,不做处理。关于blanking更详细的说明,可以参考对应的用户手册章节

前级保护(PREP)和后级保护(PSTP)

SRPWM模块包含了前级保护PREP(pre-protect)和后级保护PSTP(post- protect)两级的保护逻辑,可以再外部电路发生故障或芯片内部出现告警时将输出的PWM波信号设置为预置的安全状态。其中前级保护基于SRPWM模块工作时钟驱动,后级保护的保护行为无需时钟驱动,且后级保护相对于前级保护将会快3个clk的时间进行保护

前级保护(PREP)功能介绍

019

从图中可以看到前级保护的保护信号来自于片内的XBAR模块。XBAR的输入信号可以来自于ACMP、SOC告警、GPIO输入的故障信号,XBAR输出6路异常信号到SRPWM通道,并由通道内异常预处理单元FPP(Fault Pre-Proccess)输出给前级保护单元和后级保护单元。

其中前级保护单元接受来自FPP的前4路,前4路异常信号可分为(不同系列芯片有差异):

  • 4路实时的异常信号

  • 4路锁存的异常信号

前级保护状态可分为:

  • 高阻状态

  • 置0状态

  • 置1状态

  • 连续取反状态

前级保护有3种保护模式:

  • CBC(逐周期)保护模式:异常信号到来时,PWM立即保护;异常信号消失时,需要等待结束信号到来后再回复PWM保护前的输出状态。

  • OS(One-Shot)保护模式:可配置保护的起始和结束时刻。

    • 若使能了保护的起始和结束功能,PWM进入保护和退出保护状态,需要根据起始和结束同步信号以及异常信号的到来和消失共同决定;

    • 若未使能保护的起始和结束功能,异常信号到来时,立即保护,异常信号消失时,立即退出保护;

    • 若仅使能保护的起始功能,异常信号和起始信号均到来时,进入保护状态,异常信号消失时,立即退出保护;

    • 若仅使能保护的解锁信号,异常信号到来时,立即保护,异常信号和结束信号均到来时,退出保护状态;

  • UNRES(无约束)立即保护模式:异常信号到来时,立即保护;异常信号消失时,立即退出保护。

针对上述三种保护模式,均可独立配置其对应的保护动作。每个通道的两路PWM(A路和B路)均可独立配置

备注

上述三种保护模式可同时开启。当不同保护模式的不同动作事件同时出现时,动作的优先级从高到低依次为:高阻 > 置0 > 置1 > 连续取反;当不同保护模式的同一种动作的不同触发事件不同时出现时,保护动作的开始与最早开始的动作事件对齐,保护动作的结束与最晚结束的动作事件对齐。举例如下:

020

后级保护(PSTP)功能介绍

021

从图中可以看到后级保护的保护信号来自于片内的XBAR。XBAR的输入信号可以来自于ACMP、SOC告警、GPIO输入的故障信号,XBAR输出6路异常信号到SRPWM通道,并由通道内异常预处理单元FPP(Fault Preprocess)输出给前级保护单元和后级保护单元。

其中后级保护单元接收来自FPP的后2路异常信号。同时,后级保护单元还可以进行SRPWM通道间和通道内的互斥保护。且均支持保护状态的取反,和A/B路的输出状态swap交换。

异常保护

来自FPP的后2路异常信号可分为:

  • 2路实时的异常信号

  • 2路锁存的异常信号

后级的异常保护状态可分为:

  • 不动作

  • 置1状态

  • 置0状态

  • 高阻状态

后级保护单元仅一种默认的保护模式:

  • 立即保护

互斥保护

后级保护单元支持SRPWM通道间和通道内的互斥保护。

通道间保护

SRPWM COM公共管理模块将12个SRPWM通道输出的24路发波信号,根据软件配置,重新组合成12对信号(sig0 和sig1),每一对信号根据互斥条件产生12组互斥结果。根据互斥屏蔽的选择,将未屏蔽的互斥结果做或运算之后,形成互斥标志送往后级保护单元。

支持的通道间互斥条件为:

  • 由SRPWM COM公共管理模块配置的互斥条件

支持的通道间互斥状态为:

  • 不动作

  • 置1状态

  • 置0状态

  • 高阻状态

通道内保护

支持的通道内A/B路互斥条件为:

  • A低B低

  • A低B高

  • A高B低

  • A高B高

后级的互斥保护状态可分为:

  • 不动作

  • 置1状态

  • 置0状态

  • 高阻状态

在应用笔记AN0002中有更加详细的代码应用示例。比较器封波和GPIO封波是电源控制中常见的场景,在该文档中,重点针对比较器和GPIO封波的应用进行讲解。

通过GPIO封波

从前级保护单元在SRPWM通道内的位置和后级保护单元在SRPWM通道内的位置可以看到,前后级保护需要借助XBAR模块,将异常信号送入SRPWM的前后级保护单元进行保护; 而后级保护仅后级保护单元支持,无需XBAR模块支持。

在配置XBAR时需要注意,XBAR可以送出18路异常信号给SRPWM,而每一个SRPWM仅支持6路来自XBAR的异常信号,所以XBAR将18路异常信号分为3组分别送往SRPWM。

对应关系如下:

  • PFXB_OUT[5:0] -> PWM_CH0~3

  • PFXB_OUT[11:6] -> PWM_CH4~7

  • PFXB_OUT[17:12] -> PWM_CH8~11

SRPWM的前级保护具备三种保护模式:CBC保护、OS保护、UNRES无约束保护。

下面以UNRES无约束保护举例。

UNRES无约束保护:顾名思义,异常信号到来就保护,异常信号消失就恢复。

通过GPIO作为保护信号,并输出给XBAR,再通过XBAR输出给SRPWM进行UNRES无约束封波保护。

代码分成3个部分进行:GPIO配置、XBAR配置、SRPWM配置,需包含各自驱动的头文件

  • GPIO配置 :

将GPIO0_15配置为输入,并作为XBAR的信号输入。

/**
* @brief 配置GPIO
*          将GPIO0_15配置为输入,作为XBAR的输入
*
* @return static
*/
static void GPIO_Config(void)
{
   IOC_Init_TypeDef Init;
   IOC_ConfigStructInit(&Init);
   Init.mode = IOC_AF_MODE_0;
   Init.dir  = GPIO_DIR_IN_OUT;
   IOC_Config(IOC_PIN_GPIO0_15, &Init);
}
  • XBAR的配置 :

作为一个中转,将GPIO0_15状态送往SRPWM进行封波。

/**
* @brief 配置XBAR
*          GPIO0_15 作为XBAR的输入,并给到SRPWM 作为异常保护信号
*          高电平封波,需注意GPIO0_15上电后的默认电平
*
*/
static void XBAR_Config(void)
{
   XBAR_INXB_InCfg_TypeDef  inputCfg;
   XBAR_PFSXB_InCfg_TypeDef pfxb_inputCfg;
   XBAR_InChMsk_TypeDef     inputChMsk;

   memset(&inputCfg, 0, sizeof(XBAR_INXB_InCfg_TypeDef));
   memset(&pfxb_inputCfg, 0, sizeof(XBAR_PFSXB_InCfg_TypeDef));
   memset(&inputChMsk, 0, sizeof(XBAR_InChMsk_TypeDef));

   /* INXBAR初始化 */
   inputCfg.inEdgeEn   = DISABLE;
   inputCfg.inFilterEn = DISABLE;
   inputCfg.inInvertEn = DISABLE;
   inputCfg.inEdgeType = XBAR_IN_EDGE_RISING;
   /* 选择INXBAR的输入源:GPIO0_15 */
   XBAR_Input_Add_Source(&inputChMsk, INXB_SRC_GPIO0_GRP + 15);
   XBAR_INXB_Input_Channel_Init(&inputCfg, &inputChMsk);
   /* 选择INXBAR的输出通道:0 */
   XBAR_INXB_Output_Mux_Config((uint16_t)BIT_MASK(0), &inputChMsk);
   /* 失能INXBAR的latch和invert */
   XBAR_INXB_Output_Latch_Disable((uint16_t)BIT_MASK(0));
   XBAR_INXB_Output_Invert_Disable((uint16_t)BIT_MASK(0));
   /* 使能INXBAR的输出功能 */
   XBAR_INXB_Output_Enable((uint16_t)BIT_MASK(0));
   /* FPXBAR初始化 */
   pfxb_inputCfg.inEdgeEn   = DISABLE;
   pfxb_inputCfg.inInvertEn = DISABLE;
   pfxb_inputCfg.inEdgeType = XBAR_IN_EDGE_RISING;
   /* 选择FPXBAR的输入源: PFSXB_SRC_INXB_OUT_FRP+0*/
   memset(&inputChMsk, 0, sizeof(XBAR_InChMsk_TypeDef));
   XBAR_Input_Add_Source(&inputChMsk, PFSXB_SRC_INXB_OUT_GRP + 0);
   XBAR_PFXB_Input_Channel_Init(&pfxb_inputCfg, &inputChMsk);
   /* 选择FPXBAR的输出通道:0 */
   /* OUT:
   PFXB_OUT[5:0]-> PWM_CH0~3
   PFXB_OUT[11:6]-> PWM_CH4~7
   PFXB_OUT[17:12]-> PWM_CH8~11
   */
   XBAR_PFXB_Output_Mux_Config((uint16_t)BIT_MASK(0), &inputChMsk);
   /* 失能FPXBAR的latch和invert */
   XBAR_PFXB_Output_Latch_Disable((uint16_t)BIT_MASK(0));
   XBAR_PFXB_Output_Invert_Enable((uint16_t)BIT_MASK(0));
   /* 使能FPXBAR的输出功能 */
   XBAR_PFXB_Output_Enable((uint16_t)BIT_MASK(0));
}
  • SRPWM的配置 :

将SRPWM0的B路配置为前级保护,UNRES保护状态为置0。

static void SRPWM_Config(void)
{
   SRPWM_TBInitTypeDef stTBInit;
   SRPWM_CMPInitTypeDef stCMPInit;
   SRPWM_PREPInitTypeDef stPREPInit;
   IOC_Init_TypeDef Init;

   /* 复位SRPWM0,并开启SRPWM0的时钟 */
   CRG_PeriphReset(CRG_SRST_SRPWM0);
   /* IO mux配置 */
   IOC_ConfigStructInit(&Init);
   Init.mode = IOC_AF_MODE_1;
   IOC_Config(IOC_PIN_GPIO0_1, &Init); //pwm0b
   /* TB初始化 */
   SRPWM_TBStructInit(&stTBInit);
   stTBInit.period    = 0xC350;
   stTBInit.countMode = SRPWM_COUNTMODE_UP;
   SRPWM_TBInit(SRPWM0, &stTBInit);
   /* CMP初始化 */
   SRPWM_CMPStructInit(&stCMPInit);
   stCMPInit.cmpA = 0xC350 / 4;
   SRPWM_CMPInit(SRPWM0, &stCMPInit);
   /* PG初始化 */
   SRPWM_SetPG(SRPWM0, SRPWM_PWMB, SRPWM_PG_EVT_CMPA_UP, SRPWM_PG_CLEAR);
   SRPWM_SetPG(SRPWM0, SRPWM_PWMB, SRPWM_PG_EVT_ZERO, SRPWM_PG_SET);
   /* PREP前级保护功能初始化 */
   SRPWM_PREPStructInit(&stPREPInit);
   stPREPInit.b.unresFaultProtectSig   = SRPWM_PREP_SIG_FAULT_REAL0;
   stPREPInit.b.unresFaultProtectState = SRPWM_PREP_STATE_CLR;
   SRPWM_PREPInit(SRPWM0, &stPREPInit);
   /* 使能高精度旁路 */
   SRPWM_HRPWMBypassEnable(SRPWM0);
   /* 使能指定模块 */
   SRPWMCOM_Enable(SRPWM_CHANNEL_0);
}

可以预见,SRPWM0的B路将会输出PWM。当GPIO0_15输入高低电平,异常信号到来时封波,异常信号消失时,恢复波形

通过比较器封波

比较器封波和GPIO封波的整体流程基本是一致的,本质都是分成3个部分配置,异常信号源配置、XBAR配置、SRPWM配置,其区别就在于异常信号源的配置,而XBAR配置和SRPWM配置几乎是一样的。

代码依然分成3个部分进行:ACMP配置、XBAR配置、SRPWM配置,需包含各自驱动的头文件

  • ACMP配置 :

配置ACMP2_B的比较电平,并将ACMP的比较结果作为XBAR的信号输入。

/**
* @brief 配置ACMP。将ACMP2_B作为封波的信号源
*
*/
static void ACMP_Config(void)
{
   ACMP_InitType cmp_init;
   ACMP_DAC_InitTypeDef dac_init;

   /* get cmpss default init value */
   ACMP_StructInit(&cmp_init);
   /* set dac path enable */
   cmp_init.dacToCmpEn = ENABLE;
   /* set positive input to IO input */
   cmp_init.cmpPositiveInputSelect = ACMP_INPUT_IO;
   cmp_init.dacRefSelect = ACMP_DACREF_VDDA;
   /* init ACMP2 channel B, == ACOMP5 */
   ACMP_Init(ACMP2, ACMP_CHANNEL_B, &cmp_init);
   /* enable ACMP2 channel B, == ACOMP5 */
   ACMP_Enable(ACMP2, ACMP_CHANNEL_B);

   /* get internal dac default init value */
   ACMP_DAC_StructInit(&dac_init);
   /* set trigger mask to NOT mask */
   dac_init.triggerMask = UNMASKED;
   /* set dac trigger enable */
   dac_init.triggerEn = ENABLE;

   /* init ACMP2 channel B, == ACOMP5 */
   ACMP_DAC_Init(ACMP2, ACMP_CHANNEL_B, &dac_init);

   /* set dac trigger to software trigger */
   ACMP_DAC_TriggerSrcSel(ACMP2, ACMP_CHANNEL_B, ACMP_DAC_TRIGGER_SEL_SW);

   /* set INPUT 1V - 2V OK */
   ACMP_DAC_SetValue(ACMP2, ACMP_CHANNEL_B, 2482U);
}
  • XBAR的配置 :

作为一个中转,将比较器结果送往SRPWM进行封波。

/**
* @brief 配置XBAR
*           ACMP2_B作为XBAR的输入,并给到SPWM 作为异常保护信号
*
*/
static void XBAR_Config(void)
{
   XBAR_PFSXB_InCfg_TypeDef  inputCfg;
   XBAR_InChMsk_TypeDef     inputChMsk;

   /* 1. input channel configure  */
   memset(&inputCfg, 0, sizeof(XBAR_PFSXB_InCfg_TypeDef));
   XBAR_InputChMsk_Init(&inputChMsk);

   /* whether to enable edge trigger */
   inputCfg.inEdgeEn = DISABLE;
   /* whether to enable input filter */
   /* whether to invert the input signal level */
   inputCfg.inInvertEn = DISABLE;
   /* select edge trigger type */
   inputCfg.inEdgeType = XBAR_IN_EDGE_RISING;

   /*
   * 2. select ACMPx out in XBAR input channel
   * IN:  PFSXB_SRC_ACMP_CMP0_RLS_GRP[3:0]  ACMP0~3_CHa
   * IN:  PFSXB_SRC_ACMP_CMP1_RLS_GRP[3:0]  ACMP0~3_CHb
   * OUT: PFXB_OUT[5:0]-> PWM_CH0~3 PFXB_OUT[11:6]-> PWM_CH4~7  PFXB_OUT[17:12]-> PWM_CH8~11
   *
   */
   /* add ACMP2_CHb */
   XBAR_Input_Add_Source(&inputChMsk, PFSXB_SRC_ACMP_CMP1_RLS_GRP + 2);
   XBAR_PFXB_Input_Channel_Init(&inputCfg, &inputChMsk);
   /* configure XBAR output channel  out_ch3 -> PWM_CH0~3 */
   XBAR_PFXB_Output_Mux_Config((uint16_t)BIT_MASK(3), &inputChMsk);
   /* output config */
   XBAR_PFXB_Output_Latch_Disable((uint16_t)BIT_MASK(3));
   XBAR_PFXB_Output_Invert_Disable((uint16_t)BIT_MASK(3));
   XBAR_PFXB_Output_Enable((uint16_t)BIT_MASK(3));
}
  • SRPWM的配置 :

将SRPWM0的B路配置为前级保护,UNRES保护状态为置0。

static void SRPWM_Config(void)
{
   SRPWM_TBInitTypeDef stTBInit;
   SRPWM_CMPInitTypeDef stCMPInit;
   SRPWM_PREPInitTypeDef stPREPInit;
   IOC_Init_TypeDef Init;

   /* 复位SRPWM0,并开启SRPWM0的时钟 */
   CRG_PeriphReset(CRG_SRST_SRPWM0);
   /* IO mux配置 */
   IOC_ConfigStructInit(&Init);
   Init.mode = IOC_AF_MODE_1;
   IOC_Config(IOC_PIN_GPIO0_1, &Init); //pwm0b
   /* TB初始化 */
   SRPWM_TBStructInit(&stTBInit);
   stTBInit.period    = 0xC350;
   stTBInit.countMode = SRPWM_COUNTMODE_UP;
   SRPWM_TBInit(SRPWM0, &stTBInit);
   /* CMP初始化 */
   SRPWM_CMPStructInit(&stCMPInit);
   stCMPInit.cmpA = 0xC350 / 4;
   SRPWM_CMPInit(SRPWM0, &stCMPInit);
   /* PG初始化 */
   SRPWM_SetPG(SRPWM0, SRPWM_PWMB, SRPWM_PG_EVT_CMPA_UP, SRPWM_PG_CLEAR);
   SRPWM_SetPG(SRPWM0, SRPWM_PWMB, SRPWM_PG_EVT_ZERO, SRPWM_PG_SET);
   /* PREP前级保护功能初始化 */
   SRPWM_PREPStructInit(&stPREPInit);
   stPREPInit.b.unresFaultProtectSig   = SRPWM_PREP_SIG_FAULT_REAL3;
   stPREPInit.b.unresFaultProtectState = SRPWM_PREP_STATE_CLR;
   SRPWM_PREPInit(SRPWM0, &stPREPInit);
   /* 使能高精度旁路 */
   SRPWM_HRPWMBypassEnable(SRPWM0);
   /* 使能指定模块 */
   SRPWMCOM_Enable(SRPWM_CHANNEL_0);
}

可以预见,SRPWM0的B路将会输出PWM。当比较器的输入脉冲变化时,将会产生脉冲比较结果作为异常信号,该结果会送外SRPWM进行封波。异常信号到来时封波,异常信号消失时,恢复波形

事件触发(ET)和中断模块

事件触发

022

输出事件模块的功能主要分为以下几类:

  • 各pwm通道间同步所需的同步信号。同步信号有两个通路:sync_out0和sync_out1

  • ADC模块所需的触发信号。触发信号有两个通路:trigger0和trigger1

  • DMA的请求信号。

  • 事件中断

事件输出

事件是指PWM外设外部输入信号产生高电平脉冲或者PWM外设内部某类条件满足之后产生高电平脉冲信号,脉冲宽度可包含1个或者多个时钟周期的长度。

PWM外设具备多种事件,具体参考用户手册的事件说明章节。需要注意的是,根据不同功能,将PWM外设所能产生的全部事件分为了以下几个事件集合类别:

  • 所有事件集合(all_evt)

    注这里的所有事件,并不表示全部的含义,仅是命名。所有事件集合主要用于:

    1、产生通道的同步输出信号(sync_out0和1);

    2、XBAR输入信号在通道内做故障处理时,产生blanking区域;

    3、封波保护时,CBC和One-Shot方式的时刻控制

  • 同步加载事件集合1

    主要用于周期、相位、主比较器值、从比较器值以及burst参数的影子加载

  • 同步加载事件集合2

    主要用于PWM波产生动作参数和死区参数的影子加载

  • 时基同步信号集合

    主要用于时基同步信号timer_0sync_in和timer_1sync_in

  • 输出事件可选同步集合

    主要用于产生DMA请求信号、中断信号、ADC触发信号。需要注意的是,这类信号,可以将信号做倍频或者分频后输出

  • Burst同步事件集合

    主要用于burst模式的开始和结束同步事件选择

  • 动作矩阵事件集合

    主要用于产生PWM发波动作

  • PG同步事件集合

    主要用于软件强制发生发波动作的起始和结束同步触发

    以上各类事件集合的详细内容,均可以在用户手册的事件集合说明中找到。

事件中断

事件中断是中断的一种类型。具体在中断章节中进行讲解

中断

各PWM通道均支持独立的中断产生,同时具备多种中断源

事件中断

事件中断作为中断的一种类型,其事件源来源于输出事件可选同步集合。要使事件中断生效,需要同时满足以下几个条件:

  1. 选择事件源,即选择输出事件可选同步集合中的某种事件作为输出事件

  2. 中断源选择事件中断

  3. 使能NVIC

其他功能中断

PWM外设还支持其他类型的中断,具体如下:

  • Burst over中断。

  • Fault Real0中断。即异常实时信号0的中断

  • Fault Real1中断。即异常实时信号1的中断

  • Fault Real2中断。即异常实时信号2的中断

  • Fault Real3中断。即异常实时信号3的中断

  • Fault Real4中断。即异常实时信号4的中断

  • Fault Real5中断。即异常实时信号5的中断

  • Fault Latch0中断。即异常锁存信号0的中断

  • Fault Latch1中断。即异常锁存信号1的中断

  • Fault Latch2中断。即异常锁存信号2的中断

  • Fault Latch3中断。即异常锁存信号3的中断

  • Fault Latch4中断。即异常锁存信号4的中断

  • Fault Latch5中断。即异常锁存信号5的中断

    以上中断类型和事件中断均为同级关系,可以同时使能多种中断类型有效。这些功能中断和事件中断的使用区别是,不再需要选择事件源。即只需要同时满足以下条件即可:

  1. 中断源选择以上的功能中断类型

  2. 使能NVIC

参数加载以及广播功能

本章节主要介绍参数的加载模式和广播功能。

参数的加载

在SRPWM模块中,有七种类型的关键参数,分别是:

  • 定时器周期值

  • 定时器相位值

  • 主比较器比较值

  • 从比较器比较值

  • PWM动作矩阵值

  • 死区调整值

  • Burst发波参数

我们将参数的加载模式分为了立即加载和影子加载。上述每种类型参数的加载方式可独立配置,互不关联。需要注意的是,除上述七种类型参数之外,其余参数只支持立即加载模式

立即加载

在前述的其中关键参数中,在未使能对应参数的影子功能时,则相应参数的加载为立即加载模式。软件更新对应参数的寄存器之后立即生效,成为活跃值。以主比较器比较值举例,需要调用的API如下:

SRPWM_initCMPStruct(&stCMPInit);

stCMPInit.cmpA = PRD_100K /4;

stCMPInit.cmpShadowLoadEn = DISABLE;

SRPWM_initCMP(SRPWM1, &stCMPInit);

其中cmpShadowLoadEn成员表示未使能该参数的影子模式,即为立即加载模式

影子加载

对于影子加载模式来说,根据通道的使用情况,又分为了单通道的影子加载和多通道的影子加载。

单通道的影子加载

单通道的影子加载,即只针对于单个通道的影子功能。该影子加载和前述章节的立即加载刚好对应,在使能对应参数的影子功能时,则该参数的加载为影子加载模式。软件更新对应参数的寄存器之后不会立即生效,需要等待影子加载事件到来。以主比较器比较值举例,需要调用的API如下:

SRPWM_initCMPStruct(&stCMPInit);
stCMPInit.cmpA = PRD_100K /4;
stCMPInit.cmpShadowLoadEn = ENABLE;
stCMPInit.cmpShadowLoadSel = SRPWM_SYNCEVTLOAD1_ZERO_EVT;
SRPWM_initCMP(SRPWM1, &stCMPInit);

其中cmpShadowLoadEn成员表示使能该关键参数的影子模式,而cmpShadowLoadSel则表示影子值生效,成为活跃值的时刻。当软件更新主比较器比较值时,SRPWM1并不会把更新的比较值作为有效的比较值,当该通道的过零时刻到来时,更新的比较值才会加载成为有效的活跃值。

多通道的影子加载

多通道的影子加载,又可以称为一次加载,表示的是,多个通道的参数为影子模式,并在同一时刻生效。要实现这类功能,有两个方案,具体如下:

  • 方案一:影子事件设置为软件事件

我们可以利用影子事件支持软件事件的方式,实现多个通道的影子加载。方式和上述章节单通道的影子加载配置方式基本一致。区别是将多个通道的cmpShadowLoadSel成员值均设置为软件事件SRPWM_SYNCEVTLOAD1_SW_EVT,当确定好加载时刻时,统一下发软件事件。以SRP WM1和SRPWM4举例,如下为涉及到的API作为参考(不同版本SDK可能有所区别):

SRPWM_initCMPStruct(&stCMPInit);
stCMPInit.cmpA = PRD_100K /4;
stCMPInit.cmpShadowLoadEn = ENABLE;
stCMPInit.cmpShadowLoadSel = SRPWM_SYNCEVTLOAD1_SW_EVT;
SRPWM_initCMP(SRPWM1, &stCMPInit);
SRPWM_initCMP(SRPWM4, &stCMPInit);
/* 下发软件事件 */
SRPWMCOM_generateSwEvt(SRPWM_CHANNEL_1 | SRPWM_CHANNEL_4);

但是这个方案的缺点在于,软件事件下发的时刻到真实生效可能有延迟。例如用户希望在固定的过零时刻下发软件事件,影子值生效成为活跃值,但实际情况可能是,在过零时刻下发软件事件,生效时刻可能已经过了好几个时钟周期了。针对这种情况,我们提供了另外一种方案。

  • 方案二:多通道多关键参数的影子加载

多通道多参数的影子加载也是实现一次加载的方式。该方案是可以实现单个通道多个关键参数在固定的时刻一次加载,也可以实现多通道多个关键参数在固定的时刻一次加载。因单通道多参数和多通道多参数的使用方式一致,所以这里不再对单通道多参数做赘述。

以SRPWM1和SRPWM4举例,如下为涉及到的API作为参考:

SRPWM_initCMPStruct(&stCMPInit);
stCMPInit.cmpA = PRD_100K /4;
stCMPInit.cmpShadowLoadEn = ENABLE;
stCMPInit.cmpShadowLoadSel = SRPWM_SYNCEVTLOAD1_ZERO_EVT;
SRPWM_initCMP(SRPWM1, &stCMPInit);
SRPWM_initCMP(SRPWM4, &stCMPInit);
/* 配置多通道多参数影子加载*/
SRPWM_enableShadowMultiRegSync(SRPWM1, SRPWM_SHD_MULTI_SYNC_PRD |SRPWM_SHD_MULTI_SYNC_CMP);
SRPWM_enableShadowMultiRegSync(SRPWM4, SRPWM_SHD_MULTI_SYNC_PRD |SRPWM_SHD_MULTI_SYNC_CMP);
SRPWM_setTimeBasePeriod(SRPWM1,PRD_50K);
SRPWM_setTimeBasePeriod(SRPWM4,PRD_50K);
SRPWM_setCounterCompareValue(SRPWM1,SRPWM_COUNTER_COMPARE_A,PRD_100K /2 );
SRPWM_setCounterCompareValue(SRPWM4,SRPWM_COUNTER_COMPARE_A,PRD_100K /2 );
/* 下发软件事件*/
SRPWMCOM_forceMultiChannelShadow(SRPWM_CHANNEL_1 | SRPWM_CHANNEL_4);

以上代码将实现SRPWM1和SRPWM4的周期值和比较值被重新更新后,在下发软件事件之后的过零时刻,同时将周期值和比较值的影子值加载成为有效活跃值。

广播加载

广播加载,也可称为全局加载。这种方式适合一些特殊的使用场景。比如有多个通道需要进行配置,且这些通道的配置完全一致。如果采用传统方式进行配置,那么将会显的非常冗余。在这种场景下则可以采用广播加载的方式实现。需要注意的是,广播加载功能本身不是采用SRPWM外设的寄存器实现,而是采用SYSC外设的寄存器实 现的。

以SRPWM1和SRPWM4举例,如下为涉及到的API作为参考:

/*使能广播功能*/
SRPWMCOM_enableBroadcast(SRPWM_CHANNEL_1 | SRPWM_CHANNEL_4);
/*配置基础设置*/
SRPWM_initCMPStruct(&stCMPInit);
stCMPInit.cmpA = PRD_100K /4;
stCMPInit.cmpShadowLoadEn = ENABLE;
stCMPInit.cmpShadowLoadSel = SRPWM_SYNCEVTLOAD1_ZERO_EVT;
SRPWM_initCMP(SRPWM_GLOBAL, &stCMPInit);
/*改变参数*/
SRPWM_setTimeBasePeriod(SRPWM_GLOBAL,PRD_50K);

如上代码,SRPWM_GLOBAL这个外设用于SRPWM1和SRPWM4的广播下发,当需要广播设置某个参数设置,只需要调用SRPWM对应的API接口,即可对SRPWM1和SRPWM4同时设置。

结尾

总结

ET6000系列实时微控制器在SRPWM (Super Resolution PWM) 高精度PWM外设中提供了丰富的功能。本文重点介绍了该外设的所有主要功能,以及如何在应用中利用这些功能。 此外,还介绍了所有必要的计算,对于某些功能,采用API调用示例的方式进行说明。因该外设丰富的设计,本文未对部分 功能展开进行详细的说明,如需要了解更多详细的信息,还需要参考官网上其他的资料或者相关应用笔记。

引用参考