1、概述
电机控制中需要产生三相六路SVPWM进行占空比与周期调制,怎么通过RTD-SDK的方式实现三相六路发波呢?本文记录一下实现方式。
1.1、理论基础
在手册的Real-time control章节,也就是实时控制这块,开篇就描述电力转换与电机控制。
如何去实现的呢?一个比较抽象的框图手册里面也有给出
NXP有自己的技术社区,在社区里面有很详细的资料描述了如何实现电机控制这块。例如下面这个框图,描述了SVPWM如何实现的,三相电流如何采样的,电机的位置信息如何获取的,静态系统框图的实现如下。
从上图也可以看出,eMios0模块通过OPWMB的模式产生中心对齐的波形,经过TRGMUX路由到LCU模块,经由IO口输出中心堆成并携带死区的PWM。
- eMios 由eMios Ch0作为counter bus,Ch1\Ch2\Ch3以OPWMB的方式进行对齐输出PWM
解释OPWMB:OPWMB支持X G Y H四种模式,有缓存可以看作影子寄存器的方式,本周期填值,下周期起作用。
- TRGMUX将eMios的信号路由到LCU模块。
- LCU作为逻辑控制单元,在这里执行上下对称并携带死区的波形。
2、RTD实现
2.1、Emios时基配置
2.1.1、EmiosMcl
Emios之间需要相互通信,不勾选的会报错,这块主要作为时间基准的,其他通过均是基于某一个count bus来执行的。
2.1.2、EmiosCommon
选择eMios0作为时间基准,使能全局时间基准,时钟分频选择12分频,也就是120MHz,分频成12MHz,计数方式为向上计数,默认Ticks这个根据需要设置,例如1250 也就是10 000 000 /1250 = 8000,频率为8K,允许调试,以PWM的方式执行。
2.2、Emios PWM配置
模式选择:EMIOS_PWM_IP_MODE_OPWMB,与上面设计需求一致。
触发方式:Trailing_Edge 后沿触发
计数总线:EMIOS_PWM_IP_BUS_BCDE 为什么选择BCDE呢?CH0属于BUS B
占空比ticks:此处设置基于周期ticks的百分比
周期ticks:与counts bus处保持一致,否则报错
相位移位ticks:在本身的基础上的偏移量
2.3、TRGMUX
Trgmux Logic Instance 这个地方无需更改的
Trgmux Logic Group
2.4、LCU
同步功能函数在代码里面会有所调用,所以此处需要打开其API,
逻辑输入
Hardware Instance:硬件通选择,例如LCU0
Hardware Logic Cell:逻辑单元的选择,每个LCU里面有三个LC
这个图不能按照正常的思维理解,也许自己段位不够,但是按照自己实践得出来的理解反而更好点
MUX Select :表示I0~I11这12个
Hardware Input:硬件输入
此处由TRGMUX路由过来的eMios一分为二,上桥与下桥。一个LC只能有4个输出,所以到了W相,需要用到LCU0的LC1进行输出。
Lcu Logic Output
Output LUT Control:逻辑输出控制,注意这个是固定的,查表如下图
根据推荐值设置即可
Rise Filter:死区设置,以ticks的方式执行
2.5、外设信号配置
将对应的Port口与LCU输出单元连接起来,便于测试。
3、代码实现
根据以上代码设计,使用到了eMios 、TRGMUX、LCU、PORT模块,需要初始化以上模块。
Lcu_Ip_SyncOutputValueType Motor_OutputList[6] =
{
{0, LCU_IP_OUTPUT_DISABLE},
{1, LCU_IP_OUTPUT_DISABLE},
{2, LCU_IP_OUTPUT_DISABLE},
{3, LCU_IP_OUTPUT_DISABLE},
{4, LCU_IP_OUTPUT_DISABLE},
{5, LCU_IP_OUTPUT_DISABLE},
};
Siul2_Port_Ip_Init(NUM_OF_CONFIGURED_PINS0, g_pin_mux_InitConfigArr0);
/* Initialize Emios0 */
Emios_Mcl_Ip_Init(0U, &Emios_Mcl_Ip_0_Config_BOARD_INITPERIPHERALS);
Emios_Pwm_Ip_InitChannel(0U, &Emios_Pwm_Ip_I0_Ch1); /*U*/
Emios_Pwm_Ip_InitChannel(0U, &Emios_Pwm_Ip_I0_Ch2); /*V*/
Emios_Pwm_Ip_InitChannel(0U, &Emios_Pwm_Ip_I0_Ch3); /*W*/
Emios_Pwm_Ip_InitChannel(0U, &Emios_Pwm_Ip_I0_Ch4); /*Trigger ADC*/
/* Initialize Trgmux */
Trgmux_Ip_Init(&Trgmux_Ip_xTrgmuxInitPB);
/* Initialize Lcu */
Lcu_Ip_Init(&Lcu_Ip_xLcuInitPB);/* 假设上电关闭LCU,需要调用 Lcu_Ip_SetSyncOutputEnable(Motor_OutputList, 6);*/
执行代码
Emios_Pwm_Ip_SetDutyCycle (0U, 1U, u16_DutyTicks_U); /*U Set Duty*/
Emios_Pwm_Ip_SetDutyCycle (0U, 2U, u16_DutyTicks_V); /*V Set Duty*/
Emios_Pwm_Ip_SetDutyCycle (0U, 3U, u16_DutyTicks_W); /*W Set Duty*/
Emios_Pwm_Ip_SetPhaseShift(0U, 1U, u16_OffSetTicks_U); /*U Centrosymmetric shift*/
Emios_Pwm_Ip_SetPhaseShift(0U, 2U, u16_OffSetTicks_V); /*V Centrosymmetric shift*/
Emios_Pwm_Ip_SetPhaseShift(0U, 3U, u16_OffSetTicks_W); /*W Centrosymmetric shift*/
更新周期
uint16 u16_FreqTicks = ticks;
Emios_Mcl_Ip_SetCounterBusPeriod(0U, 0U, u16_FreqTicks);
Emios_Pwm_Ip_SetPeriod(0U, 1U, u16_FreqTicks);
Emios_Pwm_Ip_SetPeriod(0U, 2U, u16_FreqTicks);
Emios_Pwm_Ip_SetPeriod(0U, 3U, u16_FreqTicks);
Emios_Pwm_Ip_SetPeriod(0U, 4U, u16_FreqTicks);
Emios_Pwm_Ip_SetDutyCycle(0U, 4U, 5U); //CH4:5 ticks duty for trigger signal not center—orinetd
4、测试结果
测试结果:占空比分别给10%、50%、60%同时测量触发ADC的波形,注意一下是后沿触发。