本帖最后由 t_fisher 于 2014-7-11 23:14 编辑
本文主要介绍使用原始C语言开发程序,来操作EV3的motor以及传感器等。今天主要介绍对motor的控制,传感器后续介绍。
首先来看看EV3程序的简单原理。EV3通过内核模块提供了各个外设的驱动程序,相应的驱动程序会在/dev目录下生成对应的设备文件。通过操作文件的模式来访问对应的外设。这也是UNIX/LINUX系统统一处理各种外设的通用方法。motor的操作主要是使用write函数发起控制命令,其他传感器的操作主要是使用mmap各种状态映射到内存后直接访问。
开发流程 加载内核模块 如果是直接启动官方固件,相对应的内核都已经加载了。如果是自制系统,则需要执行如下的脚本。关于如何从官方固件构建自制系统,可以参考我的日志。
启动脚本init.sh,修改自EV3源码
sync cd /home/root/lms2012/sys var=$(printf 'HostStr=%s SerialStr=%s' $(cat/home/root/lms2012/sys/settings/BrickName) $(cat/home/root/lms2012/sys/settings/BTser)) echo $var > /home/root/lms2012/sys/settings/UsbInfo.dat
insmod ${PWD}/mod/d_iic.ko `cat/home/root/lms2012/sys/settings/HwId` insmod ${PWD}/mod/d_uart.ko `cat/home/root/lms2012/sys/settings/HwId` insmod ${PWD}/mod/d_power.ko `cat/home/root/lms2012/sys/settings/HwId` insmod ${PWD}/mod/d_pwm.ko `cat/home/root/lms2012/sys/settings/HwId` insmod ${PWD}/mod/d_ui.ko `cat /home/root/lms2012/sys/settings/HwId` insmod ${PWD}/mod/d_analog.ko `cat/home/root/lms2012/sys/settings/HwId` insmod ${PWD}/mod/d_usbdev.ko `cat/home/root/lms2012/sys/settings/UsbInfo.dat` insmod ${PWD}/mod/d_usbhost.ko insmod ${PWD}/mod/d_sound.ko `cat/home/root/lms2012/sys/settings/HwId` insmod ${PWD}/mod/d_bt.ko `cat /home/root/lms2012/sys/settings/HwId`
chmod 666 /dev/lms_pwm chmod 666 /dev/lms_motor chmod 666 /dev/lms_analog chmod 666 /dev/lms_dcm chmod 666 /dev/lms_ui chmod 666 /dev/lms_uart chmod 666 /dev/lms_power chmod 666 /dev/lms_usbdev chmod 666 /dev/lms_usbhost chmod 666 /dev/lms_sound chmod 666 /dev/lms_iic chmod 666 /dev/lms_bt
本文用到的几个设备文件 文件 | 作用 | /dev/lms_pwm | motor控制文件 | /dev/lms_motor | motor传感器状态文件 | /dev/lms_uart | 距离传感器 | /dev/lms_analog | 触摸 光线 色彩 |
|
|
其他的设备文件以后再研究
motor控制 motor的命令字位于EV3源码的c_output.c的注释中
#include<stdint.h> #include<unistd.h> #include<fcntl.h>
#defineMOTOR_NUMS 4 #defineMOTOR_BRAKE 1
#define MAX_100 101
#define MOTOR_A 0x01 #define MOTOR_B 0x02 #define MOTOR_C 0x04 #define MOTOR_D 0x08 #defineMOTOR_ALL 0x0F
//motor的命令字
typedef enum { MOTOR_ERROR = 0x00, MOTOR_NOP = 0x01, MOTOR_PROGRAM_STOP = 0x02, MOTOR_PROGRAM_START = 0x03, MOTOR_GET_TYPE = 0xA0, // 00000 MOTOR_SET_TYPE = 0xA1, // 00001 MOTOR_RESET = 0xA2, // 00010 MOTOR_STOP = 0xA3, // 00011 MOTOR_POWER = 0xA4, // 00100 MOTOR_SPEED = 0xA5, // 00101 MOTOR_START = 0xA6, // 00110 MOTOR_POLARITY = 0xA7, // 00111 MOTOR_READ = 0xA8, // 01000 MOTOR_TEST = 0xA9, // 01001 MOTOR_READY = 0xAA, // 01010 MOTOR_POSITION = 0xAB, // 01011 MOTOR_STEP_POWER = 0xAC, // 01100 MOTOR_TIME_POWER = 0xAD, // 01101 MOTOR_STEP_SPEED = 0xAE, // 01110 MOTOR_TIME_SPEED = 0xAF, // 01111
MOTOR_STEP_SYNC = 0xB0, // 10000 MOTOR_TIME_SYNC = 0xB1, // 10001 MOTOR_CLR_COUNT = 0xB2, // 10010 MOTOR_GET_COUNT = 0xB3, // 10011
MOTOR_PRG_STOP = 0xB4, // 10100 }EMotorCmd;
//步进+power的控制结构 typedef structSMotorStepPower { uint8_t cmd; uint8_t nos; int8_t power; uint32_t ramp_up_step; uint32_t constant_step; uint32_t ramp_down_step; uint8_t brake; }SMotorStepPower;
int main() { int fd; char buf[10]; SMotorStepPower step;
//打开motor控制设备文件 fd = open("/dev/lms_pwm",O_RDWR); if(fd == -1) return -1;
//重置所有motor buf[0] = MOTOR_RESET; buf[1] = MOTOR_ALL; write(fd,buf,2);
step.cmd = MOTOR_STEP_POWER; step.nos = MOTOR_A; step.power = 100; step.ramp_up_step = 360; step.constant_step= 1000; step.ramp_down_step = 360; step.brake = 1; write(fd,&step,sizeof(step)); sleep(10); close(fd); return 0; }
arm-none-linux-gnueabi-gcc-o m m.c
scp到ev3后直接执行
|