调试ST电机库5.20遇到的问题

ST电机库v5.4.4源代码分析(3): α、β方向的电流值与三相PWM 波形的联系 st电机库源代码 v5.4.4 电流和占空比 阅读详情
AI摘要

本文深入探讨无刷电机控制中的常见问题,包括霍尔传感器干扰、编码器接线错误、观测器参数调整及电流环KPKI计算。分析霍尔状态异常导致电机停转的原因,对比霍尔与编码器反馈的优劣,解决启动电流持续上升和低速运行不稳的问题。

1.使用带霍尔的无刷电机运行ST MotorControl Workbench 5.2.0生成的例程。霍尔状态经常出现0或者7,是因为霍尔信号干扰太大了吗?正常的霍尔状态为1-6,一出现0或7电机就不能转了。Iq的目标值变成6067(为标称最大电流值,这个值是用标称电流3.8A转换的)。Iq的目标值是由于速度PI控制器输出的。当霍尔状态为0或7,程序将pHandle->SensorIsReliable = false; 认为此时速度传感器不可靠,将测到的速度值设成0了。由于0和设定的目标速度相差很大,同时电机不能转速度一直是0,速度PI控制器输出的Iq的目标值立马就超过了标称值6067.

下图为用STMStudio读到的霍尔状态

用示波器测到到霍尔波形

阅读ST电机库中hall_speed_pos_fdbk.c源码中的void * HALL_TIMx_CC_IRQHandler( void * pHandleVoid )函数。

void * HALL_TIMx_CC_IRQHandler( void * pHandleVoid )
{
  HALL_Handle_t * pHandle = ( HALL_Handle_t * ) pHandleVoid;
  TIM_TypeDef * TIMx = pHandle->TIMx;
  uint8_t bPrevHallState;
  uint32_t wCaptBuf;
  uint16_t hPrscBuf;
  uint16_t hHighSpeedCapture;

  if ( pHandle->SensorIsReliable )
  {
    /* A capture event generated this interrupt */
    bPrevHallState = pHandle->HallState;

    if ( pHandle->SensorPlacement == DEGREES_120 )
    {
      pHandle->HallState  = LL_GPIO_IsInputPinSet( pHandle->H3Port, pHandle->H3Pin ) << 2
                            | LL_GPIO_IsInputPinSet( pHandle->H2Port, pHandle->H2Pin ) << 1
                            | LL_GPIO_IsInputPinSet( pHandle->H1Port, pHandle->H1Pin );
    }
    else
    {
      pHandle->HallState  = ( LL_GPIO_IsInputPinSet( pHandle->H2Port, pHandle->H2Pin ) ^ 1 ) << 2
                            | LL_GPIO_IsInputPinSet( pHandle->H3Port, pHandle->H3Pin ) << 1
                            | LL_GPIO_IsInputPinSet( pHandle->H1Port, pHandle->H1Pin );
    }

    switch ( pHandle->HallState )
    {
      case STATE_5:
        if ( bPrevHallState == STATE_4 )
        {
          pHandle->Direction = POSITIVE;
          pHandle->MeasuredElAngle = pHandle->PhaseShift;
        }
        else if ( bPrevHallState == STATE_1 )
        {
          pHandle->Direction = NEGATIVE;
          pHandle->MeasuredElAngle = ( int16_t )( pHandle->PhaseShift + S16_60_PHASE_SHIFT );
        }
        else
        {
        }
        break;

      case STATE_1:
        if ( bPrevHallState == STATE_5 )
        {
          pHandle->Direction = POSITIVE;
          pHandle->MeasuredElAngle = pHandle->PhaseShift + S16_60_PHASE_SHIFT;
        }
        else if ( bPrevHallState == STATE_3 )
        {
          pHandle->Direction = NEGATIVE;
          pHandle->MeasuredElAngle = ( int16_t )( pHandle->PhaseShift + S16_120_PHASE_SHIFT );
        }
        else
        {
        }
        break;

      case STATE_3:
        if ( bPrevHallState == STATE_1 )
        {
          pHandle->Direction = POSITIVE;
          pHandle->MeasuredElAngle = ( int16_t )( pHandle->PhaseShift + S16_120_PHASE_SHIFT );
        }
        else if ( bPrevHallState == STATE_2 )
        {
          pHandle->Direction = NEGATIVE;
          pHandle->MeasuredElAngle = ( int16_t )( pHandle->PhaseShift + S16_120_PHASE_SHIFT +
                                                  S16_60_PHASE_SHIFT );
        }
        else
        {
        }

        break;

      case STATE_2:
        if ( bPrevHallState == STATE_3 )
        {
          pHandle->Direction = POSITIVE;
          pHandle->MeasuredElAngle = ( int16_t )( pHandle->PhaseShift + S16_120_PHASE_SHIFT
                                                  + S16_60_PHASE_SHIFT );
        }
        else if ( bPrevHallState == STATE_6 )
        {
          pHandle->Direction = NEGATIVE;
          pHandle->MeasuredElAngle = ( int16_t )( pHandle->PhaseShift - S16_120_PHASE_SHIFT );
        }
        else
        {
        }
        break;

      case STATE_6:
        if ( bPrevHallState == STATE_2 )
        {
          pHandle->Direction = POSITIVE;
          pHandle->MeasuredElAngle = ( int16_t )( pHandle->PhaseShift - S16_120_PHASE_SHIFT );
        }
        else if ( bPrevHallState == STATE_4 )
        {
          pHandle->Direction = NEGATIVE;
          pHandle->MeasuredElAngle = ( int16_t )( pHandle->PhaseShift - S16_60_PHASE_SHIFT );
        }
        else
        {
        }
        break;

      case STATE_4:
        if ( bPrevHallState == STATE_6 )
        {
          pHandle->Direction = POSITIVE;
          pHandle->MeasuredElAngle = ( int16_t )( pHandle->PhaseShift - S16_60_PHASE_SHIFT );
        }
        else if ( bPrevHallState == STATE_5 )
        {
          pHandle->Direction = NEGATIVE;
          pHandle->MeasuredElAngle = ( int16_t )( pHandle->PhaseShift );
        }
        else
        {
        }
        break;

      default:
        /* Bad hall sensor configutarion so update the speed reliability */
        //pHandle->SensorIsReliable = false;

        break;
    }


#ifdef HALL_MTPA
    {
      pHandle->_Super.hElAngle = pHandle->MeasuredElAngle;
    }
#endif

    /* Discard first capture */
    if ( pHandle->FirstCapt == 0u )
    {
      pHandle->FirstCapt++;
      LL_TIM_IC_GetCaptureCH1( TIMx );
    }
    else
    {
      /* used to validate the average speed measurement */
      if ( pHandle->BufferFilled < pHandle->SpeedBufferSize )
      {
        pHandle->BufferFilled++;
      }

      /* Store the latest speed acquisition */
      hHighSpeedCapture = LL_TIM_IC_GetCaptureCH1( TIMx );
      wCaptBuf = ( uint32_t )hHighSpeedCapture;
      hPrscBuf =  LL_TIM_GetPrescaler ( TIMx );

      /* Add the numbers of overflow to the counter */
      wCaptBuf += ( uint32_t )pHandle->OVFCounter * 0x10000uL;

      if ( pHandle->OVFCounter != 0u )
      {
        /* Adjust the capture using prescaler */
        uint16_t hAux;
        hAux = hPrscBuf + 1u;
        wCaptBuf *= hAux;

        if ( pHandle->RatioInc )
        {
          pHandle->RatioInc = false;  /* Previous capture caused overflow */
          /* Don't change prescaler (delay due to preload/update mechanism) */
        }
        else
        {
          if ( LL_TIM_GetPrescaler ( TIMx ) < pHandle->HALLMaxRatio ) /* Avoid OVF w/ very low freq */
          {
            LL_TIM_SetPrescaler ( TIMx, LL_TIM_GetPrescaler ( TIMx ) + 1 ); /* To avoid OVF during speed decrease */
            pHandle->RatioInc = true;   /* new prsc value updated at next capture only */
          }
        }
      }
      else
      {
        /* If prsc preload reduced in last capture, store current register + 1 */
        if ( pHandle->RatioDec ) /* and don't decrease it again */
        {
          /* Adjust the capture using prescaler */
          uint16_t hAux;
          hAux = hPrscBuf + 2u;
          wCaptBuf *= hAux;

          pHandle->RatioDec = false;
        }
        else  /* If prescaler was not modified on previous capture */
        {
          /* Adjust the capture using prescaler */
          uint16_t hAux = hPrscBuf + 1u;
          wCaptBuf *= hAux;

          if ( hHighSpeedCapture < LOW_RES_THRESHOLD ) /* If capture range correct */
          {
            if ( LL_TIM_GetPrescaler ( TIMx ) > 0u ) /* or prescaler cannot be further reduced */
            {
              LL_TIM_SetPrescaler ( TIMx, LL_TIM_GetPrescaler ( TIMx ) - 1 ); /* Increase accuracy by decreasing prsc */
              /* Avoid decrementing again in next capt.(register preload delay) */
              pHandle->RatioDec = true;
            }
          }
        }
      }

#if 0
      /* Store into the buffer */
      /* Null Speed is detected, erase the buffer */
      if ( wCaptBuf > pHandle->MaxPeriod )
      {
        uint8_t bIndex;
        for ( bIndex = 0u; bIndex < pHandle->SpeedBufferSize; bIndex++ )
        {
          pHandle->SensorSpeed[bIndex]  = 0;
        }
        pHandle->BufferFilled = 0 ;
        pHandle->SpeedFIFOSetIdx = 1;
        pHandle->SpeedFIFOGetIdx = 0;
        /* Indicate new speed acquisitions */
        pHandle->NewSpeedAcquisition = 1;
        pHandle->ElSpeedSum = 0;
      }
      /* Filtering to fast speed... could be a glitch  ? */
      /* the HALL_MAX_PSEUDO_SPEED is temporary in the buffer, and never included in average computation*/
      else
#endif
        if ( wCaptBuf < pHandle->MinPeriod )
        {
          pHandle->CurrentSpeed = HALL_MAX_PSEUDO_SPEED;
          pHandle->NewSpeedAcquisition = 0;
        }
        else
        {
          pHandle->ElSpeedSum -= pHandle->SensorSpeed[pHandle->SpeedFIFOIdx]; /* value we gonna removed from the accumulator */
          if ( wCaptBuf >= pHandle->MaxPeriod )
          {
            pHandle->SensorSpeed[pHandle->SpeedFIFOIdx]  = 0;
          }
          else
          {
            pHandle->SensorSpeed[pHandle->SpeedFIFOIdx] = ( int16_t ) ( pHandle->PseudoFreqConv / wCaptBuf );
            pHandle->SensorSpeed[pHandle->SpeedFIFOIdx] *= pHandle->Direction;
            pHandle->ElSpeedSum += pHandle->SensorSpeed[pHandle->SpeedFIFOIdx];
          }
          /* Update pointers to speed buffer */
          pHandle->CurrentSpeed = pHandle->SensorSpeed[pHandle->SpeedFIFOIdx];
          pHandle->SpeedFIFOIdx++;
          if ( pHandle->SpeedFIFOIdx == pHandle->SpeedBufferSize )
          {
            pHandle->SpeedFIFOIdx = 0u;
          }
          /* Indicate new speed acquisitions */
          pHandle->NewSpeedAcquisition = 1;
        }
      /* Reset the number of overflow occurred */
      pHandle->OVFCounter = 0u;
    }
  }
  return MC_NULL;
}

 其中pHandle->HallState是通过读取三个霍尔传感器的引脚电平得到的。当出现0或7时,程序设置传感器不可靠pHandle->SensorIsReliable = false;,并将速度设成0,不再进行速度读取。当我把这行注释掉,电机可以运行,不会再停下来。但是会出现异音的情况。我猜是因为霍尔的位置检测有错误时,电角度的位置和方向信息都不会更新,而这些信息在后面的FOC控制中会用到,所以导致转子转动不连贯,出现了震动。

2.B-Emf constant这三个参数只有在使用观测器时才会用到。RS、LS在计算电流环KP KI时用到了。

上图中的wc为带宽系数

在使用霍尔控制,没有用观测器时,ST电机库生成的代码只有parameters_conversion.h中的下面这段代码使用了这三个参数。

/************************* OBSERVER + PLL PARAMETERS **************************/
#define MAX_BEMF_VOLTAGE  (uint16_t)((MAX_APPLICATION_SPEED * 1.2 *\
                           MOTOR_VOLTAGE_CONSTANT*SQRT_2)/(1000u*SQRT_3))

/*max phase voltage, 0-peak Volts*/
#define MAX_VOLTAGE (int16_t)((MCU_SUPPLY_VOLTAGE/2)/BUS_ADC_CONV_RATIO) 

#define MAX_CURRENT (MCU_SUPPLY_VOLTAGE/(2*RSHUNT*AMPLIFICATION_GAIN))

#define C1 (int32_t)((((int16_t)F1)*RS)/(LS*TF_REGULATION_RATE))
#define C2 (int32_t) GAIN1
#define C3 (int32_t)((((int16_t)F1)*MAX_BEMF_VOLTAGE)/(LS*MAX_CURRENT*TF_REGULATION_RATE))
#define C4 (int32_t) GAIN2
#define C5 (int32_t)((((int16_t)F1)*MAX_VOLTAGE)/(LS*MAX_CURRENT*TF_REGULATION_RATE))

#define PERCENTAGE_FACTOR    (uint16_t)(VARIANCE_THRESHOLD*128u)      
#define OBS_MINIMUM_SPEED        (uint16_t) (OBS_MINIMUM_SPEED_RPM/6u)
#define HFI_MINIMUM_SPEED        (uint16_t) (HFI_MINIMUM_SPEED_RPM/6u)

/*********************** OBSERVER + CORDIC PARAMETERS *************************/
#define CORD_C1 (int32_t)((((int16_t)CORD_F1)*RS)/(LS*TF_REGULATION_RATE))
#define CORD_C2 (int32_t) CORD_GAIN1
#define CORD_C3 (int32_t)((((int16_t)CORD_F1)*MAX_BEMF_VOLTAGE)/(LS*MAX_CURRENT\
                                                           *TF_REGULATION_RATE))
#define CORD_C4 (int32_t) CORD_GAIN2
#define CORD_C5 (int32_t)((((int16_t)CORD_F1)*MAX_VOLTAGE)/(LS*MAX_CURRENT*\
                                                          TF_REGULATION_RATE))
#define CORD_PERCENTAGE_FACTOR    (uint16_t)(CORD_VARIANCE_THRESHOLD*128u)      
#define CORD_MINIMUM_SPEED        (uint16_t) (CORD_MINIMUM_SPEED_RPM/6u)

3.仅使用编码器作为位置反馈时,效果比仅使用霍尔的时候要好。测得的速度也要稳定。如果启动电机,电机不转并且电流一直上升,可能是因为编码器AB相的接线反了。另外启动电机前需要进行Encoder Align 操作。

4.仅使用编码器作为位置反馈时,我发现测得的速度变化时都是以6的倍数来变化的。并且当速度过小,电机可能转不起来。另外当电机速度很小,力矩会比较小。力矩增大需要速度PI控制器的误差积分慢慢增加来提高输出力矩。

5.我发现st电机库中采样a,b相电流后没有进行数字滤波就直接使用了。用DAC的debug功能在示波器上看到相电流的正弦波形上会有杂波。另外,当设定好Iq和Id参考值后,Iq和Id对应的PI控制器输出相应的Vq和Vd,经过反Park变换后送到SVPWM模块生成相应的PWM波形控制6个MOS管。

这个过程中测量得到的Iq和Id一直在参考线上波动。如下图:

6.只使用编码盘作为速度反馈时,电机在低速时不能正常运行,有时会反转成最大速度。另外电机在100rpm这个转速运行时,会突然变速,有时会导致under voltage报警。

关注公众号《首飞》回复“机器人”获取精心推荐的C/C++,Python,Docker,Qt,ROS1/2,机器人学等机器人行业常用技术资料。

ST电机库v5.4.4源代码分析(2): 磁链圆限制之计算以及一个小bug st电机库源代码分析 阅读详情

相关推荐

ST电机库v5.4.4源代码分析(4): 电角度和力矩方向分析(Hall传感器)

st电机库 v5.5.4 Hall电角度

danger的博客 9918

ST最新电机库文件V6.2.1

ST官方最新版本的电机库文件,版本6.2.1。

ST电机库5.0完全开源对电机控制软件工程师有何影响?

ST电机库5.0完全开源对电机控制软件工程师有何影响?安装了ST的MC_SDK后,生成工程比较麻烦,跟安装的版本,插件都有关系,这样子就很难读到开源的代码。机缘巧合之下,发现可以直接在安装路径下看到源码,路径是:D:\Program Files (x86)\STMicroelectronics\MC_SDK_5.3.2\Middlewares\ST\MotorControl\MCSDK\MCLib\Any\Src一般我是把这类软件装在D盘。原厂的源码还是值得初学者学习的,祝大家好运,早日年薪百万!另外安装5

专注单片机实战教学,分享单片机学习资料 1837

STM32 电机教程 17 - 基于ST MotorControl Workbench的电机调试

前言 磁场定向控制又称矢量控制(FOC), 本质上为控制定子电流的幅度和相位,使之产生的磁场和转子的磁场正交,以产生最大的扭矩. PMSM的磁场定向控制框图如下图所示: 上一讲详细介绍了磁场定向控制的原理,有兴趣的同学可以自己写代码去实现它,ST官方对电机的控制有一套完整的库(最新版本已更新5.3了,开源),该电机库功能齐全,同时还配备了完整的图形界面开发工具,配合STCUBE...

张十三的博客 2万+

ST电机库FOC实战避坑:你的Clarke变换矩阵和ST官方一样吗?

本文深入解析ST电机库FOC实现中的Clarke变换陷阱,对比等幅值变换与等功率变换的差异,揭示ST官方代码中的负号问题及其调试技巧。通过理论分析、仿真验证和硬件调试指南,帮助工程师避免常见错误,优化电机控制性能。

weixin_28358083的博客 417

避开理论深坑:用ST电机库5.4.4快速实现你的第一个FOC电机控制项目

本文介绍如何利用ST电机库5.4.4快速实现FOC电机控制项目,绕过复杂的理论推导,直接进入实战环节。通过硬件准备、软件环境搭建、关键代码实战和调试技巧,帮助开发者快速掌握FOC控制技术,提升电机控制效率。

weixin_30888413的博客 1305

【ST电机库学习过程探索】

(4) 2上将speed sensor config–>Max Num. Errors before fault从2改成10.每次都能旋转,但开始时有几次旋转方向是反的,而且转速也不是设定的转速。(3)2上增加profier功能,则启动不正常,有时不能启动,有时长时间之后能转起来,但速度值一直维持在高位,有时一旋转即报"speed feedback".第一次启动时,会改变speed ref.后来都正常启动,但一吃负载,即报"speed feedback".pwm模式的不同,电流采样通道的不同。

ashang2002的博客 2877

手把手调试ST电机库:用逻辑分析仪抓取MediumFrequencyTask运行状态

本文详细介绍了如何使用逻辑分析仪调试ST电机库中的MediumFrequencyTask运行状态,包括硬件连接方案、软件标记注入、关键状态机时序分析以及RUC加速曲线解析。通过Saleae Logic Pro 8和PulseView工具,开发者可以实时捕获STM32的时序信号,有效解决电机控制中的抖动和异常问题,提升调试效率。

weixin_29158413的博客 342

STM32电机库(ST-MC-Workbench)学习记录——无感FOC代码生成

总结前面文章,将总体无感FOC代码生成归纳为以下步骤; 第一步:设定芯片 点击MCU选择, 进入如下界面,根据MCU型号选择。 第二步:设定电源电压模块参数 以母线电压为24V供电系统为例,最低电压设为12V,最高电压设为36V,额定电压设为24V,电压范围为±50% 第三步:设置母线电压采样参数 根据设计的电路原理图填入下列参数,一般为串联电阻分压结构。 第四步:电机参数设置 同样根据电机参数表,首先选择电机类型,分为表贴式电机和内置式电机。然后是极对数、额定转速、额

sy243772901的博客 2万+

ST电机库FOC算法源码精讲:从三相电流到SVPWM的闭环实现

本文深入解析ST电机库中FOC算法的实现细节,从三相电流到SVPWM的闭环控制全过程。通过源码分析和工程实践,详细讲解Clarke变换、Park变换及SVPWM等关键技术的实现技巧,帮助开发者高效掌握电机控制核心技术。

weixin_42554408的博客 461

告别ST上位机!用VOFA+和STM32电机库5.4.4调试单电阻采样的实战记录

本文详细介绍了如何利用VOFA+工具与STM32电机库5.4.4进行单电阻采样调试,显著提升调试效率。通过对比传统ST上位机工具,VOFA+在高采样率、实时观测和多视图显示方面的优势,帮助工程师精准捕获电流重建细节,优化关键参数,构建高效调试工作流。

weixin_33461476的博客 333

【亲测免费】 探索高效驱动世界:ST MC SDK5.x 电机库——您的智能驱动解决方案

探索高效驱动世界:ST MC SDK5.x 电机库——您的智能驱动解决方案 去发现同类优质开源项目:https://gitcode.com/ 在当今高速发展的工业自动化领域,一款强大的电机控制库能够显著提升设备性能与开发效率。今天,我们要向大家推荐的正是业界翘楚——ST MC SDK5.x 电机库软件框架。这是一份源于ST官方的珍贵文档,专为电机控制领域的开发者和技术人员量身定制。 项目介绍 ST...

gitblog_06649的博客 807

从零解析ST电机库FOC:核心算法与工程实现

本文深入解析ST电机库FOC(Field Oriented Control)的核心算法与工程实现,涵盖Clarke变换、Park变换、SVPWM等关键技术。通过源代码分析和实战技巧,帮助开发者掌握无刷电机控制的高效方法,提升工程应用能力。

weixin_30340819的博客 494

ST PMSM电机库深度解析:从代码架构到调试技巧

磁场定向控制(FOC)是永磁同步电机(PMSM)实现平稳高效驱动的核心技术,它将三相交流电流变换为旋转坐标系下的直流量,从而简化电机控制模型。在工程落地中,ST的电机控制SDK提供从参数自动识别到实时调试的完整工具链,让开发者能快速上手。其开源的核心代码不仅包含PI调节器、坐标变换和状态机等关键实现,还支持深度定制,满足风机、水泵、电动工具和机器人关节等多样化工况。针对调试中的常见痛点,如有感PMSM零位标定原理、stm32f10x.h编译错误等,实际排查需要结合实践经验。从代码架构、工程配置到参数整定,完

weixin_33912638的博客 456

告别ST上位机!用VOFA+调试STM32电机库单电阻采样,实时波形真香

本文介绍了使用VOFA+工具调试STM32电机库单电阻采样的高效可视化方案,替代传统ST上位机工具。通过硬件配置、软件栈设置和实时调试技巧,实现高达1MHz的采样率和实时波形观测,显著提升调试效率和精度。特别适合电机控制算法的优化和故障诊断。

weixin_31355483的博客 360

ST电机库无感启动避坑指南:高频注入vs开环启动的工程实践

本文深入探讨了ST电机库中无感启动的两种主流方案——高频注入法和开环启动的工程实践。针对永磁同步电机(PMSM)在工业风机、水泵等应用中的启动挑战,提供了详细的技术解析、参数配置建议和故障排除方法,帮助工程师优化启动性能并避免常见问题。

weixin_29306011的博客 461

python foc电机库_No.3 FOC SDK5.0电机库软件系统分析

本帖最后由 子曰好人 于 2018-9-1 22:42 编辑拿到套件快一周了,线上培训也去听了,任务也做完了,只是一直没有发帖,想通过我的这些帖子让大家更容入门ST的电机库。前两篇帖子做了一些对套件出厂固件和硬件配置做了一个大概的分析,希望对刚接触STFOC SDK的朋友有一定的帮助。今天来分析一下代码结构,带着各位逐步深入理解这份不错的电机库。如何生成一份可用的工程我就不做过多介绍了,可以参看论...

weixin_39641231的博客 1116

ST开源PMSM电机库源码解读:FOC控制与调试实战

永磁同步电机(PMSM)因高效率、高功率密度而被广泛应用于机器人、工业伺服等领域。其控制核心是磁场定向控制(FOC),通过坐标变换将三相电流解耦为励磁和转矩分量,实现类似直流电机的精准调速。FOC的实现涉及电流采样、SVPWM、PI调节等关键环节,工程实践中常因参数整定和调试环境而困扰。ST开源的PMSM电机控制库提供了完整的代码参考,覆盖从底层驱动到上层算法的全链路,帮助开发者深入理解状态机、电流环设计以及无感观测器原理。本文基于实际移植与调试经历,梳理了源码结构、有感零位标定、无感FOC启动、常见编译与

weixin_34175509的博客 510
上一篇: ROS中CMakeList.txt每条命令的含义
下一篇: 将ros功能包制作成deb格式发布
首飞爱玩机器人
博客等级 码龄14年 6990粉丝 120原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

首飞爱玩机器人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值