在很多学科竞赛中,我们时常会使用到电机。那么本篇文章我们就来说说如何基于STM32F4xx来驱动电机。
首先本篇文章的内容主要有以下几点:
一.我们需要控制什么样的电机。
二.控制这个电机所需要学习的知识。
三.如何对电机的速度进行控制。
一. 我们需要控制什么样的电机
我们所要控制的是带有编码器的电机,编码器的工作原理下文会讲到,这里将他理解为可以读出当前电机速的一个模块就好。
接下来我们对上图电机的接线简单的说明一下:由上至下依次标号1 ~ 6
1,6号线:电机电源输入。
2,5号线:电机编码器供电。
3,4号线双向编码器读值线路。
二、控制这个电机所需要学习的知识。
1.初始化相关GPIO口。
示例:
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB,PE端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB.5
GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB.5 输出高电平
初始化GPIO口几点注意事项:
1.开启时钟的总线需要准确。(查找总线翻阅参考手册即可)
2.配置的输出模式需要根据使用的用途进行调整。
2. TIM定时器使用。
TIM定时器使用之定时器:顾名思义就是将TIM定时器作为定时器然后使其产生中断,然后我们对中断服务函数进行操作。
这部分最重要的就是了解定时器定时时间的计算:
例:寄存器配置如下:
TIM_TimeBaseInitStruct.TIM_Period = (10000 - 1); //重装载值
TIM_TimeBaseInitStruct.TIM_Prescaler = (7200 - 1); //预分频系数
在默认时钟为72M时计算如下:
预分频系数为7199,那么定时器时钟频率为72M / 7200 = 10kHz
周期为0.1ms,定时器计数达到重装值时候,产生定时器中断
则定时器中断时间为10000 * 0.1ms = 1s
TIM定时器使用之PWM输出:即使用TIM的PWM模式使对应IO口输出PWM方波。部分配置主要代码:
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1 设置为模式一即小于CCRX为有效
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse =250; //CCRx
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出的有效极性 低
TIM_OC3Init(TIM8, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM8 通道3
TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable); //使能TIM8在CCR1上的预装载寄存器
TIM_ARRPreloadConfig(TIM8,ENABLE);//ARPE使能 //这个周期生效或下个周起生效
TIM_Cmd(TIM8, ENABLE); //使能TIM8
TIM_CtrlPWMOutputs(TIM8, ENABLE); //高级定时器需要这句才能输出PWM
TIM定时器使用之编码器读值:即使用定时器的编码器模式,对电机速度进行读值。部分配置主要代码:
// 定时器编码器模式初始化
//配置时基单元
TIM_DeInit(TIM3); //复位TIM3相关寄存器
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); //初始化
TIM_TimeBaseStructure.TIM_Prescaler = 0; //分频值
TIM_TimeBaseStructure.TIM_Period = 65535; //自动重装载
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Down; // 这里可以自己设置,或使用默认值
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
//此处:TIM_ICPolarity_Rising 意思是不反相
TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising ,TIM_ICPolarity_Rising); // 这里配置了编码器模式
//配置编码器
TIM_ICStructInit(&TIM_ICInitStructure); //该结构中按缺省值(默认)填入
TIM_ICInitStructure.TIM_Channel=TIM_Channel_1 |TIM_Channel_2; //通道
TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection =TIM_ICSelection_DirectTI; //设置
TIM_ICInitStructure.TIM_ICFilter = 0; //配置滤波器值
TIM_ICInit(TIM3, &TIM_ICInitStructure); //设置通道
TIM_SetCounter(TIM3, 0);
TIM_Cmd(TIM3, ENABLE); //定时器总开关
这里使用的是TIM3定时器的通道1和2。
3.PID算法相关知识:
这部分学习可参考:https://www.bilibili.com/video/BV1Ds411t7x4?from=search&seid=17723158423363342532
三.如何对电机的速度进行控制
学习完上面这部分,我们对于控制电机所需要用到的部分已经清楚了。
接下来我们在只要将上面的配置结合起来就能做到对电机的控制。
结合思路如下:
- 初始化GPIO口。
- 设定一个定时器为编码器模式,并初始化它。
- 设置一个定时器,负责每隔一段时间将编码器的计数值读出来。
- 设置PWM输出,相关寄存器配置。
- 结合编码器读出的数值编写PID算法。
- 根据PID算法所返回的值,改变PWM占空比。