STM32F407ZGT6控制电机

STM32F407ZGT6控制电机

大概思路

1.利用定时器产生可控方波(选好定时器及通道),
需要注意的是设置PWM输出引脚时要将引脚复用到定时器
2.将电机控制引脚设置成推挽输出模式
3.改变占空比即可改变速度
4.采用的电机驱动为TB6612,这里不做介绍
5.我这里用的是定时器1的通道1,2,3,4。可自行修改
STM32F407ZGT6控制电机_第1张图片

定时器初始化

定时器1初始化

void TIM1_PWM_Init(u32 arr,u32 psc)
{
	//此部分需手动修改IO口设置
	int ccr1=500,ccr2=500,ccr3=500,ccr4=500;
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);  	//TIM1时钟使能
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); 	//使能时钟
	
	GPIO_PinAFConfig(GPIOE,GPIO_PinSource9,GPIO_AF_TIM1);
	GPIO_PinAFConfig(GPIOE,GPIO_PinSource11,GPIO_AF_TIM1);
	GPIO_PinAFConfig(GPIOE,GPIO_PinSource13,GPIO_AF_TIM1); //GPIOE9,E11,E13,E14复用为定时器1
	GPIO_PinAFConfig(GPIOE,GPIO_PinSource14,GPIO_AF_TIM1);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_11|GPIO_Pin_13|GPIO_Pin_14;           //GPIOF9
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
	GPIO_Init(GPIOE,&GPIO_InitStructure);              //初始化IO口
	  
	TIM_TimeBaseStructure.TIM_Prescaler=psc;  //定时器分频
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
	TIM_TimeBaseStructure.TIM_Period=arr;   //自动重装载值
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
	
	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
	
	TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);//初始化定时器1
	

	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
///**************
  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;//输出同相
		TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 
	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High;


  TIM_OCInitStructure.TIM_Pulse = ccr1; 
	TIM_OC1Init(TIM1, &TIM_OCInitStructure); 
	
	TIM_OCInitStructure.TIM_Pulse = ccr2; 
	TIM_OC2Init(TIM1, &TIM_OCInitStructure); 
  
  
	TIM_OCInitStructure.TIM_Pulse = ccr3; 
	TIM_OC3Init(TIM1, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM1 OCx

   TIM_OCInitStructure.TIM_Pulse = ccr4; //设置待装入捕获比较寄存器的脉冲值
	TIM_OC4Init(TIM1, &TIM_OCInitStructure); 

	TIM_Cmd(TIM1, ENABLE); 
 TIM_CtrlPWMOutputs(TIM1,ENABLE);
}

高级定时器与通用定时器异同

1.采用定时器产生可控方波,高级定时器TIM1、TIM8与通用定时器配置有所不同,比通用定时器多两行代码:

下面展示一些 内联代码片

TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;//重复计数器的值
TIM_CtrlPWMOutputs(TIM1,ENABLE);//主输出使能,当使用的是通用定时器时,这句不需要
电机IO口初始化

IO设置为推挽输出即可
我这里用的IO为D0,D1,D2,D3,D10,D11,B14,B15
(4个电机,8个IO)

void MOTOR_GPIO_Config(void)  电机控制对应IO口
{
	/*定义一个GPIO_InitTypeDef类型的结构体*/
	GPIO_InitTypeDef GPIO_InitStructure;

	/*开启GPIOB的外设时钟*/
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); 

	/*选择要控制的引脚*/
    // 4个电机 ,8个IO口	
  	GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_10|GPIO_Pin_11;	

	/*设置引脚模式为通用推挽输出*/
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;   

	/*设置引脚速率为50MHz*/   
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 

	/*调用库函数,初始化*/		  
	  	GPIO_Init(GPIOD, &GPIO_InitStructure);		 
	
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
	GPIO_InitStructure.GPIO_Pin =GPIO_Pin_14|GPIO_Pin_15;
	  GPIO_Init(GPIOB, &GPIO_InitStructure);

	GPIO_SetBits(GPIOD,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_10|GPIO_Pin_11);
  GPIO_SetBits(GPIOB,GPIO_Pin_14|GPIO_Pin_15);
}
改变占空比调速

调用函数改变占空比即可改变调速

TIM_SetCompareN(TIMx, Compare2)

N为定时器哪个通道,x为定时器几,Compare2为自己设置的数值

总结

控制电机、舵机这一类模块电源最好跟其它模块电源分开,不然对其它模块工作会有影响。(比如循迹模块啥的)。控制原理已知,具体效果看实际,需进行多次试验。

你可能感兴趣的:(单片机,stm32)