为了进一步加深Mbed OS下 C++类的印象,我们来编写一个步进电机的控制类。
步进电机的连接方式
步进电机有许多种接线方式,常用的是4 相5 线连接。
步进电机的控制序列
控制步进电机的方法比较简单,只要按规律向1,2,3,4 线发送脉冲就可以了,下表总结了控制序列
步进电机的控制方式
步进电机一个脉冲走一步(step),步数/圈其实也就是步进电机走一圈所用的步数。我们选择的步进电机,每一步走1.8 度。也就是说,步进电机转360 度需要200个脉冲。
步进电机接口的驱动
处理器的GPIO驱动的能力不能直接驱动步进电机的,需要增加驱动能力,在Modular-2 模块化电脑中,我们使用MOS 管驱动的数字输出IO扩展板来驱动步进电机。最大电流可达2A。
Mbed OS 中代码
我们将步进电机的控制封装成一个类Step,类定义(sMotor.h)
#include "mbed.h"
class sMotor {
public:
sMotor(PinName A0, PinName A1, PinName A2, PinName A3); //motor constructor
void step(int num_steps, int direction, int speed);
void anticlockwise();
void clockwise();
void stop();
private:
uint8_t state;
DigitalOut _A0;
DigitalOut _A1;
DigitalOut _A2;
DigitalOut _A3;
};
这个类中有三个成员函数
anticlockwise 逆时针
逆时针方向走一步
clockwise顺时针
瞬时钟方向走一步
step(int num_steps, int direction, int speed);
走num_step 步。
direction 是方向 0-顺时针,1-逆时针。
speed 为速度
sMotor.cpp 代码
#include "sMotor.h"
#include "mbed.h"
int motorSpeed; // Steper speed
sMotor::sMotor(PinName A0, PinName A1, PinName A2, PinName A3) : _A0(A0), _A1(A1), _A2(A2), _A3(A3) { // Defenition of motor pins
_A0=1;
_A1=1;
_A2=1;
_A3=1;
state=0;
}
void sMotor::anticlockwise() { // rotate the motor 1 step anticlockwise
switch (state) { // activate the ports A0, A2, A3, A3 in a binary sequence for steps
case 0: {
_A0=1;
_A1=1;
_A2=1;
_A3=0;
}
break;
case 1: {
_A0=1;
_A1=1;
_A2=0;
_A3=0;
}
break;
case 2: {
_A0=1;
_A1=1;
_A2=0;
_A3=1;
}
break;
case 3: {
_A0=1;
_A1=0;
_A2=0;
_A3=1;
}
break;
case 4: {
_A0=1;
_A1=0;
_A2=1;
_A3=1;
}
break;
case 5: {
_A0=0;
_A1=0;
_A2=1;
_A3=1;
}
break;
case 6: {
_A0=0;
_A1=1;
_A2=1;
_A3=1;
}
break;
case 7: {
_A0=0;
_A1=1;
_A2=1;
_A3=0;
}
break;
}
if (state==7) state=0;else state=7;
wait_us(motorSpeed); // wait time defines the speed
}
void sMotor::clockwise() { // rotate the motor 1 step clockwise
switch (i) {
case 0: {
_A0=1;
_A1=1;
_A2=1;
_A3=0;
}
break;
case 1: {
_A0=1;
_A1=1;
_A2=0;
_A3=0;
}
break;
case 2: {
_A0=1;
_A1=1;
_A2=0;
_A3=1;
}
break;
case 3: {
_A0=1;
_A1=0;
_A2=0;
_A3=1;
}
break;
case 4: {
_A0=1;
_A1=0;
_A2=1;
_A3=1;
}
break;
case 5: {
_A0=0;
_A1=0;
_A2=1;
_A3=1;
}
break;
case 6: {
_A0=0;
_A1=1;
_A2=1;
_A3=1;
}
break;
case 7: {
_A0=0;
_A1=1;
_A2=1;
_A3=0;
}
break;
}
if (state==0) state=7;else state--;
wait_us(motorSpeed); // wait time defines the speed
}
void sMotor::step(int num_steps, int direction, int speed) {// steper function: number of steps, direction (0- right, 1- left), speed (default 1200)
int count=0; // initalize step count
motorSpeed=speed; //set motor speed
if (direction==0) // turn clockwise
do {
clockwise();
count++;
} while (count
主程序
#include "mbed.h"
#include "sMotor.h"
Serial pc(USBTX, USBRX);
sMotor motor(PE_13, PE_14, PE_8, PB_1); // creates new stepper motor: IN1, IN2, IN3, IN4
DigitalOut Enable(PA_8);
DigitalOut Reset(PE_6);
int step_speed = 1200 ; // set default motor speed
int numstep = 200 ; // defines full turn of 360 degree
int main() {
int sel;
int i;
Enable=1;
Reset=1;
Reset=0;
Enable=0;
//Credits
printf("4 Phase Stepper Motor v0.1 - Test Program\r\n")
while(1)
{
motor.step(numstep*2,0,step_speed);
wait(1);
motor.step(numstep*2,1,step_speed);
wait(1);
}
}
顺时针转2圈,逆时针转两圈。
你可以不了解sMotor 类的实现,直接使用这个类。任何一个复杂的系统都是由简单的组件构成的。关键是我们要掌握构建的方法。
正是因为Mbed OS 采取了C++类来构建库和API,使得编写应用程序异常地简单。