在用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);