07-CMD_set命令详解

本文详细介绍了在命令行环境中使用set命令设置、显示、删除环境变量的方法,包括使用set命令进行简单计算、字符串处理及操作变量的技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

set命令详解


一, 用set 命令设置自定义变量

作用:
    显示、设置或删除 cmd.exe  环境变量。
格式:
    SET [variable]=[string] 
        variable    指定环境变量名。 
        string      指定要指派给变量的一系列字符串。    
说明:
    1) set          : 显示所有环境变量
    2) set var=     : 清楚var的值
    3) %var%        : 引用变量的值
举例:
    d:\cmd\04>set myVar=123
    d:\cmd\04>echo %myVar%
    123 


格式:
    SET /P variable=[promptString] 
        variable, 变量名
        promptString, 提示信息
说明:
    提供一个交互界面,让用户自己输入变量的值,
举例:
    d:\cmd\04>set /p var=input value: & @echo %var%
    input value: 123
    123


二, 用set 命令进行简单计算

格式:
    SET /A expression 
说明:
    /A 命令行开关指定等号右边的字符串为被评估的数字表达式。
    该表达式评估器很简单,并以递减的优先权顺序支持下列操作: 
        ()                   分组 
        ! ~ -                一元运算符 
        * / %                算数运算符 
        + -                  算数运算符 
        << >>                二进制逻辑移位 
        &                    二进制按位“与” 
        ^                    二进制按位“异” 
        |                    二进制按位“或” 
        = *= /= %= += -=     算数赋值 
        &= ^= |= <<= >>=     二进制运算赋值 
        ,                    表达式分隔符
    十进制数字 : 不带前缀, 如 98
    八进制数字 : 前缀 0 (零), 如 0123
    十六进制数字:前缀 0x , 0xFF
举例:
  1, 
    d:\cmd\04>set num=123
    d:\cmd\04>echo %num%
    123
    d:\cmd\04>set /a num=4%num%
    4123
    d:\cmd\04>set /a num=%num%-23
    4100
  2, 计算器功能
   2.bat =>
    @echo off
    set /p expression=输入计算表达式:
    set /a var=%expression%
    echo %expression%=%var%
    pause
   MS-DOS =>
    d:\cmd\04>2.bat
    输入计算表达式:1+2+3/2
    1+2+3/2=4    
        表达式: 
  3, 逗号
    d:\cmd\04>set /a a=1+1,b=2+2
    4
    d:\cmd\04>echo %a%, %b%
    2, 4
  4, 直接在变量上运算
    d:\cmd\04>set a=1
    d:\cmd\04>set /a a+=10
    11
  5, 逻辑运算(需要将运算符用双引号包裹,或使用转义符^)
    set /a var= 1 "&" 1     这样结果就显示出来了,其他逻辑或取余操作符用法 
    set /a var= 1 "+" 1     异运算 
    set /a var= 1 "%" 1     取模运算 
    set /a var= 3 "<<" 2    左移位运算, 3 的二进制为 11,左移 2 位为 1100,换成十进制就是 12,自行验证 
    set /a var= 4 ">>" 2    右移位运算,4 的二进制为 100 ,右移动 2 位为 1,结果为 1
  6, 2的N次方
    3.bat => 变量无需用 "%%" 包裹
    @echo off
    set /p n=请输入2的幂:
    set /a num=1 "<<" n
    echo %num%
    pause


三, 用set 命令进行字符串处理

1、字符串替换  
    格式:
        %variable:targetStr=replacementStr%
          variable      : 变量名
          targetStr     : 需要替换的字符串
          replacementStr: 替换后的内容
    举例:
        d:\cmd\04>set a=www.  baidu.com
        d:\cmd\04>echo %a%
        www.  baidu.com
        -----------------------------------------
        d:\cmd\04>set var=%a: =%        // 去掉空格
        d:\cmd\04>echo %var%
        www.baidu.com
        d:\cmd\04>set var=%a:.=#%       // 将"."换成"#"
        d:\cmd\04>echo %var%
        www#  baidu#com   
        ------------------------------------------
        d:\cmd\04>echo %a: =%
        www.baidu.com
        d:\cmd\04>echo %a:.=#%
        www#  baidu#com
2, 字符串截取
格式:
    %variable:~[ start [, length] ]%
        start   : 从第几个字符开始, 缺省为0
                    正数(+p), 总左边数p个
                    负数(-p), 从右边数p个
        length  : 截取多少个, 缺省则取到末尾
                    正数(+n), n个
                    负数(-n), 总数-n  个
举例:
    d:\cmd\04>echo %b%
    0123456789
    d:\cmd\04>echo %b:~1,4%
    1234
    d:\cmd\04>echo %b:~-3%
    789
    d:\cmd\04>echo %b:~0,-3%
    0123456    
总结:
    a=bbs.wuyou.com%a:~1,2%   =“bs”    
        偏移量 1,从第二位开始向右取 2 位 
    %a:~-3%    =“com ”   
        偏移量负 3,即倒数 3 位(也可理解为留下右边 3 位),右取全部 
    %a:~3%     =“.wuyou.com ”  
        偏移量 3(也可理解为去掉左边 3 位),右取全部 
    %a:~0,-3%    =“bbs.wuyou.”  
        偏移量 0,右取长度至负 3,即倒数 3 位 
    %a:~2,-3%    =“s.wuyou.”   
        偏移量2,右取长度至负 3,即倒数 3 位


思考: 输入任意字符串, 求其长度
    @echo off
    set /p targetStr=请输入任意长度的字符串:
    echo 您输入的字符串为: "%targetStr%"


    :: 参数1, 传入的字符串, 如有空格, 请用双引号 括起来
    :: 参数2, 返回变量的名称
    call :getStringLen "%targetStr%" len


    echo "%targetStr%" 的长度为: %len%


    :: 参数1, 传入的字符串, 如有空格, 请用双引号 括起来
    :: 参数2, 返回变量的名称
    :getStringLen


        set theString=%~1
        set count=0


        :continue
            set /a count+=1 
            set theString=%theString:~0,-1%
            rem 如果theString未定义或者值为空
            if defined theString goto continue


        if not "%2"=="" set %2=%count%
    goto :eof

<think>嗯,用户问的是如何使用这个函数static void gimbal_motor_raw_angle_control(Gimbal_Motor_t *gimbal_motor)。首先,我需要先理解这个函数的功能。看代码的话,这个函数接收一个Gimbal_Motor_t结构体指针,然后检查是否为NULL。如果不是,就将current_set设为raw_cmd_current,然后把current_set转换为int16_t类型的given_current。 用户之前问过关于push电机持续转动的问题,现在这个函数可能和云台电机的原始角度控制有关。可能用户现在在开发云台控制,需要了解如何正确使用这个函数。首先,我应该解释这个函数的作用,可能是一个开环控制,直接设置电流值,而不是闭环PID控制。 接下来,用户可能需要知道如何在实际项目中调用这个函数,以及需要准备哪些结构体成员。例如,结构体Gimbal_Motor_t需要包含raw_cmd_current、current_set和given_current这些成员变量。然后,使用步骤可能包括初始化结构体、设置原始命令电流、调用函数、最后发送电流值到电机驱动器。 还要考虑用户可能的误区,比如没有正确初始化结构体,或者没有处理NULL指针的情况,但这里函数已经有NULL检查了。另外,用户可能不清楚这个函数和之前PID控制的区别,是否需要闭环控制,这时候需要说明这个函数是开环的,适用于调试或者特定场景,而持续转动可能需要闭环控制。 另外,用户可能想知道如何结合这个函数到整个系统中,比如在定时中断中调用,或者如何与之前的PID函数配合使用。需要给出示例代码,说明如何设置raw_cmd_current并调用函数,然后发送电流到电机。 还要注意安全机制,比如电流限幅,防止电机过载。在示例代码中加入限幅检查,确保电流值在合理范围内。同时,提醒用户这个方法的优缺点,比如开环控制可能不够精确,需要根据应用场景选择合适的方法。 最后,用户可能需要验证函数是否正确工作,比如通过监测电流值或者电机实际运动情况。需要给出验证步骤,比如使用调试工具打印given_current的值,或者观察电机响应。</think>好的,我将从代码功能解析、使用方法和应用场景三个层面详细说明这个云台电机原始角度控制函数的使用方法。 --- ### **一、函数功能解析** ```c static void gimbal_motor_raw_angle_control(Gimbal_Motor_t *gimbal_motor) { if (gimbal_motor == NULL) { return; } gimbal_motor->current_set = gimbal_motor->raw_cmd_current; // 设置目标电流 gimbal_motor->given_current = (int16_t)(gimbal_motor->current_set); // 类型转换 } ``` #### 1. **核心功能** - **开环电流控制**:直接将`raw_cmd_current`的值转换为电机电流输出 - **无闭环反馈**:不依赖编码器角度或速度反馈 - **硬件接口适配**:将浮点电流值转换为驱动器接受的`int16_t`整型 #### 2. **关键结构体成员** ```c typedef struct { float raw_cmd_current; // 原始电流指令(单位:mA) float current_set; // 电流设定值(中间变量) int16_t given_current; // 最终输出电流(驱动器输入) // 其他成员(编码器数据、PID参数等可能存在于完整实现中) } Gimbal_Motor_t; ``` --- ### **二、使用步骤详解** #### 1. **初始化配置** ```c // 创建电机控制对象 Gimbal_Motor_t yaw_motor = { .raw_cmd_current = 0.0f, // 初始电流设为0 .current_set = 0.0f, .given_current = 0 }; // 硬件初始化(需实现) HAL_CAN_Init(); // 初始化CAN总线 Encoder_Init(); // 编码器初始化(可选) ``` #### 2. **电流指令设置** ```c // 在控制逻辑中直接写入目标电流 void User_Control_Logic() { // 示例:设置2000mA电流 yaw_motor.raw_cmd_current = 2000.0f; // 单位需与驱动器协议一致 // 调用控制函数 gimbal_motor_raw_angle_control(&yaw_motor); // 发送电流到驱动器(需实现) CAN_Send_Current(yaw_motor.given_current); } ``` #### 3. **安全保护实现** ```c // 在调用函数前加入限幅检查 #define MAX_CURRENT 30000 // 根据驱动器规格设置 void Safe_Control_Wrapper(Gimbal_Motor_t *motor) { // 电流绝对值限幅 if (motor->raw_cmd_current > MAX_CURRENT) { motor->raw_cmd_current = MAX_CURRENT; } else if (motor->raw_cmd_current < -MAX_CURRENT) { motor->raw_cmd_current = -MAX_CURRENT; } gimbal_motor_raw_angle_control(motor); } ``` --- ### **三、典型应用场景** #### 1. **调试阶段开环测试** ```c // 示例:手动控制电流斜坡上升 void Test_Ramp_Current() { for(int i=0; i<100; i++) { yaw_motor.raw_cmd_current = 100.0f * i; gimbal_motor_raw_angle_control(&yaw_motor); CAN_Send_Current(yaw_motor.given_current); HAL_Delay(10); // 10ms间隔 } } ``` #### 2. **紧急停止功能** ```c // 立即切断电流输出 void Emergency_Stop() { yaw_motor.raw_cmd_current = 0; gimbal_motor_raw_angle_control(&yaw_motor); CAN_Send_Current(yaw_motor.given_current); } ``` #### 3. **底层驱动层对接** ```c // CAN总线发送函数示例 void CAN_Send_Current(int16_t current) { CAN_TxHeaderTypeDef tx_header; uint8_t tx_data[8]; tx_header.StdId = 0x200; // CAN ID需匹配电机型号 tx_header.IDE = CAN_ID_STD; tx_header.RTR = CAN_RTR_DATA; tx_header.DLC = 8; // 按大端格式填充电流值 tx_data[0] = (current >> 8) & 0xFF; tx_data[1] = current & 0xFF; // 其他数据字节通常补0 memset(&tx_data[2], 0, 6); HAL_CAN_AddTxMessage(&hcan1, &tx_header, tx_data, (uint32_t*)CAN_TX_MAILBOX); } ``` --- ### **四、参数配置建议** #### 1. **电流单位换算表** | 驱动器型号 | 1LSB对应电流 | 计算公式 | |--------------|-------------|--------------------------| | C620/C610 | 1mA | `given_current = 目标mA` | | M3508/M2006 | 20mA/LSB | `given_current = 目标mA / 20` | #### 2. **典型电机参数参考** ```c // GM6020电机(需注意不同型号的差异) #define GM6020_MAX_CURRENT 30000 // 峰值电流30A #define GM6020_CONT_CURRENT 10000 // 持续电流10A ``` --- ### **五、调试验证方法** #### 1. **硬件监测** - 使用万用表测量电机相线电流 - 观察电机响应是否符合预期转速 #### 2. **软件监测** ```c // 添加调试打印 printf("CMD:%.1f mA -> OUT:%d\r\n", yaw_motor.raw_cmd_current, yaw_motor.given_current); ``` #### 3. **动态响应测试** ```c // 阶跃响应测试(记录电流变化过程) void Step_Response_Test() { yaw_motor.raw_cmd_current = 0; Safe_Control_Wrapper(&yaw_motor); HAL_Delay(1000); yaw_motor.raw_cmd_current = 5000; // 阶跃到5A Safe_Control_Wrapper(&yaw_motor); HAL_Delay(2000); } ``` --- ### **六、与闭环控制的对比** | 特性 | 本函数(开环) | 闭环PID控制 | |--------------------|----------------------------|---------------------------| | 控制精度 | 低(依赖负载特性) | 高(有反馈校正) | | 响应速度 | 快(无计算延迟) | 受PID计算周期影响 | | 抗干扰能力 | 弱 | 强 | | 适用场景 | 调试、紧急操作、简单运动 | 精确位置/速度控制 | | 参数敏感性 | 仅需电流限幅 | 需整定KP/KI/KD | --- ### **七、进阶使用建议** 1. **与闭环控制结合**:可在上层做模式切换 ```c enum ControlMode {OPEN_LOOP, CLOSED_LOOP}; void Motor_Main_Control(Gimbal_Motor_t *motor, enum ControlMode mode) { if(mode == OPEN_LOOP) { gimbal_motor_raw_angle_control(motor); } else { pid_angle_control(motor); // 假设存在闭环控制函数 } } ``` 2. **动态电流补偿**:根据温度调整最大
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值