您的位置:首页 > 其它

Pixhawk控制电机命令pwm源码详解

2015-11-04 15:13 453 查看
在用USB转串口连接好飞控板之后,可以在终端使用命令pwm来进行设置pwm的输出值

例如:命令

nsh>pwm test –c 13 –p 1200

该命令用来测试通道1和3,并将他们的输出值设定为1200us。

pwm命令的源文件存储路径为:

originalcode/PX4Firmware/src/systemcmds/pwm/pwm.c

pwm命令的参数‘c’的源代码为:

case 'c':

/*Read in channels supplied as one int and convert to mask: 1234 -> 0xF */

channels= strtoul(optarg, &ep, 0);

while((single_ch = channels % 10)) {

set_mask|= 1<<(single_ch-1);

channels/= 10;

}

break;

设channels从命令行参数optarg得到的值为1234,则

single_ch =1234 % 10=4;

set_mask |= 1<<(single_ch-1)=1<<(4-1)=1<<3

{set_mask的初始值为0,所以,现在set_mask=0|1<<3=0|1000=1000}

channels/=10

{channels = 1234/10 = 123}

此段源代码一直运行,直到single_ch得到的值为0,此时set_mask的值为1111,

即四个通道的掩码值都被设置为1,参数‘c’用于选择打开哪几个通道

pwm命令的参数‘p’的源代码为:

case 'p':

pwm_value = strtoul(optarg, &ep, 0);

if(*ep != '\0')

usage("BADPWM VAL");

break;

pwm_value是pwm的数值,pwm_value的值从命令行参数optarg得到,并且命令行参数optarg在输入pwm的数值之后必须要有结束符,参数‘p’用于改变pwm的数值

pwm命令中“test”参变量的源代码详解:

else if (!strcmp(argv[1],"test")) {

//用来判断参变量是否是“test”命令

if(set_mask == 0) {

usage("nochannels set");

}

//如果set_mask值为0,说明没有设置选通通道

if(pwm_value == 0)

usage("noPWM provided");

//如果pwm_value值为0,说明pwm的数值没有设定

/*get current servo values */

structpwm_output_values last_spos;

//last_spos结构体用于存储当前电机的值

for(unsigned i = 0; i < servo_count; i++) {

ret= ioctl(fd, PWM_SERVO_GET(i), (unsigned long)&last_spos.values[i]);

//读取电机的当前数值

if(ret != OK)

err(1,"PWM_SERVO_GET(%d)", i);

}

/*perform PWM output */

/*Open console directly to grab CTRL-C signal */

structpollfd fds;

fds.fd= 0; /* stdin */

fds.events= POLLIN;

//设置控制台终端来接收CTRL-C信号,以终止程序

warnx("PressCTRL-C or 'c' to abort.");

while(1) {

for(unsigned i = 0; i < servo_count; i++) {

//依次选中电机

if(set_mask & 1<<i) {

//set_mask与1的左移i位后的值进行相与,使得只有相应的位为1,其他的位为0,例如,i=0,

//时,set_mask的值为1,i=1时,set_mask的值为2,i=2时,set_mask的值为4,i=3时,set_mask

//的值为8,根据set_mask值得不同就可以设置,相应的电机的状态

ret= ioctl(fd, PWM_SERVO_SET(i), pwm_value);

//设置相应电机的pwm的值

if(ret != OK)

err(1,"PWM_SERVO_SET(%d)", i);

}

}

/*abort on user request */

//以下代码用来在终端接收到指定的字符之后,重新恢复电机原来的转速

charc;

ret= poll(&fds, 1, 0);

if(ret > 0) {

read(0,&c, 1);

if(c == 0x03 || c == 0x63 || c == 'q') {

//如果接收到的字符是EXT、C、Q几个字符,则会退出用户设定模式

/*reset output to the last value */

for(unsigned i = 0; i < servo_count; i++) {

if(set_mask & 1<<i) {

ret= ioctl(fd, PWM_SERVO_SET(i), last_spos.values[i]);

//将所有电机的油门值设为电机原来的油门值

if(ret != OK)

err(1,"PWM_SERVO_SET(%d)", i);

}

}

warnx("Userabort\n");

//发出信息说明用户已经终止设置自定义油门参数

exit(0);

}

}

usleep(2000);

//睡眠2000毫秒

}

exit(0);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: