01 机械臂调试


1.简介

对于 基于STM32对于三轴机械臂控制器设计 的设计已经进行了如下的调试:

  1. 对于STM32F103三轴机械臂控制器进行基本功能测试-关节角度读取
  2. 对于STM32F103三轴机械臂控制器进行基本功能测试-上下运动功能
  3. 基于STM32对于三轴机械臂控制器设计 基本调试:串口命令调试。

下面对于该机械臂的两个关节转动进行调试:

1) 肘关节运动:参见: 增加行星轮减速后机械臂调试组装肩部带有减速器双轴机械臂组装与调试
2)肘关节运动:参见: 两轴机械臂+机械爪整体控制板设计与机械爪控制调试双关节机械臂+机械爪运动控制

02 关节转动初步调试


1.接口1

三个步进信号接口定义:

PSM1 PSM2 PSM3
肩关节 肘关节 上下运动

(1)电路图

▲ 三个步进电机信号输出控制端口

(2)步进电机设置

A. 肩关节步进电机: S1 ~ S6: ON,ON,OFF,ON,OFF,OFF
参考步进电机数据文件: 57HSXXXXEIS一体化步进伺服驱动电机

**B. 肘关节步进电机:**S1 ~ S5: OFF,OFF,OFF,OFF,ON
参考步进电机数据文件: 42HS48EIS步进闭环电机最大转速

(3)角度运行范围

根据 组装肩部带有减速器双轴机械臂组装与调试 给出的测试结果:

(1)肩部角度运行180°,给定脉冲个数:32000
(2)肘部角度运行180°,给定脉冲个数:25600

脉冲数量:正→顺时针旋转;负→逆时针旋转

2.设置中断服务程序2

(1)中断Timer4

通过中断程序:ArthrosisISR来对两个关节步进电机发送脉冲信号。中断程序是在10kHzTimer4的定时中断下工作的。输出脉冲的频率为:5kHz。

(2)中断频率细分

分别通过g_nArthrosisDividerSoulderCount, g_nArthrosisDividerElbowCount对于两个关节脉冲输出频率从5kHz进行细分。

//------------------------------------------------------------------------------
void ArthrosisISR(void) {//--------------------------------------------------------------------------g_nArthrosisDividerShoulderCount += g_nShoulderDividerInc;if(g_nArthrosisDividerShoulderCount >= ARTHROSIS_DIVIDER_SHOULDER_PERIOD) {g_nArthrosisDividerShoulderCount -= ARTHROSIS_DIVIDER_SHOULDER_PERIOD;g_nArthrosisShoulderCount ++;if(g_nShoulderAngle != 0) {if(g_nShoulderAngle > 0) {ON(SM_DIR1);if(g_nArthrosisShoulderCount & 0x1) {ON(SM_PUL1);} else {OFF(SM_PUL1);g_nShoulderAngle --;}            } else {OFF(SM_DIR1);if(g_nArthrosisShoulderCount & 0x1) {ON(SM_PUL1);} else {OFF(SM_PUL1);g_nShoulderAngle ++;}            }}}g_nArthrosisDividerElbowCount += g_nElbowDividerInc;if(g_nArthrosisDividerElbowCount >= ARTHROSIS_DIVIDER_ELBOW_PERIOD) {g_nArthrosisDividerElbowCount -= ARTHROSIS_DIVIDER_ELBOW_PERIOD;g_nArthrosisElbowCount ++;if(g_nElbowAngle != 0) {if(g_nElbowAngle > 0) {ON(SM_DIR2);if(g_nArthrosisElbowCount & 0x1) {ON(SM_PUL2);} else {OFF(SM_PUL2);g_nElbowAngle --;}            } else {OFF(SM_DIR2);if(g_nArthrosisElbowCount & 0x1) {ON(SM_PUL2);} else {OFF(SM_PUL2);g_nElbowAngle ++;}            }}}
}

3.设置角度极限检查

使用 ArthrosisLimitCheck()来检查角度的极限。

CONTROL_EXT int g_nArthrosisCheckCount;
#define ARTHROSIS_CHECK_PERIOD                  50
void ArthrosisLimitCheck(void);#define SHOULDER_ANGLE_MIN          8192
#define SHOULDER_ANGLE_MAX          24576
#define ELBOW_ANGLE_MIN             4096
#define ELBOW_ANGLE_MAX             28672
void ArthrosisLimitCheck(void) {if(HAL_GetTick() < g_nArthrosisCheckCount) return;g_nArthrosisCheckCount = HAL_GetTick() + ARTHROSIS_CHECK_PERIOD;if(g_nShoulderAngle != 0) {        int nAngle = ShoulderAngle();if(g_nShoulderAngle < -1) {if(nAngle < SHOULDER_ANGLE_MIN)g_nShoulderAngle = -1;                } else if(g_nShoulderAngle > 1) {if(nAngle > SHOULDER_ANGLE_MAX)g_nShoulderAngle = 1;}        }if(g_nElbowAngle != 0) {        int nAngle = ElbowAngle();if(g_nElbowAngle < -1) {if(nAngle < ELBOW_ANGLE_MIN)g_nElbowAngle = -1;                } else if(g_nElbowAngle > 1) {            if(nAngle > ELBOW_ANGLE_MAX)g_nElbowAngle = 1;}        }
}

 

03 角度调节


1.角度设置

void ShoulderGotoAngle(int nAngle) {if(nAngle < SHOULDER_ANGLE_MIN) nAngle = SHOULDER_ANGLE_MIN;if(nAngle > SHOULDER_ANGLE_MAX) nAngle = SHOULDER_ANGLE_MAX;int nNowAngle = ShoulderAngle();int nDeltaAngle = (nAngle - nNowAngle) * SHOULDER_HALF_PULSE / 0x4000;g_nShoulderAngle += nDeltaAngle;
}void ElbowGotoAngle(int nAngle) {if(nAngle < ELBOW_ANGLE_MIN) nAngle = ELBOW_ANGLE_MIN;if(nAngle > ELBOW_ANGLE_MAX) nAngle = ELBOW_ANGLE_MAX;int nNowAngle = ElbowAngle();int nDeltaAngle = (nAngle - nNowAngle) * ELBOW_HALF_PULSE / 0x4000;g_nElbowAngle += nDeltaAngle;}

2.角度调节

void ShoulderAngleSet(int nAngle) {g_nElbowAngleSet = nAngle;g_nElbowAngleAdjustTime = 5;
}void ElbowAngleSet(int nAngle) {g_nShoulderAngleSet = nAngle;g_nShoulderAngleAdjustTime = 5;
}

 

➤※ 附件


/*
**==============================================================================
** CONTROL.C:             -- by Dr. ZhuoQing, 2014-2-4
**
**==============================================================================
*/
#include "stm32f1xx_hal.h"
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "stm32f1xxa.h"
#include "serialtxt.h"
#include "stdsub.h"
#include "config.h"
#include "cmdsub.h"
//------------------------------------------------------------------------------#define CONTROL_GLOBALS        1                       // Define the global variables
#include "CONTROL.H"
#include "ST3806.H"//==============================================================================
//                    Initialize function
//------------------------------------------------------------------------------
extern TIM_HandleTypeDef htim1, htim4;
void ControlInit(void) {SerialTxtInit();                            // Initialize the console debug interface//--------------------------------------------------------------------------HAL_TIM_Base_Start(&htim1);HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);HAL_TIM_Base_Start_IT(&htim4);//----------------------------------------------------------------------OFF(SM_PUL1);                           // as NL2003 output, OFF means out off.OFF(SM_DIR1);OFF(SM_PUL2);OFF(SM_DIR2);OFF(SM_PUL3);OFF(SM_DIR3);OFF(SM_ENABLE);OUT(SM_PUL1);OUT(SM_DIR1);OUT(SM_PUL2);OUT(SM_DIR2);OUT(SM_PUL3);OUT(SM_DIR3);OUT(SM_ENABLE);//------------------------------------------------------------------        ON(ARM_POS0);ON(ARM_POS1);INPU(ARM_POS0);INPU(ARM_POS1);    g_nArmUpDownFlag = ARM_UPDOWN_STOP;g_nArmUpDownCount = 0;//--------------------------------------------------------------------------ST3806Init(1);//--------------------------------------------------------------------------g_nShoulderAngle = 0;g_nElbowAngle = 0;g_nArthrosisShoulderCount = 0;g_nArthrosisElbowCount = 0;g_nArthrosisDividerShoulderCount = 0;g_nArthrosisDividerElbowCount = 0;g_nShoulderDividerInc = ARTHROSIS_DIVIDER_SHOULDER_INC;g_nElbowDividerInc = ARTHROSIS_DIVIDER_ELBOW_INC;g_nArthrosisCheckCount = HAL_GetTick() + ARTHROSIS_CHECK_PERIOD;g_nShoulderAngleSet = ShoulderAngle();g_nElbowAngleSet = ElbowAngle();g_nShoulderAngleAdjustTime = 0;g_nElbowAngleAdjustTime = 0;
}//--------------------------------------------------------------------------
void ArmMoveUpDownISR(void) {if(g_nArmUpDownFlag == ARM_UPDOWN_STOP) return;//--------------------------------------------------------------------------g_nArmUpDownISRCount ++;if(++g_nArmUpDownCount & 0x1) {ON(SM_PUL3);} else {OFF(SM_PUL3);if(g_nArmUpDownFlag == ARM_UPDOWN_MOVEUP) {if(ARM_POS_UP)    g_nArmUpDownFlag = ARM_UPDOWN_STOP;} else {if(ARM_POS_DOWN)  g_nArmUpDownFlag = ARM_UPDOWN_STOP;}}
}//------------------------------------------------------------------------------
void ArmMoveUp(void) {ON(SM_DIR3);g_nArmUpDownFlag = ARM_UPDOWN_MOVEUP;g_nArmUpDownISRCount = 0;}//------------------------------------------------------------------------------
void ArmMoveDown(void) {OFF(SM_DIR3);g_nArmUpDownFlag = ARM_UPDOWN_MOVEDOWN;g_nArmUpDownISRCount = 0;
}void ArmMoveStop(void) {g_nArmUpDownFlag = ARM_UPDOWN_STOP;g_nArmUpDownISRCount = 0;
}        //------------------------------------------------------------------------------
unsigned int ShoulderAngle(void) {unsigned int nAngle;nAngle = ST3806ReadNumber(ST3806_CHANNEL_1);return (nAngle + ARM_SHOULDER_OFFSET) & 0x7fff;
}unsigned int ElbowAngle(void) {unsigned int nAngle;nAngle = ST3806ReadNumber(ST3806_CHANNEL_2);return (nAngle + ARM_ELBOW_OFFSET) & 0x7fff;
}//------------------------------------------------------------------------------
void ArthrosisISR(void) {//--------------------------------------------------------------------------g_nArthrosisDividerShoulderCount += g_nShoulderDividerInc;if(g_nArthrosisDividerShoulderCount >= ARTHROSIS_DIVIDER_SHOULDER_PERIOD) {g_nArthrosisDividerShoulderCount -= ARTHROSIS_DIVIDER_SHOULDER_PERIOD;g_nArthrosisShoulderCount ++;if(g_nShoulderAngle != 0) {if(g_nShoulderAngle > 0) {ON(SM_DIR1);if(g_nArthrosisShoulderCount & 0x1) {ON(SM_PUL1);} else {OFF(SM_PUL1);g_nShoulderAngle --;}            } else {OFF(SM_DIR1);if(g_nArthrosisShoulderCount & 0x1) {ON(SM_PUL1);} else {OFF(SM_PUL1);g_nShoulderAngle ++;}            }}}g_nArthrosisDividerElbowCount += g_nElbowDividerInc;if(g_nArthrosisDividerElbowCount >= ARTHROSIS_DIVIDER_ELBOW_PERIOD) {g_nArthrosisDividerElbowCount -= ARTHROSIS_DIVIDER_ELBOW_PERIOD;g_nArthrosisElbowCount ++;if(g_nElbowAngle != 0) {if(g_nElbowAngle > 0) {ON(SM_DIR2);if(g_nArthrosisElbowCount & 0x1) {ON(SM_PUL2);} else {OFF(SM_PUL2);g_nElbowAngle --;}            } else {OFF(SM_DIR2);if(g_nArthrosisElbowCount & 0x1) {ON(SM_PUL2);} else {OFF(SM_PUL2);g_nElbowAngle ++;}            }}}}//------------------------------------------------------------------------------
void ArthrosisLimitCheck(void) {if(HAL_GetTick() < g_nArthrosisCheckCount) return;g_nArthrosisCheckCount = HAL_GetTick() + ARTHROSIS_CHECK_PERIOD;if(g_nShoulderAngle != 0) {        int nAngle = ShoulderAngle();if(g_nShoulderAngle < -1) {if(nAngle < SHOULDER_ANGLE_MIN)g_nShoulderAngle = -1;                } else if(g_nShoulderAngle > 1) {if(nAngle > SHOULDER_ANGLE_MAX)g_nShoulderAngle = 1;}        } else {if(g_nShoulderAngleAdjustTime > 0) {g_nShoulderAngleAdjustTime --;ShoulderGotoAngle(g_nShoulderAngleSet);}}if(g_nElbowAngle != 0) {        int nAngle = ElbowAngle();if(g_nElbowAngle < -1) {if(nAngle < ELBOW_ANGLE_MIN)g_nElbowAngle = -1;                } else if(g_nElbowAngle > 1) {            if(nAngle > ELBOW_ANGLE_MAX)g_nElbowAngle = 1;}        } else {if(g_nElbowAngleAdjustTime > 0) {g_nElbowAngleAdjustTime --;
//            ElbowGotoAngle(g_nElbowAngleSet);}}}//------------------------------------------------------------------------------
void ShoulderGotoAngle(int nAngle) {if(nAngle < SHOULDER_ANGLE_MIN) nAngle = SHOULDER_ANGLE_MIN;if(nAngle > SHOULDER_ANGLE_MAX) nAngle = SHOULDER_ANGLE_MAX;int nNowAngle = ShoulderAngle();int nDeltaAngle = (nAngle - nNowAngle) * SHOULDER_HALF_PULSE / 0x4000;g_nShoulderAngle += nDeltaAngle;
}void ElbowGotoAngle(int nAngle) {if(nAngle < ELBOW_ANGLE_MIN) nAngle = ELBOW_ANGLE_MIN;if(nAngle > ELBOW_ANGLE_MAX) nAngle = ELBOW_ANGLE_MAX;int nNowAngle = ElbowAngle();int nDeltaAngle = (nAngle - nNowAngle) * ELBOW_HALF_PULSE / 0x4000;g_nElbowAngle += nDeltaAngle;}//------------------------------------------------------------------------------
void ShoulderAngleSet(int nAngle) {g_nElbowAngleSet = nAngle;g_nElbowAngleAdjustTime = 5;
}void ElbowAngleSet(int nAngle) {g_nShoulderAngleSet = nAngle;g_nShoulderAngleAdjustTime = 5;
}//------------------------------------------------------------------------------//==============================================================================
//                END OF THE FILE : CONTROL.C
//------------------------------------------------------------------------------
/*
**==============================================================================
** CONTROL.H:             -- by Dr. ZhuoQing, 2014-2-4
**
**  Description:
**
**==============================================================================
*/
#ifndef __CONTROL__
#define __CONTROL__
//------------------------------------------------------------------------------
#ifdef CONTROL_GLOBALS#define CONTROL_EXT
#else#define CONTROL_EXT extern
#endif // CONTROL_GLOBALS
//------------------------------------------------------------------------------//==============================================================================
//                INTERFACE INITIALIZE FUNCTION
//------------------------------------------------------------------------------
void ControlInit(void);//#define ANGLE_DIR1      GPIOB,7
//#define ANGLE_DIR2      GPIOB,6
#define BEEP            GPIOB,5
#define KEYIN           GPIOB,4    //---------------------------------------------------------------------------
#define SM_PUL1         GPIOA,4
#define SM_DIR1         GPIOA,5
#define SM_PUL2         GPIOA,6
#define SM_DIR2         GPIOA,7
#define SM_PUL3         GPIOB,0
#define SM_DIR3         GPIOB,1
#define SM_ENABLE       GPIOC,15#define ARM_MOVE_UP     ON(SM_DIR3)
#define ARM_MOVE_DOWN   OFF(SM_DIR3)//------------------------------------------------------------------------------
#define ARM_POS0        GPIOA,0
#define ARM_POS1        GPIOA,1#define ARM_POS_UP      VAL(ARM_POS1)
#define ARM_POS_DOWN    VAL(ARM_POS0)void ArmMoveUpDownISR(void);
CONTROL_EXT int g_nArmUpDownFlag;           // 0: Stop; 1:Move Up; 2:Move Down
CONTROL_EXT int g_nArmUpDownCount;          // Last bit generate pulse
#define ARM_UPDOWN_STOP         0
#define ARM_UPDOWN_MOVEUP       1
#define ARM_UPDOWN_MOVEDOWN     2CONTROL_EXT int g_nArmUpDownISRCount;void ArmMoveUp(void);
void ArmMoveDown(void);
void ArmMoveStop(void);//------------------------------------------------------------------------------
#define ARM_SHOULDER_OFFSET     15176
#define ARM_ELBOW_OFFSET        7433unsigned int ShoulderAngle(void);
unsigned int ElbowAngle(void);//------------------------------------------------------------------------------
CONTROL_EXT int g_nShoulderAngle, g_nElbowAngle;
CONTROL_EXT int g_nArthrosisShoulderCount, g_nArthrosisElbowCount;
CONTROL_EXT int g_nArthrosisDividerShoulderCount, g_nArthrosisDividerElbowCount;#define ARTHROSIS_DIVIDER_SHOULDER_PERIOD       100
#define ARTHROSIS_DIVIDER_SHOULDER_INC          65
#define ARTHROSIS_DIVIDER_ELBOW_PERIOD          100
#define ARTHROSIS_DIVIDER_ELBOW_INC             60CONTROL_EXT int g_nShoulderDividerInc, g_nElbowDividerInc;void ArthrosisISR(void);//------------------------------------------------------------------------------
CONTROL_EXT int g_nArthrosisCheckCount;
#define ARTHROSIS_CHECK_PERIOD                  50
void ArthrosisLimitCheck(void);#define SHOULDER_ANGLE_MIN          8192
#define SHOULDER_ANGLE_MAX          24576
#define ELBOW_ANGLE_MIN             4096
#define ELBOW_ANGLE_MAX             28672#define SHOULDER_HALF_PULSE         32000
#define ELBOW_HALF_PULSE            25600//------------------------------------------------------------------------------
void ShoulderGotoAngle(int nAngle);
void ElbowGotoAngle(int nAngle);//------------------------------------------------------------------------------
CONTROL_EXT int g_nShoulderAngleSet, g_nElbowAngleSet;
CONTROL_EXT int g_nShoulderAngleAdjustTime;
CONTROL_EXT int g_nElbowAngleAdjustTime;void ShoulderAngleSet(int nAngle);
void ElbowAngleSet(int nAngle);//==============================================================================
//             END OF THE FILE : CONTROL.H
//------------------------------------------------------------------------------
#endif // __CONTROL__

■ 相关文献链接:

  • 基于STM32对于三轴机械臂控制器设计
  • 对于STM32F103三轴机械臂控制器进行基本功能测试-关节角度读取
  • 对于STM32F103三轴机械臂控制器进行基本功能测试-上下运动功能
  • 增加行星轮减速后机械臂调试
  • 组装肩部带有减速器双轴机械臂组装与调试
  • 两轴机械臂+机械爪整体控制板设计与机械爪控制调试
  • 双关节机械臂+机械爪运动控制
  • 57HSXXXXEIS一体化步进伺服驱动电机
  • 42HS48EIS步进闭环电机最大转速

  1. 硬件结构AD设计工程文件:AD\XQWF\2020\机械臂\CNTINTERFACE.PcbDoc ↩︎

  2. STM32单片机工程文件:STM32\Application\XQWF\2020\CNTSTM103\ ↩︎

对于STM32F103控制的三轴机械臂基本功能测试-关节转动控制相关推荐

  1. 基于STM32对于三轴机械臂控制器设计

    简 介: 本文使用了STM32对于一款三轴机械臂进行初步驱动,调试他的各个关节的运动情况. 关键词: 机械臂,三轴机械臂,STM32 ➤ 01背景 在 组装肩部带有减速器双轴机械臂组装与调试 的调试基 ...

  2. 对于STM32F103三轴机械臂控制器进行基本功能测试-上下运动功能

    简 介: 本文针对基于在基于STM32对于三轴机械臂控制器设计 中设计了控制电路板.本文记录对其在机械臂实际部件进行调试的过程. 关键词: STM32F103,机械臂,三轴,上下运动 ➤01 机械臂控 ...

  3. 对于STM32F103三轴机械臂控制器进行基本功能测试-关节角度读取

    ➤01 机械臂调试 1.简介 对 基于STM32对于三轴机械臂控制器设计 中对应的控制电路读取肩部和肘部两个 角度编码器 ST-3806-15-RS 数据进行调试. 2.接口电路1 ▲ 角度读取的相关 ...

  4. Rviz玩转三轴机械臂

    前言 最近想加深ROS仿真机械臂的理解,所以笔者参考一些资料与博客,在ROS下搭个简单的三轴机械臂,在Rviz下实现各轴关节转动,如果后续有时间的话,可能会更新下Gazebo下仿真,如果时间不够的话, ...

  5. grbl控制3轴机械臂 原理 实现 (四) 之GRBL源码修改驱动三轴机械臂

    往期回顾: 第一篇:grbl控制3轴机械臂 原理 实现 (一) 之2D机械臂模拟及实现 第二篇:grbl控制3轴机械臂 原理 实现 (二) 之3D机械臂模拟及实现 第三篇:grbl控制3轴机械臂 原理 ...

  6. 逆运动学:RRR型 2D 三轴机械臂的IK求解 | 机械臂运动学笔记(二)

    任务: 给定末端的(x,y, \phi),求各轴角度( θ 1 , θ 2 , θ 3 \theta_1 , \theta_2, \theta_3 θ1​,θ2​,θ3​) 先将多个空间几何拆解成平面 ...

  7. 三轴机械臂/三自由度四足单腿DH正逆运动学及matlab验证

    实物模型 DH建立坐标系以及正逆运动学推导 Matlab验证 clear; clc; a1=-9.57*0.001;alpha1=pi/2; a2=-59.2*0.001; a3=-77*0.001; ...

  8. 基于STM32F103双轴机械臂完整电路板设计

    ➤01 机械臂设计   在 基于STM32对于三轴机械臂控制器设计 设计了机械臂的控制电路板.采用了双板分开设计方式.并分别进行了如下的测试:   1. 对于STM32F103三轴机械臂控制器进行基本 ...

  9. grbl控制3轴机械臂 原理 实现 (三) 之如何通过步进电机控制机械臂、插补算法

    参考: 图形学入门 https://www.zhihu.com/question/20330720 https://zhuanlan.zhihu.com/p/30553006 https://www. ...

最新文章

  1. LeetCode: 344. Reverse String
  2. 【Android NDK 开发】Android.mk 配置静态库 ( Android Studio 配置静态库 | 配置动态库与静态库区别 | 动态库与静态库打包对比 )
  3. w ndows无法识别usb,电脑无法识别usb设备的解决方法
  4. 8支团队正在努力构建下一代Ethereum
  5. Python资料分享来袭,收下不谢!
  6. 在线打假!“鲁迅说过的话”检索系统上线 网友太热情系统一度崩溃
  7. 创建多个设备文件节点_使用DEVICE_ATTR实例分析
  8. 推荐 OS X 下最方便实用的六款解压缩软件
  9. MATLAB 内积外积混合积
  10. itext7接口和类概述以及pdf常见操作
  11. vcard怎么转excel vcf转excel神器教程
  12. 心存希望,幸福就会靠近你;心存梦想,机遇就会笼罩你;心存坚持,快乐就会常伴你;心存善念,阳光就会照耀你;心存美丽,温暖就会围绕你;心存他人,真情就会回报你;心存感恩,贵人就会青睐你。
  13. 电商行业特点以及理解电商的模式
  14. java http心跳_MQTT协议笔记之连接和心跳
  15. 重启w7计算机按那个键,win7电脑重启的快捷键
  16. 顺丰下单空运实际发陆运
  17. 【H.264】SPS 解析
  18. 开放世界游戏中的大地图的实现——内容制作篇/异次元篇
  19. vue3版本网页小游戏
  20. 2022华为杯数学建模B题——方形件组批优化问题

热门文章

  1. 新ITC提交APP常见问题与解决方法(Icon Alpha,Build version,AppIcon120x120)(2014-11-17)
  2. asp.net core 教程(七)-异常处理、静态文件
  3. 机器学习——大数据与MapReduce
  4. android下调试声卡驱动之概述
  5. 浅谈通信编程(二)--如何分离通信物理接口和应用程序
  6. 从强制卸载Office到强制安装WPS
  7. 第 127 章 Piranha - Cluster administation tools
  8. LeoFS —— 高可靠性的分布式对象存储系统
  9. PHP并发IO编程之路
  10. jquery插件,nocube