需要达成的目的为CH1通道输出PWM波,CH1N通道输出高电平等。
最新方法已在新博客贴出,更为简便。
==========================以下为较为复杂的初始方法===========================
最近科研训练在做无刷电机的控制。
需要达成的目的为CH1通道输出PWM波,CH1N通道输出高电平等。
算法采用六步换向算法,开环系统。
主控芯片选用STM32F103VCT6。
PWM输出引脚如下:
采用了高级定时器TIM1的完全重映射引脚。

PE9->UH 1
PE10->UL 2N
PE11->VH 2
PE12->VL 3N
PE13->WH 3
PE14->WL 4
通道设置的有点问题,正确的较为方便的应该是UH1接CH1,UL1接CH1N(1通道的互补通道),后续利用飞线解决问题。(这里不处理也可以)
利用光耦将功率电与控制部分隔离开。光耦芯片使用6N137,注意:6N137是反逻辑的。即输入高电平经光耦后输出低电平。
6N137的真值表:
隔离电路设计:
驱动芯片选用IR2136,由于尚未实测IR2136是否能成功驱动MOSFET,暂不贴电路设计了。
无刷电机旋转时,需要导通一个上桥臂和一个下桥臂,如UH、WL导通,其他桥臂关断(UH指U相上桥臂,WL为W相下桥臂),此时需要PWM_UH与PWM_WL引脚输出PWM波,其他引脚为高电平输出(经光耦后反相为低电平)。
在这里贴出一个比较容易理解的方法:
需要说明的是:
需要达成的目的为CH1通道输出PWM波,CH1N通道输出高电平。(并不一定是这样的输出,只是通过修改CCR寄存器的值与比较值时,CH1与CH1N无法达到这样的目的,只能同时输出相同或互补的PWM波)。
这里达成目的的简单粗暴的方法为:首先所有通道正常输出PWM波,然后失能所有不需要输出PWM的引脚,通过配置GPIO,使这些不需要输出PWM的引脚输出高电平。
PWM输出相关配置:
PWM的占空比在主函数中配置。
//PE9(UH)、PE11(VH)、PE13(WH)、PE14(WL)、PE10(UL)、PE12(VL) PWM 输出
void TIM1_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE); //使能GPIOE时钟时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //使能AFIO时钟
GPIO_PinRemapConfig(GPIO_FullRemap_TIM1,ENABLE);//映射为TIMx
//设置该引脚为复用输出功能,输出TIMx_CHx的PWM脉冲波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_11|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_10|GPIO_Pin_12; //TIMx_CHx
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 不分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;//互补通道输出比较极性为低
//根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC1Init(TIM1, &TIM_OCInitStructure); //PE9
TIM_OC2Init(TIM1, &TIM_OCInitStructure); //PE11
TIM_OC3Init(TIM1, &TIM_OCInitStructure); //PE13
TIM_OC4Init(TIM1, &TIM_OCInitStructure); //PE14
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);//使能或者失能 TIMx 在 CCR1 上的预装载寄存器
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_CtrlPWMOutputs(TIM1,ENABLE); //MOE 主输出使能
TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器
TIM_Cmd(TIM1, ENABLE); //使能TIMx
}
GPIO配置:
void GPIOx_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); // 使能PE端口时钟
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11|GPIO_Pin_13|GPIO_Pin_10|GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; // 推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; // IO口速度为50MHz
GPIO_Init(GPIOE, &GPIO_InitStructure); // 根据设定参数初始化GPIOB.5
//GPIO_SetBits(GPIOE, GPIO_Pin_9|GPIO_Pin_11|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_10|GPIO_Pin_12);
}
以UH、WL输出PWM,其他引脚输出高电平为例:
void GPIOE_High(void)
{
GPIOx_Init();
GPIO_SetBits(GPIOE,GPIO_Pin_11|GPIO_Pin_13|GPIO_Pin_12|GPIO_Pin_10);//引脚输出高电平
}
利用宏定义:
#define PWMUVW_Dis TIM1->CCER &= ~(TIM_CCER_CC1E|TIM_CCER_CC2NE|TIM_CCER_CC2E|TIM_CCER_CC3NE|TIM_CCER_CC3E|TIM_CCER_CC4E);//取消使能UVW所有的输出,所有管子均关闭
#define UH_ON TIM1->CCER |= TIM_CCER_CC1E;
#define UL_ON TIM1->CCER |= TIM_CCER_CC2NE;
#define VH_ON TIM1->CCER |= TIM_CCER_CC2E;
#define VL_ON TIM1->CCER |= TIM_CCER_CC3NE;
#define WH_ON TIM1->CCER |= TIM_CCER_CC3E;
#define WL_ON TIM1->CCER |= TIM_CCER_CC4E;
#define PWMUH_ON_WL_ON PWMUVW_Dis; UH_ON; WL_ON; GPIOx_Init(); GPIO_SetBits(GPIOE,GPIO_Pin_11|GPIO_Pin_13|GPIO_Pin_12|GPIO_Pin_10);
最后进行主函数的编写:
int main(void)
{
//delay_init();
//PWM输出测试
TIM1_PWM_Init(1799,1);//不分频。PWM频率=72000/(1799+1)=40 KH
TIM_SetCompare1(TIM1,300); //PE9,通过修改300这个数字来修改占空比
TIM_SetCompare2(TIM1,300); //PE11、PE10
TIM_SetCompare3(TIM1,300); //PE13
TIM_SetCompare4(TIM1,300); //PE14
PWMUH_ON_WL_ON;
}
利用KEIL自带的虚拟示波器验证结果:
发现,只有PE9与PE14输出PWM, 其他引脚输出高电平,达成目的。