本帖最后由 wangjj19950516 于 2021-8-26 13:07 编辑
关于电机驱动的极性,之前写过一篇帖子,介绍了电控的4种极性所需的PWM配置。https://bbs.21ic.com/icview-3044066-1-1.html
近期发现一点问题,在PWM模块初始化期间会将输出端口的电平拉低,在不同极性下存在烧坏功率器件的风险,比如上桥低有效,下桥低有效。
1.如果驱动极性为上桥高有效,下桥高有效,硬件上会加下拉电阻,上电后在PWM模块初始化之前端口会被拉到低电平,上下桥MOS都处于关闭状态。PWM模块初始化期间也是低电平,不会有导通的风险。
2.如果驱动极性为上桥低有效,下桥低有效,硬件上是加上拉电阻,上电后在PWM模块初始化之前端口被拉到高电平,上下桥MOS处于关闭状态。但在PWM模块初始化期间会将输出拉低,导致上下桥直通,持续时间长的话就会烧坏MOS。
3.如果驱动极性为一高一低,则在PWM模块初始化期间,会同时导通3个上桥或3个下桥,这种情况不会上下桥直通烧坏MOS,但会使电机短暂的处于刹车状态,如果电机处于自由运行状态,会有大电流产生。
下图展示了实际测试波形,配置上下桥都为低有效,外部电路带上拉电阻。黄色为上桥PWM,绿色为下桥PWM,紫色为测试IO口,在PWM模块初始化函数开始时拉高,初始化配置完成后拉低。可以看到在进入PWM初始化之前,两路通道由于外部上拉电阻的原因都为高电平,但在PWM初始化期间被拉低了,持续时间有50us.
既然这样,那在电机应用中就会存在很大的风险。别急,我们的PWM模块考虑到了这种情况,PWM可以配置在初始化期间强制控制通道输出电平,PWM_OUTINIT寄存器配置每个通道的初始输出电平,PWM_FUNCSEL寄存器的INIT位使能该功能。
为规避风险,不管电机的驱动极性是哪一种,都应该配置相应的初始输出电平。在使用过程中,应将使能位放在通道输出电平配置的后面,才会生效。
一、AC781X系列配置
下面以上下桥都低有效为例,PWM的CH0,CH2,CH3为上桥,CH1,CH3,CH5为下桥,在初始化配置里最先配置通道初始化并使能,就能在整个初始化期间将通道输出控制为所配置的电平。void PWM_Initialize(void)
{
/*首先打开PWM模块时钟 */
CKGEN_Enable(CLK_PWM2_TIMER, 1);
CKGEN_Enable(CLK_PWM2_APB, 1);
CKGEN_SoftReset(SRST_PWM2_APB, 1);
CKGEN_SoftReset(SRST_PWM2_TIMER, 1);
/* 根据不同电机极性,配置通道初始输出电平*/
PWM_OutputInit_Config(PWM2, 0x15);
/* 使能通道初始输出控制功能 */
PWM_EnableInitChlOutput(PWM2);
/* PWM init config*/
PWM_PWMInit(PWM2, PWM_PWMMODE_COMBINE, PWM_PWM_LOWTRUEPULSE);
PWM_SetModValue(PWM2, (3000 - 1)); //设置最大计数值
PWM_SetChannelValue(PWM2, PWM_CHANNEL_CHANNEL0, 0);
PWM_SetChannelValue(PWM2, PWM_CHANNEL_CHANNEL2, 0);
PWM_SetChannelValue(PWM2, PWM_CHANNEL_CHANNEL4, 0);
PWM_SetChannelValue(PWM2, PWM_CHANNEL_CHANNEL1, 0);
PWM_SetChannelValue(PWM2, PWM_CHANNEL_CHANNEL3, 0);
PWM_SetChannelValue(PWM2, PWM_CHANNEL_CHANNEL5, 0);
/* Active Low, down edge input dead time */
PWM_OutputPolaritySet(PWM2, PWM_CHANNEL_CHANNEL0, 1);
PWM_OutputPolaritySet(PWM2, PWM_CHANNEL_CHANNEL2, 1);
PWM_OutputPolaritySet(PWM2, PWM_CHANNEL_CHANNEL4, 1);
PWM_OutputPolaritySet(PWM2, PWM_CHANNEL_CHANNEL1, 1);
PWM_OutputPolaritySet(PWM2, PWM_CHANNEL_CHANNEL3, 1);
PWM_OutputPolaritySet(PWM2, PWM_CHANNEL_CHANNEL5, 1);
/* 1us Deadtime */
PWM_PWMDeadtimeSet(PWM2, 2, 24);
/* PWM Start */
PWM_ClockSet(PWM2, PWM_CLOCK_SYSTEMCLOCK, 0);
}
二、AC780X系列配置
AC780X系列的驱动库CMSIS1.0.5及以上版本中有该功能的驱动接口,可直接调用,以下版本的需要额外添加几条指令实现,下面一一说明:
1.CMSIS驱动包是1.0.5及以上的:
void Motor_PWM_LOW_LOW(void)
{
PWM_DeInit(PWM1);
PWM_CombineChConfig chConfig[4];
PWM_ModulationConfigType pwmConfig;
PWM_ConfigType config;
GPIO_SetPinLevel(GPIOC, GPIO_PIN8, 1); //拉高测试端口
/* Config PWM Interface */
memset(&chConfig, 0, sizeof(chConfig));
memset(&pwmConfig, 0, sizeof(PWM_ModulationConfigType));
memset(&config, 0, sizeof(PWM_ConfigType));
/* channel 0/1 */
chConfig[0].pairChannel = PWM_CH_0;
chConfig[0].ch1stValue = 500;
chConfig[0].ch2ndValue = 500;
chConfig[0].levelMode = PWM_LOW_TRUE;
chConfig[0].complementEn = ENABLE;
chConfig[0].deadtimeEn = ENABLE;
chConfig[0].ch1stMatchDir = PWM_MATCH_DIR_UP;
chConfig[0].ch2ndMatchDir = PWM_MATCH_DIR_DOWN;
chConfig[0].ch1stPolarity = PWM_OUTPUT_POLARITY_ACTIVE_LOW;
chConfig[0].ch2ndPolarity = PWM_OUTPUT_POLARITY_ACTIVE_LOW;
chConfig[0].ch1stInitLevel =1; //配置CH0通道初始输出电平为高电平
chConfig[0].ch2ndInitLevel =1; //配置CH1通道初始输出电平为高电平
/* channel 2/3 */
chConfig[1].pairChannel = PWM_CH_2;
chConfig[1].ch1stValue = 500;
chConfig[1].ch2ndValue = 500;
chConfig[1].levelMode = PWM_LOW_TRUE;
chConfig[1].complementEn = ENABLE;
chConfig[1].deadtimeEn = ENABLE;
chConfig[1].ch1stMatchDir = PWM_MATCH_DIR_UP;
chConfig[1].ch2ndMatchDir = PWM_MATCH_DIR_DOWN;
chConfig[1].ch1stPolarity = PWM_OUTPUT_POLARITY_ACTIVE_LOW;
chConfig[1].ch2ndPolarity = PWM_OUTPUT_POLARITY_ACTIVE_LOW;
chConfig[1].ch1stInitLevel =1; //配置CH2通道初始输出电平为高电平
chConfig[1].ch2ndInitLevel =1;//配置CH3通道初始输出电平为高电平
/* channel 4/5 */
chConfig[2].pairChannel = PWM_CH_4;
chConfig[2].ch1stValue = 500;
chConfig[2].ch2ndValue = 500;
chConfig[2].levelMode = PWM_LOW_TRUE;
chConfig[2].complementEn = ENABLE;
chConfig[2].deadtimeEn = ENABLE;
chConfig[2].ch1stMatchDir = PWM_MATCH_DIR_UP;
chConfig[2].ch2ndMatchDir = PWM_MATCH_DIR_DOWN;
chConfig[2].ch1stPolarity = PWM_OUTPUT_POLARITY_ACTIVE_LOW;
chConfig[2].ch2ndPolarity = PWM_OUTPUT_POLARITY_ACTIVE_LOW;
chConfig[2].ch1stInitLevel =1;//配置CH4通道初始输出电平为高电平
chConfig[2].ch2ndInitLevel =1;//配置CH5通道初始输出电平为高电平
pwmConfig.initTriggerEn = ENABLE;
pwmConfig.countMode = PWM_UP_DOWN_COUNT;
pwmConfig.combineChannelNum = 3;
pwmConfig.combineChConfig = chConfig;
pwmConfig.deadtime = 24;
pwmConfig.deadtimePsc = PWM_DEADTIME_DIVID_4;
pwmConfig.initChOutputEn =ENABLE; //使能通道初始输出控制功能
/* pwm config */
config.mode = PWM_MODE_MODULATION;
config.initModeStruct = &pwmConfig;
config.clkSource = PWM_CLK_SOURCE_NONE;
config.clkPsc = 1;
config.maxValue = 1000-1; //设置最大计数值
config.interruptEn = ENABLE;
config.callBack = PWM_Callback;
PWM_Init(PWM1, &config);
/* Set interrupt priority */
NVIC_SetPriority(PWM1_IRQn, 0);
/* PWM Start */
PWM_SetClockSource(PWM1, PWM_CLK_SOURCE_APB);
GPIO_SetPinLevel(GPIOC, GPIO_PIN8, 0); //拉低测试端口
}
2.CMSIS在1.0.5版本以下
1.0.5以下版本的驱动库,通道初始输出控制的配置存在问题,按上面的配置无法生效,可以在正式配置之前,添加如下如下代码解决
void Motor_PWM_LOW_LOW(void)
{
PWM_DeInit(PWM1);
PWM_CombineChConfig chConfig[4];
PWM_ModulationConfigType pwmConfig;
PWM_ConfigType config;
GPIO_SetPinLevel(GPIOC, GPIO_PIN8, 1); //拉高测试端口
/* Config PWM Interface */
memset(&chConfig, 0, sizeof(chConfig));
memset(&pwmConfig, 0, sizeof(PWM_ModulationConfigType));
memset(&config, 0, sizeof(PWM_ConfigType));
/*首先打开PWM模块时钟*/
CKGEN_Enable(CLK_PWM1, ENABLE);
CKGEN_SoftReset(SRST_PWM1, ENABLE);
/*根据不同电机驱动极性,配置初始输出电平*/
PWM_SetChannelOutputInitLevel(PWM1, PWM_CH_0, 1); //CH0初始输出高电平
PWM_SetChannelOutputInitLevel(PWM1, PWM_CH_1, 1); //CH1初始输出高电平
PWM_SetChannelOutputInitLevel(PWM1, PWM_CH_2, 1); //CH2初始输出高电平
PWM_SetChannelOutputInitLevel(PWM1, PWM_CH_3, 1); //CH3初始输出高电平
PWM_SetChannelOutputInitLevel(PWM1, PWM_CH_4, 1); //CH4初始输出高电平
PWM_SetChannelOutputInitLevel(PWM1, PWM_CH_5, 1); //CH5初始输出高电平
/* 使能初始输出控制功能*/
PWM_SetInitChannelOutput(PWM1, ENABLE);
/* channel 0/1 */
chConfig[0].pairChannel = PWM_CH_0;
chConfig[0].ch1stValue = 500;
chConfig[0].ch2ndValue = 500;
chConfig[0].levelMode = PWM_LOW_TRUE;
chConfig[0].complementEn = ENABLE;
chConfig[0].deadtimeEn = ENABLE;
chConfig[0].ch1stMatchDir = PWM_MATCH_DIR_UP;
chConfig[0].ch2ndMatchDir = PWM_MATCH_DIR_DOWN;
chConfig[0].ch1stPolarity = PWM_OUTPUT_POLARITY_ACTIVE_LOW;
chConfig[0].ch2ndPolarity = PWM_OUTPUT_POLARITY_ACTIVE_LOW;
chConfig[0].ch1stInitLevel =1;
chConfig[0].ch2ndInitLevel =1;
/* channel 2/3 */
chConfig[1].pairChannel = PWM_CH_2;
chConfig[1].ch1stValue = 500;
chConfig[1].ch2ndValue = 500;
chConfig[1].levelMode = PWM_LOW_TRUE;
chConfig[1].complementEn = ENABLE;
chConfig[1].deadtimeEn = ENABLE;
chConfig[1].ch1stMatchDir = PWM_MATCH_DIR_UP;
chConfig[1].ch2ndMatchDir = PWM_MATCH_DIR_DOWN;
chConfig[1].ch1stPolarity = PWM_OUTPUT_POLARITY_ACTIVE_LOW;
chConfig[1].ch2ndPolarity = PWM_OUTPUT_POLARITY_ACTIVE_LOW;
chConfig[1].ch1stInitLevel =1;
chConfig[1].ch2ndInitLevel =1;
/* channel 4/5 */
chConfig[2].pairChannel = PWM_CH_4;
chConfig[2].ch1stValue = 500;
chConfig[2].ch2ndValue = 500;
chConfig[2].levelMode = PWM_LOW_TRUE;
chConfig[2].complementEn = ENABLE;
chConfig[2].deadtimeEn = ENABLE;
chConfig[2].ch1stMatchDir = PWM_MATCH_DIR_UP;
chConfig[2].ch2ndMatchDir = PWM_MATCH_DIR_DOWN;
chConfig[2].ch1stPolarity = PWM_OUTPUT_POLARITY_ACTIVE_LOW;
chConfig[2].ch2ndPolarity = PWM_OUTPUT_POLARITY_ACTIVE_LOW;
chConfig[2].ch1stInitLevel =1;
chConfig[2].ch2ndInitLevel =1;
pwmConfig.initTriggerEn = ENABLE;
pwmConfig.countMode = PWM_UP_DOWN_COUNT;
pwmConfig.combineChannelNum = 3;
pwmConfig.combineChConfig = chConfig;
pwmConfig.deadtime = 24;
pwmConfig.deadtimePsc = PWM_DEADTIME_DIVID_4;
pwmConfig.initChOutputEn =ENABLE;
/* pwm config */
config.mode = PWM_MODE_MODULATION;
config.initModeStruct = &pwmConfig;
config.clkSource = PWM_CLK_SOURCE_NONE;
config.clkPsc = 1;
config.maxValue = 1000-1;
config.interruptEn = ENABLE;
config.callBack = PWM_Callback;
PWM_Init(PWM1, &config);
/* Set interrupt priority */
NVIC_SetPriority(PWM1_IRQn, 0);
/* PWM Start */
PWM_SetClockSource(PWM1, PWM_CLK_SOURCE_APB);
GPIO_SetPinLevel(GPIOC, GPIO_PIN8, 0); //拉低测试端口
}
按上面的配置,可以测试,在PWM模块初始化期间,通道输出为对应通道的配置电平,在电机应用中可以确保在任何时候都不会出现MOS错误导通的情况。
|
|