STM32F1基于H桥的电机控制程序分析

N-MOS H桥结构

在这里插入图片描述

控制原理

N-MOS的G极与S级的电压差大于某一值的时候,D极和S极之间导通,DS电阻极小,可看作导线,否则DS之间视为断路。

因此有以下控制方法
在这里插入图片描述当 Signal-A 和 Signal-D > 24V+VGS
且Signal-B 和 Signal-C < 24V+VGS 的时候,
MOSA和MOSD视为导通,BC断开,电流从左至右流过电机使之旋转。
反之,
在这里插入图片描述当 Signal-B 和 Signal-C > 24V+VGS
且Signal-A 和 Signal-D < 24V+VGS的时候,
MOSB和MOSC视为导通,AD断开,电流从右至左流过电机使之反转。

MOS驱动

因为不借助外部电路的话,芯片不可能提供一个大于24V+VGS的信号,所以在H桥电路中会用到MOS驱动芯片。
一般来讲,
MOS驱动的信号输入端接单片机PWM输出。
控制几个MOS就需要接几个输入信号。
电源输入端需要从外部接入高电压(高到足以导通MOS管)。
信号输出端接MOS的G极。
在这里插入图片描述例如上图即为某一款MOS驱动芯片的数据手册提供的经典电路图。
其中HIN和LIN为上下桥臂信号输入。
HO和LO为上下桥臂信号输出,也就是上文的Signal-ABCD。
Vcc为芯片工作所需电压。
VB和VS就是上下桥臂输出信号的电源(一个绝对电压,一个偏移电压)。
二极管和电容用于升压,VCC和GND之间电容用于滤波。
在这里插入图片描述工作的时候就这样:
LIN = 0 则 LO = 0
LIN = 1 则 LO = 1
HIN 和 HO同理。

调速的实现

通过上面对MOS驱动的了解,我们可以得知在驱动芯片输入端给1,输出端会输出1,给0就输出0。
那么我们就可以输入一个低压PWM信号来得到一个高压PWM信号。这样就可以控制MOS的导通与否来改变电机两端电压的波形,从而改变电机的电流,实现电机的调速。

(要是想采集电机的电流的话,在两个下桥臂MOS和GND之间接一个数毫欧的大功率电阻就可以实现。)

在这里插入图片描述
/***********************/

1.受限单极模式
A:PWM B:OFF C:OFF D:ON
在这里插入图片描述当PWM高电平时,电机两端分别为24V和GND,有电流流过,电机产生扭矩,进行转动。
当PWM低电平时,电机两端未导通,不形成闭合回路,没有电流流过,此时电机的转动没有力来维持,难以控制。

优点:控制方法简单,一个单独PWM即可进行控制。
缺点:控制效果不好,稳定性也差。

在这里插入图片描述
2.单极模式
A:PWM B:OFF C:互补PWM D:ON
在这里插入图片描述

大致跟受限单极模式相同,但是当A信号为0时,C信号1,此时电机两端虽然都是与GND相连,但是此时形成了闭合回路,如下图。
在这里插入图片描述
电机中仍然有电流流过,虽然电流会减小,但是仍会产生磁场,仍会产生力矩来继续控制电机转动。

优点:转动时力的连续性好,启动速度快。
缺点:速度快要接近0时没有上图中2阶段的电流控制,此时与受限单极模式缺点相同。

在这里插入图片描述

3.双极模式
A:PWM B:PWM2 C:互补PWM D:互补PWM2

在这里插入图片描述

双极模式下,AB为互补的PWM,CD分别是他们的互补信号,在AD导通时电流方向如下
在这里插入图片描述然后下一时刻AD断开,BC导通,电流方向如下
在这里插入图片描述
在此时刻,电流会沿着原来的方向减小,如果此时间更长,电流会减为0后反向增加。

最终电机的转动方向就由PWM和PWM1共同决定。
若A的PWM占空比高于50%则电流从左至右,
若低于50%则从右至左。

优点:继承单极模式优点的基础下,在速度快要接近于0时也可以提供一定的力矩,加减速性能更好,因此正反转的性能优于单极模式。控制效果好。
缺点:控制更复杂,工作时4个MOS都在工作,功耗大。

控制程序编写

在这里插入图片描述
基于电路设计程序
由图可知,
PWM用的是TIM1的通道3生成
PWM-N是用TIM1的通道3的互补通道生成
PWM1用的是TIM1的通道2
PWM1-Nxxxxxxxxxxxxxx2的互补通道

先配置PWM生成

在这里插入代码片
void Pwm_Init(void)
{
	GPIO_InitTypeDef			GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef		TIM_TimeBaseStructure;
	TIM_OCInitTypeDef			TIM_OCInitStructure;
	TIM_BDTRInitTypeDef			TIM_BDTRInitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO ,ENABLE);
	//时钟使能
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	//GPIOA初始化
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14|GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	//GPIOB初始化
	TIM_DeInit(TIM1);
	TIM_TimeBaseStructure.TIM_Prescaler = 2;//预分配系数
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned2;//计数模式
	TIM_TimeBaseStructure.TIM_Period = 700;//PWM的周期值
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;
	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;//pwm模式
	TIM_OCInitStructure.TIM_OutputState =TIM_OutputState_Disable;
	TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;	
	//此处将输出和互补输出先都关闭
	//到时候确定控制模式后再改
	//单极模式和双极模式需要打开互补通道
	TIM_OCInitStructure.TIM_Pulse =700;
	
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 
	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
	//此处极性设置也可以后面更改CCER来改变
	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
	TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
	TIM_OC2Init(TIM1,&TIM_OCInitStructure);
	TIM_OC3Init(TIM1,&TIM_OCInitStructure);
	//通道2,3初始化
	TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
	TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
	TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
	TIM_BDTRInitStructure.TIM_DeadTime = 100;
	//死区时间
	TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
	TIM_BDTRInitStructure.TIM_BreakPolarity =  TIM_BreakPolarity_Low;
	TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;
	TIM_BDTRConfig(TIM1,&TIM_BDTRInitStructure);
	TIM_OC2PreloadConfig(TIM1,TIM_OCPreload_Enable);
	TIM_OC3PreloadConfig(TIM1,TIM_OCPreload_Enable);
	//重装载使能
	TIM_SelectInputTrigger(TIM1, TIM_TS_ITR2);
	//选择触发源
	TIM_CtrlPWMOutputs(TIM1,ENABLE);
	TIM_Cmd(TIM1,ENABLE);
}

根据电路不同,配置也有差距。

配置好之后就是根据不同控制模式来编写控制程序了。

模式TIM1 CH2TIM1 CH2NTIM1 CH3TIM1 CH3N
受限单极模式 (正转)1000
受限单极模式 (反转)0010
单极模式(正转)1100
单极模式(反转)0011
双极模式1111

大家可以根据自己的电路来列出像我这个表一样的配置表
然后在CCER寄存器修改即可
例如,单极模式的正反转
speed是我们输入的占空比,speed<周期。

void set_pwm(int speed)
{
	if(speed > 0)
	{
		TIM1->CCER = 0x10;//这个值不懂的话继续往后看
	}
	else if(speed < 0)
	{
		TIM1->CCER = 0x0100;//CCER中输出极性根据自己的需要可以改
		speed = -speed;
	}
  	speed = 700 - speed;
	if(speed <= 10) 
	{
		speed = 10;
	}
	TIM1->CCR2=speed;
	TIM1->CCR3=speed;
}

其中CCER的值需要通过上面的表和接下来这个表来确定

在这里插入图片描述

上图未截完,0位是CC1E:通道1输出使能

例如我要使能CH2
那么CH2使能这一位就是1,否则是0。
如下:
受限单极正转:000000000010000 = 0x10
受限单极反转:000000100000000 = 0x100
单极模式正转:000000001010000 = 0x50
单极模式反转:000010100000000 = 0x500
双极模式正反:000010101010000 = 0x550

至此控制程序也完毕了。

注:在单极模式下和受限单极模式下,改变CCER值后一定要记得将另一边桥臂的信号给出一高一低。
最简单的方法就是GPIO_SetBits()和GPIO_ResetBits()。
不过更实用的方法就是直接在CCER中一起改变。

	TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
	TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;

因为之前的配置中我们使能了OSSR,那么对应下表圈出来的地方。

OCx=CCxP,OCxN=CCxNP

也就是
通道x输出=CCxP的值,通道x互补通道的输出=CCxNP的值。
CCxP=0则通道x为低电平,CCxP=1则通道x为高电平。

那么据此我们就可以在CCER中直接写入CCxP和CCxNP来控制另一边桥臂的高低电平。
在这里插入图片描述那么在单极模式中,
正转:CCER: 0000 1000 0101 0000 = 0x850
反转:CCER: 0000 0101 1000 0000 = 0x580

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值