using System; using CCDCount.DLL.CanBus; namespace CanTest { /// /// PDO映射配置示例 /// 演示如何配置TPDO和RPDO的数据映射 /// public class PdoMappingExample { /// /// 示例1:配置TPDO1映射(从站→PLC) /// 将数字输入和模拟输入映射到TPDO1 /// public static void Example1_ConfigureTpdoMapping(CanOpenSlave slave) { Console.WriteLine("=== 示例1: 配置TPDO1映射 ===\n"); // TPDO1映射配置: // 条目1: 0x6000:01 (Digital Input Bit 0) - 8位 // 条目2: 0x6400:01 (Analog Input Ch1) - 16位 ushort mappingIndex = 0x1A00; // TPDO1映射参数 // 设置映射条目数量 slave.SetObjectValue(mappingIndex, 0x00, (byte)2); // 配置第1个映射项:0x6000:01, 8位 // 格式:[索引(16位)][子索引(8位)][位数(8位)] uint mapping1 = (0x6000U << 16) | (0x01U << 8) | 0x08U; slave.SetObjectValue(mappingIndex, 0x01, mapping1); // 配置第2个映射项:0x6400:01, 16位 uint mapping2 = (0x6400U << 16) | (0x01U << 8) | 0x10U; slave.SetObjectValue(mappingIndex, 0x02, mapping2); Console.WriteLine("TPDO1映射配置完成:"); Console.WriteLine(" - 0x6000:01 (Digital Input) - 8位"); Console.WriteLine(" - 0x6400:01 (Analog Input Ch1) - 16位"); Console.WriteLine(" TPDO1总长度: 3字节\n"); } /// /// 示例2:配置RPDO1映射(PLC→从站) /// 将数字输出和模拟输出映射到RPDO1 /// public static void Example2_ConfigureRpdoMapping(CanOpenSlave slave) { Console.WriteLine("=== 示例2: 配置RPDO1映射 ===\n"); // RPDO1映射配置: // 条目1: 0x6200:01 (Digital Output Bit 0) - 8位 // 条目2: 0x6410:01 (Analog Output Ch1) - 16位 ushort mappingIndex = 0x1600; // RPDO1映射参数 // 设置映射条目数量 slave.SetObjectValue(mappingIndex, 0x00, (byte)2); // 配置第1个映射项:0x6200:01, 8位 uint mapping1 = (0x6200U << 16) | (0x01U << 8) | 0x08U; slave.SetObjectValue(mappingIndex, 0x01, mapping1); // 配置第2个映射项:0x6410:01, 16位 uint mapping2 = (0x6410U << 16) | (0x01U << 8) | 0x10U; slave.SetObjectValue(mappingIndex, 0x02, mapping2); Console.WriteLine("RPDO1映射配置完成:"); Console.WriteLine(" - 0x6200:01 (Digital Output) - 8位"); Console.WriteLine(" - 0x6410:01 (Analog Output Ch1) - 16位"); Console.WriteLine(" RPDO1总长度: 3字节\n"); } /// /// 示例3:配置多个TPDO /// public static void Example3_MultipleTpdoConfiguration(CanOpenSlave slave) { Console.WriteLine("=== 示例3: 配置多个TPDO ===\n"); // TPDO1: 数字输入 (事件驱动) ConfigureTpdo(slave, 1, 0x1A00, new uint[] { (0x6000U << 16) | (0x01U << 8) | 0x08U, // Digital Input Bit 0 (0x6000U << 16) | (0x02U << 8) | 0x08U, // Digital Input Bit 1 }, transmissionType: 0xFF); // TPDO2: 模拟输入 (SYNC同步,每10个SYNC发送) ConfigureTpdo(slave, 2, 0x1A01, new uint[] { (0x6400U << 16) | (0x01U << 8) | 0x10U, // Analog Input Ch1 (0x6400U << 16) | (0x02U << 8) | 0x10U, // Analog Input Ch2 }, transmissionType: 10); Console.WriteLine("多TPDO配置完成\n"); } /// /// 辅助方法:配置TPDO /// private static void ConfigureTpdo(CanOpenSlave slave, byte pdoNumber, ushort mappingIndex, uint[] mappings, byte transmissionType = 0xFF) { // 启用TPDO slave.ConfigureTpdo(pdoNumber, true, transmissionType); // 设置映射条目数量 slave.SetObjectValue(mappingIndex, 0x00, (byte)mappings.Length); // 配置每个映射项 for (int i = 0; i < mappings.Length; i++) { slave.SetObjectValue(mappingIndex, (byte)(i + 1), mappings[i]); } Console.WriteLine($"TPDO{pdoNumber}已配置 ({mappings.Length}个映射项, 传输类型:{transmissionType})"); } /// /// 完整配置示例 /// public static void RunFullExample() { Console.WriteLine("========================================"); Console.WriteLine(" CANopen从站 PDO映射完整配置示例"); Console.WriteLine("========================================\n"); byte nodeId = 5; using (CanOpenSlave slave = new CanOpenSlave(nodeId)) { // 初始化 if (!slave.Initialize(CanBaudRate.BaudRate_500K)) { Console.WriteLine("初始化失败"); return; } // 配置PDO映射 Example1_ConfigureTpdoMapping(slave); Example2_ConfigureRpdoMapping(slave); Example3_MultipleTpdoConfiguration(slave); // 设置心跳 slave.SetHeartbeatTime(1000); // 生成EDS文件 slave.GenerateEdsFile($"Node{nodeId}_Configured.eds"); // 启动从站 slave.Start(); Console.WriteLine("\n从站已启动,等待PLC连接..."); Console.WriteLine("按任意键退出...\n"); Console.ReadKey(); slave.Stop(); } } } }