本帖最后由 crazy2012 于 2013-8-29 15:29 编辑
airwill 发表于 2013-8-29 09:19
你想配置成什么呢? 最常用的是刹车变成全部无效低电平.
虽然设置有好多项, 也不算太复杂
测试的时候, 可以 ...
下面我写的可能比较多,希望你能耐心好好看看,代码部分你大概看下,看似好长其实很多是重复的配置。关键的地方我都说出来了。
另外这里面总是反复出现一个什么高电平、低电平有效啥的。我的理解就是:1就是高电平、就是有效电平,0则反之,不知道手册上引入有效电平这个概念有何意图。
我在做BLDC,我的硬件条件为上桥臂PMOS,低电平导通。下桥臂NMOS,高电平导通。
我需要的波形如下。
现在可以正常输出,遇到的问题是刹车功能不能按照我的意愿输出。
下图为正常输出的波形。
下图为刹车后,我需要CH1为高电平,CH1N为低电平,但是,却输出这个波形。
我的软件代码是在6step这个例程中修改的
这里我只写出关键代码
初始化配置如下:
=================================
/* Channel 1, 2,3 and 4 Configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = ps;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
/* Automatic Output enable, Break, dead time and lock configuration*/
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
TIM_BDTRInitStructure.TIM_DeadTime = 1;
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
6步换相代码如下,这里提示一下,请注意换相过程中对下桥臂的输出电平进行的调整
这里比较绕口的就是 Polarity_Low实际上是往极性控制位写1,所以会输出高电平,
而Polarity_High实际上是往极性控制位写0,所以会输出低电平,也就是手册中所说的异或(xor)。
=====================================================
if (step == 1)
{
/* Next step: Step 2 Configuration ---------------------------- */
/* Channel1 configuration */
// TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Enable);
#if 0
TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Disable);
/**OC1N=CC1NP,CC1NP=0下桥臂关*/
TIM_OC1NPolarityConfig(TIM1, TIM_OCNPolarity_High);
#endif
/* Channel2 configuration */
// TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_OCMode_PWM1 );
TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);
/*OC2N=CC2NP,CC2NP=1下桥臂开*/
TIM_OC2NPolarityConfig(TIM1, TIM_OCNPolarity_Low);
/* Channel3 configuration */
TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);
/*OC3N=CC3NP,CC3NP=0下桥臂关*/
TIM_OC3NPolarityConfig(TIM1, TIM_OCNPolarity_High);
step++;
}
else if (step == 2)
{
/* Next step: Step 3 Configuration ---------------------------- */
/* Channel1 configuration */
TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Disable);
#if 0
TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Disable);
/**OC1N=CC1NP,CC1NP=0下桥臂关*/
TIM_OC1NPolarityConfig(TIM1, TIM_OCNPolarity_High);
#endif
/* Channel2 configuration */
// TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Disable);
#if 0
TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);
/*OC2N=CC2NP,CC2NP=1下桥臂开*/
TIM_OC2NPolarityConfig(TIM1, TIM_OCNPolarity_Low);
#endif
/* Channel3 configuration */
// TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Enable);
#if 0
TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);
/*OC3N=CC3NP,CC3NP=0下桥臂关*/
TIM_OC3NPolarityConfig(TIM1, TIM_OCNPolarity_High);
#endif
step++;
}
else if (step == 3)
{
/* Next step: Step 4 Configuration ---------------------------- */
/* Channel1 configuration */
// TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Disable);
/*OC1N=CC1NP,CC1NP=1下桥臂开*/
TIM_OC1NPolarityConfig(TIM1, TIM_OCNPolarity_Low);
/* Channel2 configuration */
TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);
/*OC2N=CC2NP,CC2NP=0下桥臂关*/
TIM_OC2NPolarityConfig(TIM1, TIM_OCNPolarity_High);
/* Channel3 configuration */
// TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Enable);
#if 0
TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);
/*OC3N=CC3NP,CC3NP=0下桥臂关*/
TIM_OC3NPolarityConfig(TIM1, TIM_OCNPolarity_High);
#endif
step++;
}
else if (step == 4)
{
/* Next step: Step 5 Configuration ---------------------------- */
/* Channel1 configuration */
// TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Disable);
/*下桥臂常开*/
TIM_OC1NPolarityConfig(TIM1, TIM_OCNPolarity_Low);
TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Disable);
/* Channel2 configuration */
// TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Enable);
#if 0
TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);
/*OC2N=CC2NP,CC2NP=0下桥臂关*/
TIM_OC2NPolarityConfig(TIM1, TIM_OCNPolarity_High);
#endif
/* Channel3 configuration */
TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Disable);
#if 0
TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);
/*OC3N=CC3NP,CC3NP=0下桥臂关*/
TIM_OC3NPolarityConfig(TIM1, TIM_OCNPolarity_High);
#endif
step++;
}
else if (step == 5)
{
/* Next step: Step 6 Configuration ---------------------------- */
/* Channel1 configuration */
TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Disable);
/**OC1N=CC1NP,CC1NP=0下桥臂关*/
TIM_OC1NPolarityConfig(TIM1, TIM_OCNPolarity_High);
/* Channel2 configuration */
// TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Enable);
#if 0
TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);
/*OC2N=CC2NP,CC2NP=0下桥臂常关*/
TIM_OC2NPolarityConfig(TIM1, TIM_OCNPolarity_High);
#endif
/* Channel3 configuration */
// TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);
/*OC3N=CC3NP,CC3NP=1下桥臂开*/
TIM_OC3NPolarityConfig(TIM1, TIM_OCNPolarity_Low);
step++;
}
else
{
/* Next step: Step 1 Configuration ---------------------------- */
/* Channel1 configuration */
// TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Enable);
#if 0
TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Disable);
/**OC1N=CC1NP,CC1NP=0下桥臂关*/
TIM_OC1NPolarityConfig(TIM1, TIM_OCNPolarity_High);
#endif
/* Channel2 configuration */
TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Disable);
#if 0
TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);
/*OC2N=CC2NP,CC2NP=0下桥臂关*/
TIM_OC2NPolarityConfig(TIM1, TIM_OCNPolarity_High);
#endif
/* Channel3 configuration */
// TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);
/*OC3N=CC3NP,CC3NP=1下桥臂开*/
TIM_OC3NPolarityConfig(TIM1, TIM_OCNPolarity_Low);
step = 1;
我发现采用上面的代码刹车后,上下桥臂照样有输出,只不过成了下面这种情况。
于是我放弃硬件刹车功能改用软件刹车,当需要刹车时候,不再执行6步换相的函数代码,而是采用下面的方法。
这样可以实现我的功能。就是硬件刹车还是用不起来。
/* Channel1 configuration */
TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Disable);
/**OC1=CC1P,CC1P=1上桥臂关*/
TIM_OC1PolarityConfig(TIM1, TIM_OCPolarity_Low);
TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Disable);
/**OC1N=CC1NP,CC1NP=0下桥臂关*/
TIM_OC1NPolarityConfig(TIM1, TIM_OCNPolarity_High);
我对下面的几个参数组合配置还是迷糊,请问里面的空闲状态到底什么时候是空闲状态,是指刹车后,不再输出PWM,输出指定的电平么?
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;
下面两个更是诡异
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
下面这个表格感觉太隐晦了,不知道是我理解能力差还是他这个表格太简单了,看的头晕啊,我调试了3天了。
CR2
CCMR1
CCER
BDTR
这几个寄存器我都有好好看过,但是还得觉得理解不透侧。
下面这个表格看的我是云里来雾里去啊
|