固高GTS运动控制卡 — C#开发完全指南

一、硬件认知与选型

1. 固高GTS系列产品线

型号 轴数 接口 特点
GTS-400 4轴 PCI/PCIe 基础款,适合小型设备
GTS-800 8轴 PCI/PCIe 主流型号,支持复杂多轴联动
GTS-VB系列 4~8轴 PCI/PCIe 支持VB/C#/LabVIEW多语言开发

2. 硬件组成清单

组件 说明
GTS控制卡(PCI插卡) 插入工控机PCI/PCIe插槽
接线板(端子板) 信号转接,连接驱动器与IO
连接线缆 控制卡与接线板之间的专用线缆
开关电源 为接线板和传感器供电(通常24V)
步进/伺服驱动器 接收脉冲信号驱动电机
NPN型感应开关 原点/限位检测

3. 通信架构

cs 复制代码
PC(上位机)→ PCI/PCIe总线 → GTS控制卡(DSP+FPGA)→ 脉冲/模拟量 → 驱动器 → 电机
                                                              ↕
                                                         编码器反馈

二、开发环境搭建

1. 准备文件

文件 位置 作用
gts.dll 项目的 bin\Debug 目录 底层动态链接库,运行时必须
gts.cs 项目源码中 C# P/Invoke 封装类,包含全部API声明
GTS800.cfg 项目目录 固高MCT2008工具生成的配置文件

2. 项目配置要求

  • 框架:.NET Framework(WinForm项目,部分功能不支持.NET Core)

  • 平台:Windows,x86 或 AnyCPU

  • 添加引用 :将 gts.cs 添加到项目类文件中;将 gts.dll 放入 bin\Debug

3. gts.cs 核心结构

gts.cs 中定义了 namespace gts 下的静态类 mc,所有函数通过 [DllImport("gts.dll")] 声明。存在两个版本:单卡版(613行)和多卡版(1265行),函数签名有显著差异:

cs 复制代码
using System.Runtime.InteropServices;
​
namespace gts
{
    public class mc
    {
        // ===== 单卡版(613行)签名 =====
        [DllImport("gts.dll")]
        public static extern short GT_Open(short channel, short param);
        // channel: 通信通道(PCI=0),param: 保留参数
​
        [DllImport("gts.dll")]
        public static extern short GT_Close();
​
        [DllImport("gts.dll")]
        public static extern short GT_LoadConfig(string pFile);
​
        [DllImport("gts.dll")]
        public static extern short GT_Reset();
​
        [DllImport("gts.dll")]
        public static extern short GT_AxisOn(short axis);
​
        [DllImport("gts.dll")]
        public static extern short GT_AxisOff(short axis);
​
        [DllImport("gts.dll")]
        public static extern short GT_Stop(int mask, int option);
        // mask: 按位选择轴(bit0=轴1),option: 停止方式
​
        // ===== 多卡版(1265行)额外签名 =====
        // GT_Open(short cardNum, string configFile, string password)
        // 所有函数额外增加 short cardNum 第一参数
    }
}

⚠️ 关键区别 :单卡版 GT_Open 参数为 (short channel, short param),多卡版为 (short cardNum, string configFile, string password)。混用会导致崩溃。


三、标准开发流程

1. 控制卡初始化

cs 复制代码
// ===== 单卡版初始化 =====
// 1. 打开控制卡(channel=0为PCI通道,param=0保留)
short rtn = mc.GT_Open(0, 0);
CheckResult(rtn); // 检查返回值,0=成功
​
// 2. 复位控制卡
rtn = mc.GT_Reset();
CheckResult(rtn);
​
// 3. 加载配置文件(由MCT2008工具生成)
rtn = mc.GT_LoadConfig("GTS800.cfg");
CheckResult(rtn);
​
// 4. 清除各轴状态(从轴1开始,清除8个轴)
rtn = mc.GT_ClrSts(1, 8);
CheckResult(rtn);

注意 :多卡版初始化为 GT_Open(cardNum, "GTS800.cfg", ""),三个参数版本。
返回值约定 :所有GT_函数返回 short 类型,0 表示成功,非0为错误码。

2. 错误码速查表

错误码 含义
0 成功
1 命令错误
2 host命令参数错误
3 地址错误
4 数据错误
5 功能号错误
6 通信错误
7 超时
8 未知错误
9 设备未找到
10 功能不支持
cs 复制代码
private void CheckResult(short rtn)
{
    if (rtn != 0)
    {
        throw new Exception($"GTS调用失败,错误码: {rtn}");
    }
}

四、单轴运动控制

1. 轴使能/关闭

cs 复制代码
// 使能轴1
mc.GT_AxisOn(1);
​
// 关闭轴1
mc.GT_AxisOff(1);

2. 点位运动(Trap梯形速度曲线)

适合从A点到B点的精确定位:

cs 复制代码
// 1. 设置为梯形速度模式(参数为profile号,非轴号)
mc.GT_PrfTrap(1);
​
// 2. 设置梯形速度参数
mc.TTrapPrm trapPrm = new mc.TTrapPrm();
trapPrm.acc = 0.5;       // 加速度(单位/秒²)
trapPrm.dec = 0.5;       // 减速度
trapPrm.velStart = 0;    // 起始速度
trapPrm.smoothTime = 0;  // 平滑时间(short类型)
mc.GT_SetTrapPrm(1, ref trapPrm);
​
// 3. 设置目标速度
mc.GT_SetVel(1, 50);    // 速度 = 50 单位/秒
​
// 4. 设置目标位置
mc.GT_SetPos(1, 10000); // 目标位置 = 10000 脉冲(int类型)
​
// 5. 更新运动(按位mask,bit0对应profile1)
mc.GT_Update(1 << 0);

绝对位置 vs 相对位置GT_SetPos 设置的是绝对位置值。要实现相对运动,需先用 GT_GetEncPos 获取当前位置,再加上偏移量设置 GT_SetPos。或用 GT_ZeroPos(axis, 1) 清零后设置。

3. Jog连续运动

适合调试时的手动点动:

cs 复制代码
// 鼠标按下 → 启动Jog
mc.GT_PrfJog(1);
​
mc.TJogPrm jogPrm = new mc.TJogPrm();
jogPrm.acc = 0.5;    // 加速度
jogPrm.dec = 0.5;    // 减速度
jogPrm.smooth = 0;   // 平滑系数(double类型)
mc.GT_SetJogPrm(1, ref jogPrm);
​
mc.GT_SetVel(1, 10); // 正值=正向,负值=反向
mc.GT_Update(1 << 0);
​
// 鼠标松开 → 停止(mask为按位选择轴,option=0为立即停止)
mc.GT_Stop(1 << 0, 0); // 停止profile1

4. 获取轴状态与位置

cs 复制代码
// 获取编码器位置(注意:实际签名包含 out uint pClock 参数)
double encPos = 0;
mc.GT_GetEncPos(1, out encPos, 1, out uint encClock);
​
// 获取规划位置
double prfPos = 0;
mc.GT_GetPrfPos(1, out prfPos, 1, out uint prfClock);
​
// 获取规划速度
double prfVel = 0;
mc.GT_GetPrfVel(1, out prfVel, 1, out uint velClock);
​
// 获取轴状态字(count=读取轴数,pClock=时钟)
int sts = 0;
mc.GT_GetSts(1, out sts, 1, out uint stsClock);
​
// 状态位解析(⚠️ 不同固件版本位定义可能不同,以官方手册为准)
bool posLimit    = (sts & 0x0001) != 0; // bit0: 正限位触发
bool negLimit    = (sts & 0x0002) != 0; // bit1: 负限位触发
bool alarm       = (sts & 0x0004) != 0; // bit2: 驱动器报警
bool homeStatus  = (sts & 0x0008) != 0; // bit3: 原点信号
bool isEnable    = (sts & 0x0100) != 0; // bit8: 驱动器使能

⚠️ 状态位差异警告 :不同项目中状态位定义不一致(如堆垛机项目中 bit1=报警, bit5=正限位, bit6=负限位, bit9=使能)。必须以你所用控制卡型号的官方编程手册为准,不能直接照搬。


五、多轴插补运动

1. 坐标系建立

插补运动需先建立坐标系,将多个物理轴映射到坐标系维度:

cs 复制代码
// 建立2D坐标系(X=轴1, Y=轴2)
mc.TCrdPrm crdPrm = new mc.TCrdPrm();
crdPrm.dimension = 2;        // 2维
crdPrm.profile1 = 1;         // 第1维对应Profile1(轴1)
crdPrm.profile2 = 2;         // 第2维对应Profile2(轴2)
crdPrm.synVelMax = 500;      // 最大合成速度
crdPrm.synAccMax = 100;      // 最大合成加速度
crdPrm.evenTime = 0;         // 匀速段时间(short类型)
crdPrm.setOriginFlag = 1;    // 设置原点(1=使用originPos作为原点)
crdPrm.originPos1 = 0;       // 原点位置X(long类型,非数组)
crdPrm.originPos2 = 0;       // 原点位置Y

mc.GT_SetCrdPrm(1, ref crdPrm); // 坐标系1

⚠️ 注意TCrdPrm 的原点位置字段是 originPos1~originPos8(独立字段,long类型),不是数组 。不同gts.cs版本中可能是 longint 类型,混用会导致内存对齐错误。

2. 直线插补

cs 复制代码
// 清除坐标系1的FIFO 0
mc.GT_CrdClear(1, 0);

// XY直线插补:从当前位置移动到(10000, 20000)
mc.GT_LnXY(1,               // 坐标系号
    10000, 20000,            // 目标X, Y位置(int类型)
    100,                     // 合成速度(double)
    0.1,                     // 合成加速度(double)
    0,                       // 终止速度(double,0=默认)
    0);                      // FIFO号(short)

// 启动插补运动(mask为坐标系bitmask,option保留)
mc.GT_CrdStart(1 << 0, 0);  // bit0=坐标系1

3. 圆弧插补

cs 复制代码
mc.GT_CrdClear(1, 0);

// XY圆弧插补(圆心方式):当前点→终点,以圆心偏移定义圆弧
mc.GT_ArcXYC(1,             // 坐标系号
    20000, 20000,            // 终点X, Y(int)
    0, 10000,               // 圆心相对起点的偏移X, Y(double)
    0,                       // 方向:0=顺时针,1=逆时针(⚠️与直觉相反)
    100, 0.1, 0, 0);        // 合成速度、合成加速度、终止速度、FIFO号

mc.GT_CrdStart(1 << 0, 0);

⚠️ 圆弧方向注意INTERPOLATION_CIRCLE_DIR_CW = 0(顺时针),INTERPOLATION_CIRCLE_DIR_CCW = 1(逆时针)。这与数学上"0=逆时针"的直觉相反。

4. 缓冲区IO与延时

插补过程中可插入IO操作和延时,实现边走边控制:

cs 复制代码
mc.GT_CrdClear(1, 0);

// 第一段直线
mc.GT_LnXY(1, 5000, 5000, 100, 0.1, 0, 0);

// 在插补路径中触发数字输出
// GT_BufIO(crd, doType, doMask, doValue, fifo)
mc.GT_BufIO(1, mc.MC_GPO,  // DO类型(MC_GPO=12, 通用输出)
    0x0001,                 // DO掩码(bit0)
    0x0001,                 // DO值(bit0=高电平)
    0);                     // FIFO号

// 在插补路径中延时500ms
mc.GT_BufDelay(1, 500, 0); // crd, delayTime(ms), fifo

// 第二段直线
mc.GT_LnXY(1, 10000, 10000, 100, 0.1, 0, 0);

mc.GT_CrdStart(1 << 0, 0);

5. 前瞻预处理

高速连续插补时需使用前瞻功能,防止速度突变:

cs 复制代码
// 初始化前瞻
// GT_InitLookAhead(crd, fifo, T, accMax, n, ref pLookAheadBuf)
// T: 转弯时间常数, accMax: 最大允许加速度, n: 前瞻缓冲区大小
mc.TCrdData[] lookAheadBuf = new mc.TCrdData[4096]; // CRD_FIFO_MAX=4096
mc.GT_InitLookAhead(1, 0, 0.05, 10, 256, ref lookAheadBuf[0]);

mc.GT_CrdClear(1, 0);
mc.GT_LnXY(1, 1000, 0, 200, 50, 0, 0);
mc.GT_LnXY(1, 1000, 1000, 200, 50, 0, 0);
mc.GT_LnXY(1, 0, 1000, 200, 50, 0, 0);
mc.GT_LnXY(1, 0, 0, 200, 50, 0, 0);
mc.GT_CrdStart(1 << 0, 0);

六、高级运动模式

1. 电子齿轮

从轴跟随主轴按比例运动:

cs 复制代码
// 设置轴2为齿轮模式
// GT_PrfGear(profile, dir) --- dir: 跟随方向
mc.GT_PrfGear(2, 0);

// 设置主轴为轴1的规划位置
// GT_SetGearMaster(profile, masterIndex, masterType, masterItem)
mc.GT_SetGearMaster(2, 1, mc.GEAR_MASTER_PROFILE, 0);

// 设置齿轮比:masterEven:slaveEven = 主轴脉冲数:从轴脉冲数
// GT_SetGearRatio(profile, masterEven, slaveEven, masterSlope)
mc.GT_SetGearRatio(2, 1, 2, 0); // 主轴走1个单位,从轴走2个单位

// 启动齿轮(按位mask)
mc.GT_GearStart(1 << 1); // bit1=profile2

2. Follow跟随模式

比电子齿轮更灵活,支持动态调整跟随比例:

cs 复制代码
// GT_PrfFollow(profile, dir)
mc.GT_PrfFollow(2, 0);

// GT_FollowClear(profile, fifo)
mc.GT_FollowClear(2, 0);

// 设置主轴(轴1规划位置)
// GT_SetFollowMaster(profile, masterIndex, masterType, masterItem)
mc.GT_SetFollowMaster(2, 1, mc.FOLLOW_MASTER_PROFILE, 0);

// 设置循环次数
mc.GT_SetFollowLoop(2, 0); // 0=无限循环

// 设置跟随事件
// GT_SetFollowEvent(profile, followEvent, masterDir, pos)
mc.GT_SetFollowEvent(2, mc.FOLLOW_EVENT_PASS, 1, 0);

// 添加跟随数据
// GT_FollowData(profile, masterSegment, slaveSegment, type, fifo)
mc.GT_FollowData(2, 10000, 5000, mc.FOLLOW_SEGMENT_NORMAL, 0);
// 主轴移动10000,从轴移动5000

// 启动(mask为按位选择,option保留)
mc.GT_FollowStart(1 << 1, 0);

3. 回零运动

cs 复制代码
// 阶段1:搜索Home信号
// GT_SetCaptureMode(encoder, mode) --- encoder号通常与轴号对应
mc.GT_SetCaptureMode(1, mc.CAPTURE_HOME); // CAPTURE_HOME=1
mc.GT_PrfTrap(1);
mc.TTrapPrm trapPrm = new mc.TTrapPrm();
trapPrm.acc = 0.5;
trapPrm.dec = 0.5;
trapPrm.velStart = 0;
trapPrm.smoothTime = 0;
mc.GT_SetTrapPrm(1, ref trapPrm);
mc.GT_SetVel(1, -10); // 负方向搜索
mc.GT_Update(1 << 0);

// 阶段2:检测Home捕获
// GT_GetCaptureStatus(encoder, out pStatus, out pValue, count, out pClock)
short captureStatus = 0;
int capturePos = 0;
mc.GT_GetCaptureStatus(1, out captureStatus, out capturePos, 1, out uint clock);
if (captureStatus != 0)
{
    // 捕获到Home信号,设置当前位置为捕获位置
    mc.GT_Stop(1 << 0, 0);
    mc.GT_SetPos(1, capturePos);
    mc.GT_Update(1 << 0);
}

4. IO控制

cs 复制代码
// 读取数字输入(DI)
// GT_GetDi(diType, out pValue) --- diType使用MC_GPI=4读取通用输入
int diValue = 0;
mc.GT_GetDi(mc.MC_GPI, out diValue);
// diValue的每一位对应一个输入点

// 设置数字输出(DO)
// GT_SetDo(doType, value) --- MC_ENABLE=10为伺服使能信号
mc.GT_SetDo(mc.MC_ENABLE, 0xFF);
// MC_GPO=12为通用数字输出

// 读取模拟输入(ADC)
// GT_GetAdc(adc, out pValue, count, out pClock)
double adcValue = 0;
mc.GT_GetAdc(1, out adcValue, 1, out uint adcClock);

// 设置模拟输出(DAC)
// GT_SetDac(dac, ref value, count) --- value为raw值,±32767对应±10V
short dacRaw = 3276; // 约1V
mc.GT_SetDac(1, ref dacRaw, 1);

七、实际项目架构参考

1. 封装类设计模式(参考堆垛机项目)

cs 复制代码
public static class GtsControl
{
    // 初始化(单卡版)
    public static void Init()
    {
        mc.GT_Open(0, 0);  // channel=0, param=0
        mc.GT_Reset();
        mc.GT_LoadConfig("GTS800.cfg");
        mc.GT_ClrSts(1, 8); // 清除轴1~8状态
    }

    // 使能/关闭
    public static void AxisEnable(short axis) => mc.GT_AxisOn(axis);
    public static void AxisDisable(short axis) => mc.GT_AxisOff(axis);

    // 停止(按位mask选择轴)
    public static void Stop(short axis)
    {
        // mask = 1 << (axis-1), option = 0b1111111111(急停方式)
        mc.GT_Stop(1 << (axis - 1), 0);
    }

    // 全部停止(mask=-1即所有位为1)
    public static void StopAll() => mc.GT_Stop(-1, 0);

    // 读取轴状态(异步循环,参考堆垛机项目位定义)
    public static async Task StartReadAxisStatus(CancellationToken ct)
    {
        while (!ct.IsCancellationRequested)
        {
            for (short axis = 1; axis <= 8; axis++)
            {
                mc.GT_GetSts(axis, out int sts, 1, out uint _);
                mc.GT_GetEncPos(axis, out double pos, 1, out uint _);

                // ⚠️ 以下位定义来自堆垛机项目,与Form1项目不同
                bool alarm    = ((sts >> 1) & 1) == 1; // bit1: 驱动器报警
                bool posLimit = ((sts >> 5) & 1) == 1; // bit5: 正限位
                bool negLimit = ((sts >> 6) & 1) == 1; // bit6: 负限位
                bool enabled  = ((sts >> 9) & 1) == 1; // bit9: 电机使能
                // ... 更新UI
            }
            await Task.Delay(100);
        }
    }

    // 2D坐标系建立
    public static void CreateCrd(short crdNum, short xAxis, short yAxis)
    {
        mc.TCrdPrm crdPrm = new mc.TCrdPrm();
        crdPrm.dimension = 2;
        crdPrm.profile1 = xAxis;
        crdPrm.profile2 = yAxis;
        crdPrm.synVelMax = 500;
        crdPrm.synAccMax = 100;
        crdPrm.setOriginFlag = 0;
        mc.GT_SetCrdPrm(crdNum, ref crdPrm);
    }
}

2. 状态位解析参考(⚠️ 两种定义并存)

Bit位 Form1项目定义 堆垛机项目定义
bit0 正限位触发 (0x0001) ---
bit1 负限位触发 (0x0002) 驱动器报警
bit2 驱动器报警 (0x0004) ---
bit3 原点信号 (0x0008) ---
bit5 --- 正限位触发
bit6 --- 负限位触发
bit8 驱动器使能 (0x0100) ---
bit9 --- 电机使能

⚠️ 重要 :两套位定义来自同一品牌不同项目,可能对应不同固件版本或不同配置工具生成的cfg。开发时必须查阅你所用控制卡型号对应的编程手册,或用MCT2008工具的状态监控功能验证实际位定义。


八、易混淆点

GT_Open 单卡版 vs 多卡版

对比项 单卡版(613行gts.cs) 多卡版(1265行gts.cs)
函数签名 GT_Open(short channel, short param) GT_Open(short cardNum, string configFile, string password)
参数类型 两个short short + string + string
适用场景 单控制卡系统 多控制卡级联系统
额外功能 激光控制、螺旋插补、2D补偿、Smart Home等
TCrdPrm.originPos long 类型 int 类型(⚠️ 内存布局不同)

⚠️ 严重警告 :两个版本的 TCrdPrm 结构体中 originPos 字段类型不同(long vs int),混用gts.cs和gts.dll版本会导致内存对齐错误和崩溃。

Trap vs Jog vs Pt

对比项 Trap(梯形) Jog(连续) Pt(位置-时间表)
适用场景 A到B定位 调试手动移动 自定义轨迹曲线
速度曲线 梯形/S形 匀速 按数据表插值
停止方式 到达目标自动停 需手动Stop 数据结束自动停
典型调用 GT_PrfTrap GT_PrfJog GT_PrfPt

九、脉冲当量换算与驱动器握手

1. 脉冲当量换算公式

控制卡发出的脉冲数需要换算为实际物理位移,必须代入全部因子:

cs 复制代码
每转脉冲数 = 步距角(°) × 细分数 / 360°

例:步距角1.8°,细分数16 → 每转脉冲数 = 1.8 × 16 / 360 = 3200 脉冲/转

每毫米脉冲数 = 每转脉冲数 × 减速比 / 丝杆导程(mm)

例:3200脉冲/转,减速比1:1,丝杆导程5mm → 3200 / 5 = 640 脉冲/mm
参数 含义 典型值
步距角 电机每步转动角度 1.8°(步进)、360°/编码器线数(伺服)
细分数 驱动器细分设置 1, 2, 4, 8, 16, 32, 256
减速比 减速器输入:输出 1:1, 1:3, 1:10, 1:50
丝杆导程 丝杆转一圈直线位移 5mm, 10mm, 20mm

2. 速度与加速度单位换算

cs 复制代码
目标速度(脉冲/秒) = 目标物理速度(mm/s) × 每毫米脉冲数

例:50mm/s × 640脉冲/mm = 32000 脉冲/秒

目标加速度(脉冲/秒²) = 目标物理加速度(mm/s²) × 每毫米脉冲数

例:500mm/s² × 640 = 320000 脉冲/秒²

⚠️ 验证要点 :设置 GT_SetVelTTrapPrm.acc/dec 时,必须确认单位是"脉冲/秒"还是"物理单位/秒",两者差 每毫米脉冲数 倍。

3. 脉冲输出模式与驱动器握手

模式 说明 驱动器设置
脉冲+方向 PULSE控制步数,DIR控制方向 驱动器设为"脉冲+方向"模式
双脉冲(CW+CCW) CW正转脉冲,CCW反转脉冲 驱动器设为"双脉冲"模式
AB相正交 A相超前B相=正转 驱动器设为"AB相"模式

模式不一致的后果:控制卡输出"脉冲+方向"但驱动器设为"AB相"→电机不转或乱转。

4. 编码器反馈配置

参数 说明 设置方式
倍频方式 1/2/4倍频 由驱动器编码器分频设置
计数方向 与电机实际转向一致 GT_ZeroPos或编码器方向反转配置
Z相捕获 每转一圈的原点信号 GT_SetCaptureMode(CAPTURE_INDEX)

十、异常处理与安全保护

1. 伺服驱动器报警 vs 控制卡报警

报警来源 含义 处理方式
驱动器报警(ALM信号) 过流、过压、编码器异常 检查驱动器面板错误码,排除硬件故障后清除报警
控制卡报警状态位 GT_GetSts检测到报警位 确认驱动器报警已排除后,GT_ClrSts清除状态
跟随误差超限 指令位置与实际位置偏差过大 检查机械阻力、调整PID增益、降低速度

2. 急停后的恢复流程

cs 复制代码
// 步骤1:停止所有轴运动
mc.GT_Stop(-1, 0); // mask=-1停止全部轴

// 步骤2:关闭所有轴使能
for (short axis = 1; axis <= 8; axis++)
    mc.GT_AxisOff(axis);

// 步骤3:排除硬件故障(检查驱动器、机械、限位)

// 步骤4:清除报警状态
mc.GT_ClrSts(1, 8);

// 步骤5:重新使能(确认安全后)
for (short axis = 1; axis <= 8; axis++)
    mc.GT_AxisOn(axis);

3. 软限位保护(第二道防线)

cs 复制代码
// 设置软限位(在硬限位内侧留余量)
// GT_SetSoftLimit(axis, positive, negative) --- 单位:脉冲
mc.GT_SetSoftLimit(1, 100000, -1000); // 正向100000, 负向-1000

// 读取当前软限位设置
mc.GT_GetSoftLimit(1, out int posLimit, out int negLimit);

十一、常见问题排查

错误1:GT_Open返回非0

  • 现象:调用GT_Open失败,返回错误码1或9

  • 原因:控制卡未插好、驱动未安装、或gts.dll版本不匹配

  • 解决

    1. 检查设备管理器中是否有固高PCI设备

    2. 从官网下载并安装最新驱动

    3. 确认gts.dll与控制卡型号匹配

错误2:轴使能后不运动

  • 现象:GT_AxisOn成功,但GT_Update后电机不动

  • 原因:驱动器未接收到脉冲信号、伺服ON信号未给出、或限位触发

  • 解决

    1. 检查脉冲线接线(PULSE+/PULSE-、DIR+/DIR-)

    2. 确认驱动器处于位置模式

    3. 检查限位开关状态:GT_GetDi(MC_LIMIT_POSITIVE, ...)

错误3:插补运动中途停止

  • 现象:插补运动在路径中间停住不继续

  • 原因:FIFO缓冲区为空,CrdStatus返回运动已完成

  • 解决

    1. 检查 GT_CrdStatus 返回的剩余空间段数

    2. 确认所有GT_LnXY/GT_ArcXYC调用返回值为0

    3. 检查是否需要启用前瞻(GT_InitLookAhead


总结

  • 固高GTS控制卡通过 gts.dll + gts.cs 提供完整C# API,大多数函数返回0表示成功

  • 开发标准流程:GT_OpenGT_ResetGT_LoadConfigGT_ClrStsGT_AxisOn → 运动控制 → GT_StopGT_AxisOffGT_Close

  • 单轴用 GT_PrfTrap/GT_PrfJog,多轴插补用 GT_SetCrdPrm + GT_LnXY/GT_ArcXYC

  • 状态监控必须定时轮询 GT_GetSts + GT_GetEncPos

  • 脉冲当量换算必须代入全部因子(步距角、细分数、减速比、丝杆导程),速度/加速度单位必须统一

  • 生产项目必须配置软限位作为第二道保护,急停后按"停轴→关使能→排故障→清状态→重新使能"流程恢复

  • 状态位定义必须以所用控制卡型号的官方手册为准,不同固件版本位定义可能不同

相关推荐
云草桑1 小时前
.NET10+AI 架构师全套实战学习文档(含源码、案例、面试题、项目源码)
人工智能·学习·ai·.net
影寂ldy1 小时前
C# 多播委托
前端·javascript·c#
The Sheep 20231 小时前
C#多线程学习
开发语言·学习·c#
我要打打代码2 小时前
C# 扩展方法
开发语言·c#
椒颜皮皮虾྅2 小时前
OpenVINO™ C# API 3.3 全新发布!正式接入 OpenVINO GenAI,C# 本地大模型开发全面启航!
人工智能·开源·c#·openvino
云草桑2 小时前
跨境信息系统术语研究 —— 产品、单据、身份名片的中文译法演变历程
面试·.net·odoo·erp·跨境
小满Autumn3 小时前
雷赛DMC运动控制卡 — C#开发完全指南
c#·.net·上位机·运动控制卡·雷赛
专注VB编程开发20年12 小时前
AI 生成C# WinForm 窗体 = 目前就是垃圾
开发语言·人工智能·c#