NikTalk
Hi!大家好,我是Nik。一名在人工智能+物联网行业混迹多年的AIOT架构工程师兼产品经理。欢迎您来到我的博客!这里记录了我的AIOT职业生涯,从最开始的一名普通嵌入式软件工程师->到嵌入式系统工程师->再到AIOT架构师兼产品经理一路上的所学所感所得。希望这些知识,经验,技术以及感悟对后来的你,在技术学习以及职业发展的道路上有所帮助。记得关注我,我将不定期分享一些AIOT相关的技术和行业信息。唯一微信号:aiotnik

Motor电机-05

AIOTNIK-ONE开发板提供了由一颗spi驱动芯片驱动的8pin电机控制接口、可接AF(自动变焦)镜头,也可以接一个或者两个4相步进电机。接口pin定义原理图和实物图如下:

步进电机和AF镜头的硬件接线

1、四相步进电机的接线原理图和实物图如下。

2、AF自动变焦镜头直接插线即可,如下图。

电机和AF镜头控制代码

由于主控是通过控制SPI电机驱动芯片去控制8个gpio口的电信号去控制电机的转动,方向以及速度的。对于主控来说,接在8pin座子上的是两个四相步进电机还是AF自动变焦镜头都是一样的。所以驱动四相步进电机转动和控制AF镜头自动变焦的代码是一样的,如下给出了控制代码的头文件和源文件的源码。
(1)motortest.h内容如下:

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#ifndef __motortest_H__
#define __motortest_H__
#define MOTOR_MOVE_STOP 0x0
#define MOTOR_MOVE_RUN 0x1
/* directional_attr */
#define MOTOR_DIRECTIONAL_UP 0x0
#define MOTOR_DIRECTIONAL_DOWN 0x1
#define MOTOR_DIRECTIONAL_LEFT 0x2
#define MOTOR_DIRECTIONAL_RIGHT 0x3
#define MOTOR1_MAX_SPEED 1000
#define MOTOR1_MIN_SPEED 10
/* ioctl cmd */
#define MOTOR_STOP 0x1
#define MOTOR_RESET 0x2
#define MOTOR_MOVE 0x3
#define MOTOR_GET_STATUS 0x4
#define MOTOR_SPEED 0x5
#define MOTOR_GOBACK 0x6
#define MOTOR_CRUISE 0x7
enum motor_status {
MOTOR_IS_STOP,
MOTOR_IS_RUNNING,
};
struct motor_message {
int x;
int y;
enum motor_status status;
int speed;
};
struct motors_steps{
int x;
int y;
};
struct motor_move_st {
int motor_directional;
int motor_move_steps;
int motor_move_speed;
};
struct motor_status_st {
int directional_attr;
int total_steps;
int current_steps;
int min_speed;
int cur_speed;
int max_speed;
int move_is_min;
int move_is_max;
};
struct motor_reset_data {
unsigned int x_max_steps;
unsigned int y_max_steps;
unsigned int x_cur_step;
unsigned int y_cur_step;
};
struct motors_steps jb_motors_steps;
struct motor_message jb_motor_message;
struct motor_status_st motor_status;
struct motor_move_st motor_action;
struct motor_reset_data motor_reset_data;
#endif

(2)motortest.c内容如下:

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include "motortest.h"
int main(int argc, const char* argv[])
{
int a,b,d,e;
int fd = open("/dev/motor", 0);
while(1)
{
printf("action:\n");
printf("1:MOTOR_STOP 2:MOTOR_RESET 3:MOTOR_MOVE 4:MOTOR_GET_STATUS 5:MOTOR_SPEED 6:MOTOR_GOBACK 7:MOTOR_CRUISE\n");
printf("choose:");
scanf("%d",&d);
switch(d)
{
case MOTOR_STOP://电机停止转动
ioctl(fd, d,0);
break;
case MOTOR_RESET://电机复位
memset(&motor_reset_data, 0, sizeof(motor_reset_data));
motor_reset_data.x_max_steps = 1000;
motor_reset_data.y_max_steps = 600;
ioctl(fd, d,&motor_reset_data);
printf("x_max_steps=%d,y_max_steps=%d,x_cur_step=%d,y_cur_step=%d\n",
motor_reset_data.x_max_steps,motor_reset_data.y_max_steps,
motor_reset_data.x_cur_step,motor_reset_data.y_cur_step);
break;
case MOTOR_MOVE://电机x,y转动指定步数,x:表示横向电机,y:表示纵向电机
printf("steps x:");
scanf("%d",&a);
printf("steps y:");
scanf("%d",&b);
printf("x=%d,y=%d\n",a,b);
jb_motors_steps.x = a;
jb_motors_steps.y = b;
ioctl(fd, d, (unsigned long)&jb_motors_steps);
break;
case MOTOR_GET_STATUS://获取电机当前的步数,状态,以及转速
ioctl(fd, d, (unsigned long)&jb_motor_message);
printf("xcurrent_steps=%d\n",jb_motor_message.x);
printf("ycurrent_steps=%d\n",jb_motor_message.y);
printf("cur_status=%d\n",jb_motor_message.status);
printf("cur_speed=%d\n",jb_motor_message.speed);
break;
case MOTOR_SPEED://设置电机转动的速度,建议设置500,最大不过1000
printf("speed:");
scanf("%d",&e);
ioctl(fd, d, (unsigned long)&e);
break;
case MOTOR_GOBACK://电机回滚到转动前的位置
ioctl(fd, d,0);
break;
case MOTOR_CRUISE://电机循环转动
ioctl(fd, d,0);
break;
}
}
close(fd);
return 0;
}

电机控制代码编译

(1)新建一个目录motor_test,将motortest.c、 motortest.h保存在这个目录下。

(2)在该目录下用工具链进行编译。

mips-linux-uclibc-gcc motortest.h motortest.c -o motortest

(3)将编译得到的motortest二进制可执行程序拷贝到板子上去运行即可控制电机转动。

【注】在电机运转之前,需要先复位。所以在运行motortest的时候,先选择2:MOTOR_RESET对电机进行复位后,再对电机进行其他的操作。