【应用笔记】TAE32G5800 HRPWM捕获
1 需要准备的环境
▶ 硬件平台:TAE32G5800_EVAL_BOARD_V1.0
▶ 软件平台:逻辑分析仪、KEIL MDK v5.34
▶ 系统配置:PLL0时钟360M,PWM时钟:180MHz
2 捕获功能介绍
此使用教程详细描述了TAE32G5800芯片HRPWM捕获周期和外部输入信号脉宽的详细过程和方法,以达到测量事件到达时间或发生间隔的目的。
每个定时单元包含2个捕获寄存器:HRPWM_CAPAxR和HRPWM_CAPBxR。捕获触发事件在HRPWM_CAPAxCR/HRPWM_CAPAxCER和HRPWM_CAPBxCR/HRPWM_CAPBxCER寄存器中编程。
每个定时单元计数器的捕获可通过多达40种事件触发,这些事件可同时在HRPWM_CAPAxCR/HRPWM_CAPAxCER和HRPWM_CAPBxCR/HRPWM_CAPBxCER寄存器中选择,具体包括以下触发源:
▶ 外部事件,HRPWM_Event0~9(10个事件)
▶ 其他定时单元:比较A、B和输出A置位/复位事件(28个事件)
▶ 自身定时单元:更新(1个事件)
▶ 软件捕获(1个事件)
可以同时选择多个事件处理多个捕获触发信号。在这种情况下,会对多个并发触发请求进行或运算。如果HRPWM_PWMxDIER.CAPxIE和HRPWM_PWMxDIER.CAPxDE已置1,捕获可生成中断或DMA请求。详细的PWM捕获功能框图如下图2.1所示。
图2.1 PWM捕获功能框图
3 TAE32G5800捕获计数值
3.1 HRPWM 捕获CMP值
程序配置预分频系数、预加载使能、周期、CMPx,选取捕获触发源。使用SLV0捕获SLV1的CMPx计数值。关于Capture更详细的配置见代码清单3.1。
代码清单3.1 捕获初始化配置
HRPWM_SLV1->CR0 = HRPWM_SLV1_CR0_CONT_Msk
| HRPWM_SLV1_CR0_PREEN_Msk |
(0x5 << HRPWM_SLV1_CR0_CKPSC_Pos) ;
HRPWM_SLV1->CR1 = HRPWM_SLV1_CR1_MUPD_Msk;
HRPWM_SLV1->PERR = 999;
HRPWM_SLV1->CMPAR = 200;
HRPWM_SLV1->CMPBR = 100;
HRPWM_SLV1->CMPCR = 600;
HRPWM_SLV1->CMPDR = 800;
HRPWM_SLV1->SETAR = HRPWM_SLV1_SETAR_CMPA_Msk;
HRPWM_SLV1->CLRAR = HRPWM_SLV1_CLRAR_CMPC_Msk;
HRPWM_SLV1->SETBR = HRPWM_SLV1_SETBR_CMPB_Msk;
HRPWM_SLV1->CLRBR = HRPWM_SLV1_CLRBR_CMPD_Msk;
HRPWM_SLV0->CAPACR_b.SLVACMPB = 1; //PWM1 CMPB触发 CaptureA事件
HRPWM_SLV0->CAPBCR_b.SLVACMPA = 1; //PWM1 CMPA触发 CaptureB事件
根据以上Capture初始化配置,debug查看捕获值是否与程序配置的相符,具体如下图3.1所示:
图3.1 捕获CMP值
3.2 使用SET/CLR事件触发捕获
在一些应用方案上,需要捕获一个PWM波的上升沿和下降沿来获取占空比。针对此项需求,在捕获选源上可以选择用SET/CLR事件触发捕获,这样设置的好处就是可以明确知道在触发SET事件后捕获到的值就是上升沿,触发CLR事件后捕获到的值就是下降沿,知道上升沿和下降沿的计数值可以很容易算出此时的占空比。详细的配置见代码清单3.2。
代码清单3.2 SET/CLR触发捕获配置
HRPWM_SLV1->CR0 = HRPWM_SLV1_CR0_CONT_Msk|
HRPWM_SLV1_CR0_PREEN_Msk |
(0x5 << HRPWM_SLV1_CR0_CKPSC_Pos) ;
HRPWM_SLV1->CR1 = HRPWM_SLV1_CR1_MUPD_Msk;
HRPWM_SLV1->PERR = 999;
HRPWM_SLV1->CMPAR = 200;
HRPWM_SLV1->CMPBR = 100;
HRPWM_SLV1->CMPCR = 600;
HRPWM_SLV1->CMPDR = 800;
HRPWM_SLV1->SETAR = HRPWM_SLV1_SETAR_CMPA_Msk;
HRPWM_SLV1->CLRAR=HRPWM_SLV1_CLRAR_CMPC_Msk;
HRPWM_SLV1->SETBR = HRPWM_SLV1_SETBR_CMPB_Msk;
HRPWM_SLV1->CLRBR = HRPWM_SLV1_CLRBR_CMPD_Msk;
HRPWM_SLV0->CAPACR_b.SLVASETA = 1; //PWM1 SET事件触发CaptureA事件
HRPWM_SLV0->CAPBCR_b.SLVACLRA = 1; //PWM1 CLR事件触发 CaptureB事件
HRPWM_SLV1->OUTR = (0 << HRPWM_SLV1_OUTR_POLB_Pos)|
(0 << HRPWM_SLV1_OUTR_POLA_Pos)|
(0 << HRPWM_SLV1_OUTR_IDLESA_Pos)|
(1 << HRPWM_SLV1_OUTR_IDLESB_Pos);
//软件更新
HRPWM_COM->CR2= HRPWM_COM_CR2_MSWU_Msk|
HRPWM_COM_CR2_SWU0_Msk |
HRPWM_COM_CR2_SWU1_Msk|
//使能计数器
HRPWM_MST->MCR1 |= HRPWM_MST_MCR1_MCEN_Msk |
HRPWM_MST_MCR1_CEN0_Msk |
HRPWM_MST_MCR1_CEN1_Msk |
debug调试查看SLV0的CAPAR和CAPBR的实际捕获值,由于SET\CLR事件比预期的对应计数值要晚3个clock,所以实际捕获的值是多3个计数值。具体如下图3.2所示。
图3.2 SET/CLR捕获值
根据上图3.2可知,SETA = 203,CLRB = 603,换算成占空比对应40%,见下图3.3所示:
图3.3 SLV1占空比
4 TAE32G5800 HRPWM间接捕获占空比
4.1 使用Event事件捕获2路PWM信号
在有些应用场景下,需要捕获外部信号的脉宽来实现对信号的控制。如果需要实现这种方式可以把捕获源选Event事件来触发捕获。外部信号的输入可以选用一个PWM波输入到Event引脚上,然后事件配置成上升沿或下降沿均触发。详细的配置见代码清单4.1。
代码清单4.1 捕获外部信号配置
GPIOB->MR0_b.PMn7 = 0x0E; //EVT 2
GPIOB->MR0_b.PMn6 = 0x0E; //EVT 3
HRPWM_COM->EECR0_b.EE3SNS = 0x3;
HRPWM_COM->EECR0_b.EE3SRC = 0;
HRPWM_COM->EECR0_b.EE2SNS = 0x3;
HRPWM_COM->EECR0_b.EE2SRC = 0;
HRPWM_SLV0->CAPACR_b.EXTEVT2 = 1; //PWMx Event2事件触发 CaptureA事件
HRPWM_SLV0->CAPBCR_b.EXTEVT3 = 1; //PWMx Event3事件触发 CaptureB事件
HRPWM_SLV1->CR0 = HRPWM_SLV1_CR0_CONT_Msk|
HRPWM_SLV1_CR0_PREEN_Msk |
(0x5 << HRPWM_SLV1_CR0_CKPSC_Pos) ;
HRPWM_SLV1->CR1 = HRPWM_SLV1_CR1_MUPD_Msk;
HRPWM_SLV1->PERR = 999;
HRPWM_SLV1->CMPAR = 200;
HRPWM_SLV1->CMPBR = 100;
HRPWM_SLV1->CMPCR = 600;
HRPWM_SLV1->CMPDR = 800;
HRPWM_SLV1->SETAR = HRPWM_SLV1_SETAR_CMPA_Msk;
HRPWM_SLV1->CLRAR=HRPWM_SLV1_CLRAR_CMPC_Msk;
HRPWM_SLV1->SETBR = HRPWM_SLV1_SETBR_CMPB_Msk;
HRPWM_SLV1->CLRBR = HRPWM_SLV1_CLRBR_CMPD_Msk;
HRPWM_SLV1->OUTR = (0 << HRPWM_SLV1_OUTR_POLB_Pos)|
(0 << HRPWM_SLV1_OUTR_POLA_Pos)|
(0 << HRPWM_SLV1_OUTR_IDLESA_Pos)|
(1 << HRPWM_SLV1_OUTR_IDLESB_Pos);
//软件更新
HRPWM_COM->CR2= HRPWM_COM_CR2_MSWU_Msk|
HRPWM_COM_CR2_SWU0_Msk |
HRPWM_COM_CR2_SWU1_Msk|
//使能计数器
HRPWM_MST->MCR1 |= HRPWM_MST_MCR1_MCEN_Msk |
HRPWM_MST_MCR1_CEN0_Msk |
HRPWM_MST_MCR1_CEN1_Msk |
如下图3.4所示,通过外部信号输入2路不同占空比的PWM输出,用PWM的捕获功能捕捉上升沿和下降沿。这里的2路PWM输出对应下图4.1的PWM0和PWM1分别给到Event2和Event3引脚上。
图4.1 PWM输出
通过debug调试查看CAPAR和CAPBR寄存器值,会有两次更新跳动,两次更新跳动的值分别对应2路PWM波的上升沿和下降沿。由于Event事件比预期的对应计数值要晚9个clock,所以实际捕获值会多计9个数,具体捕获数值如下图4.2所示。
图4.2 Event捕获值
4.2 使用Event事件捕获不同脉宽PWM信号
对于一路PWM发不同占空比的外部信号的捕获可以使用下面这种捕获方式:
一路PWM有CAPA/CAPB两个输入捕获,每个输入捕获来源有多路可配,CAPA可以捕获EVTx上升沿,CAPB可以捕获EVTy下降沿,通过在CAPA处和CAPB起中断、可以读取CAPA/CAPB数值进行处理,以达到捕获脉宽的目的。详细的外部信号如下图4.3所示:
图4.3 外部信号
CAPA捕获PWM的上升沿,CAPB捕获PWM的下降沿,以下代码清单4.2是关于此种配置下的SLV0、SLV1的捕获初始化配置。
代码清单4.2 捕获不同占空比初始化配置
HRPWM_COM->EECR0_b.EE3SNS = 0x2; //检测下降沿
HRPWM_COM->EECR0_b.EE3SRC = 0;
HRPWM_COM->EECR0_b.EE2SNS = 0x1; //检测上升沿
HRPWM_COM->EECR0_b.EE2SRC = 0;
HRPWM_SLV0->CAPACR_b.EXTEVT2 = 1; //PWMx Event2事件触发CaptureA事件
HRPWM_SLV0->CAPBCR_b.EXTEVT3 = 1; //PWMx Event3事件触发CaptureB事件
HRPWM_SLV1->CR0 = HRPWM_SLV1_CR0_CONT_Msk|
HRPWM_SLV1_CR0_PREEN_Msk |
(0x5 << HRPWM_SLV1_CR0_CKPSC_Pos) ;
HRPWM_SLV1->CR1 = HRPWM_SLV1_CR1_MUPD_Msk;
HRPWM_SLV1->PERR = 999;
HRPWM_SLV1->CMPAR = 200;
HRPWM_SLV1->CMPBR = 100;
HRPWM_SLV1->CMPCR = 600;
HRPWM_SLV1->CMPDR = 800;
HRPWM_SLV1->SETAR = HRPWM_SLV1_SETAR_CMPA_Msk;
HRPWM_SLV1->CLRAR = HRPWM_SLV1_CLRAR_CMPC_Msk;
HRPWM_SLV1->SETBR = HRPWM_SLV1_SETBR_CMPB_Msk;
HRPWM_SLV1->CLRBR = HRPWM_SLV1_CLRBR_CMPD_Msk;
NVIC_EnableIRQ(HRPWM_SLV0_IRQn); //SLV0外设中断使能
HRPWM_SLV0->DIER_b.CAPAIE = 1; //开启CAPA捕获中断使能
HRPWM_SLV0->DIER_b.CAPBIE = 1; //开启CAPB捕获中断使能
以上配置生效后,会将捕获到的上升和下降沿值存储在CAPA、CAPB寄存器,通过开启CAPA和CAPB的中断使能可以将其存储值进行读取处理,以下代码清单4.3是CAPA/CAPB的中断处理函数。
代码清单4.3 CAPA/CAPB中断处理
volatile uint16_t ValueCAPA = 0;
volatile uint16_t ValueCAPB = 0;
volatile uint16_t flag = 0;
void HRPWM_SLV0_IRQHandler(void)
{
if(flag == 0){
if((HRPWM_SLV0->ISR_b.CAPA == 1) && (HRPWM_SLV0->DIER_b.CAPAIE == 1))
{
HRPWM_SLV0->ISR_b.CAPA = 1;
ValueCAPA = HRPWM_SLV0->CAPAR_b.CAPA;
flag = 1;
}
}
else if((HRPWM_SLV0->ISR_b.CAPB == 1) && (HRPWM_SLV0->DIER_b.CAPBIE == 1))
{
HRPWM_SLV0->ISR_b.CAPB = 1;
ValueCAPB = HRPWM_SLV0->CAPBR_b.CAPB;
flag = 0;
}
}
下图4.4和图4.5所示是捕获上升沿和下降沿的数值,通过此种方式将实际捕获到的值储存在相应变量中进行处理。
图4.4 CAPA上升沿捕获
图4.5 CAPB下降沿捕获
5 TAE32G5800 HRPWM直接捕获脉宽和周期
以上几个章节描述的都是通过捕获到的数值间接去算脉宽,这样用在一些应用方案上比较麻烦,鉴于此给出一种直接通过捕获脉宽和周期的方式来解决此问题。
配置PWM单次模式,用事件去复位计数器。Event 2捕获上升沿并复位CNT开始计数,Event 3捕获下降沿得到脉宽。下图5.1是此种实现方式的时序图。
图5.1 实现原理时序图
下图5.2是捕获脉宽和周期的具体捕获过程。Event 2触发上升沿捕获并复位计数器重新开始计数,将捕获值存放CAPAR寄存器,Event 3触发下降沿捕获并将捕获值存放CAPBR寄存器。CAPA捕获到上升沿事件后触发计数器复位,当CAPA第二次捕获到上升沿时,此时CAPA捕获的计数值便是对应周期值。CAPB捕获下降沿事件后此时CAPB捕获的计数值便是对应脉冲宽度。
图5.2 捕获脉宽周期
基于以上的实现原理和捕获过程给出详细的配置代码,见代码清单5.1所示:
代码清单5.1 捕获周期、脉宽初始化配置
HRPWM_SLV0->CR0 = (0<<HRPWM_SLV0_CR0_CONT_Pos) | //单次模式
HRPWM_SLV0_CR0_PREEN_Msk|
(0x5 << HRPWM_SLV0_CR0_CKPSC_Pos) |
HRPWM_SLV0_CR0_RETRIG_Msk ; //单次可重触发
HRPWM_SLV0->RSTR = HRPWM_SLV0_RSTR_EXTEVT2_Msk;
HRPWM_SLV0->PERR = 900;
HRPWM_SLV0->CMPAR = 100;
HRPWM_SLV0->CMPBR = 200;
HRPWM_SLV0->CMPCR = 500;
HRPWM_SLV0->CMPDR = 0;
HRPWM_SLV0->SETAR = HRPWM_SLV0_SETAR_CMPA_Msk;
HRPWM_SLV0->CLRAR = HRPWM_SLV0_CLRAR_CMPC_Msk;
HRPWM_SLV0->SETBR = HRPWM_SLV0_SETBR_PER_Msk;
HRPWM_SLV0->CLRBR = HRPWM_SLV0_CLRBR_CMPC_Msk;
HRPWM_COM->EECR0_b.EE3SNS = 0x2; //检测下降沿HRPWM_COM->EECR0_b.EE3SRC = 0;
HRPWM_COM->EECR0_b.EE2SNS = 0x1; //检测上升沿HRPWM_COM->EECR0_b.EE2SRC = 0;
HRPWM_SLV0->CAPACR_b.EXTEVT2 = 1; //PWMx Event2事件触发 CaptureA事件
HRPWM_SLV0->CAPBCR_b.EXTEVT3 = 1; //PWMx Event3事件触发 CaptureB事件
下图5.3是实际的仿真结果,CAPA对应周期,CAPB对应脉宽。
图5.3 捕获周期、脉宽仿真