STM32学习笔记:PWM互补输出(无刷直流电机驱动控制)

需要达成的目的为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, 其他引脚输出高电平,达成目的。

  • 4
    点赞
  • 94
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值