首页 > 编程语言 >Pixhawk控制电机命令pwm源码详解

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

时间:2022-12-06 11:34:28浏览次数:36  
标签:set mask ret Pixhawk 源码 value pwm PWM

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

标签:set,mask,ret,Pixhawk,源码,value,pwm,PWM
From: https://blog.51cto.com/u_15903730/5915585

相关文章

  • CountDownLatch闭锁源码解析(基于jdk11)
    目录CountDownLatch闭锁源码解析(基于jdk11)1.1CountDownLatch概述1.2CountDownLatch原理1.2.1基本结构(jdk11)1.2.2await()方法1.2.3await(timeout,unit)方法1.2.4......
  • python爬虫爬取网易云音乐(超详细教程,附源码)
    一、前言先说结论,目前无法下载无损音乐,也无法下载vip音乐。此代码模拟web网页js加密的过程,向api接口发送参数并获取数据,仅供参考学习,如果需要下载网易云音乐,不如直接在......
  • C++学习---cstdbool和cstddef源码学习分析
    引言cstdbool是C++对stdbool.h头文件的封装,里面定义了与bool变量相关的宏;cstddef是C++对stddef.h头文件的封装,里面定义一些特殊类型(如size_t),有用的宏函数(offsetof)。平时我们......
  • php版高校宿舍管理系统源码(文末有下载方式)
    大家好,我是程序猿零壹。分享一款高校宿舍管理系统,该系统使用php+mysql开发,实现了学生宿舍管理的功能模块,包含学生管理、楼宇管理、宿舍管理、宿舍分配,物品出入登记、来访......
  • Spring源码-03-容器创建
    Spring源码-03-容器创建注解Bean方式publicclassAnnotationCtxMain02{ publicstaticvoidmain(String[]args){ newAnnotationConfigApplicationContext(MyCf......
  • Spring源码-02-Bean容器
    Spring源码-02-Bean容器一类关系二宏观视角......
  • Spring源码-04-注解Bean读取器
    Spring源码-04-注解Bean读取器AnnotatedBeanDefinitionReader一构造方法publicAnnotatedBeanDefinitionReader(BeanDefinitionRegistryregistry,Environmentenviro......
  • DataX源码分析一:环境搭建
    最近工作中使用到了DataX工具,比较肤浅的看了看源码,做一个记录。比较肤浅的探讨,各位莫见笑。 【1】获取源码源码地址(github):[email protected]:alibaba/DataX.git源码地址(g......
  • @Import源码翻译
     类上方注释指示要导入的一个或多个组件类——通常是@Configuration类。提供等同于SpringXML中的<import/>元素的功能。允许导入@Configuration类、ImportSel......
  • @EnableAsync源码注释翻译
     类上方注释启用Spring的异步方法执行能力,类似于Spring的<task:*>XML命名空间中的功能。与@Configuration类一起使用,如下所示,为整个Spring应用程序上下文启用注解......