SDO:
SDO是讀寫單個寄存器。主要用于配置伺服驅動器參數。
1? 收發功能:?
//public unsafe struct VCI_CAN_OBJ //CAN數據幀 【單幀對象】//{// public uint ID;// 幀ID。 【11bit】數據右對齊。 詳情請參照: 《8.附件1: ID對齊方式.pdf》說明文檔。// public uint TimeStamp; //設備接收到某一幀的時間標識。 時間標示從CAN卡上電開始計時,計時單位為0.1ms。// public byte TimeFlag; //時間標識,為1時TimeStamp有效// public byte SendType; //發送幀類型。=0時為正常發送(發送失敗會自動重發,重發超時時間為4秒, 4秒內沒有發出則取消);=1時為單次發送// public byte RemoteFlag; //是否是遠程幀【RTR】。 =0時為數據幀, =1時為遠程幀(數據段空)。// public byte ExternFlag; //是否是擴展幀。 =0時為標準幀(11位ID), =1時為擴展幀(29位ID)。// public byte DataLen; //數據長度 DLC (<=8),即CAN幀Data有幾個字節。約束了后面Data[8]中的有效字節。// public fixed byte Data[8]; //如DataLen定義為3,即Data[0]、 Data[1]、 Data[2]是有效的。// public fixed byte Reserved[3];//系統保留。//}
unsafe public int Get_Receive(ref VCI_CAN_OBJ[] obj){//===1 等待加載=================DelaySecond(0.005);//5ms // USB速度3~5ms//===2 接口接收=================object obj2 = new object();//對象int num = Help_rtx.RXs(ref obj2);// can.get_Receive(CAN_DeviceType, CAN_ind, CAN1, ref obj[0], 2000, 50);if (num < 1) return 0;// 空退//===3 取出幀,并且分發=========obj = (VCI_CAN_OBJ[])obj2;//====3界面顯示=================// 分發數據幀,UI層顯示if (Wt_get != null){// 數組是引用類型VCI_CAN_OBJ[] uiObj = new VCI_CAN_OBJ[num];uiObj = obj;UIshow(num, uiObj);// //COB - ID Byte 0:1 Byte 2 Byte 3:7// //0x080 + Node - ID 應急錯誤代碼 錯誤寄存器(1001H) 廠商指定區域// //byte0~1: 8120 【0x603F】// // 應急錯誤代碼// // 0000H 無錯誤// // 8110H CAN 溢出// // 8120H 錯誤被動模式(0411)// // 8130H 壽命保護/ 心跳錯誤// // 8140H 被迫離線恢復故障// // 8141H 被迫離線// // 8150H 發送 COB - ID 沖突// // 8210H PDO 長度錯誤未處理// // 8220H PDO 超過長度// //byte2: 11// // (1001H)位定義// // Bit0:generic error 一般錯誤// // Bit1:current 電流// // Bit2:voltage 電壓 (04)// // Bit3:temperature 溫度// // Bit4:通訊// // Bit5:協議402錯誤// // Bit6:保留// // Bit7:伺服廠家// //————————————————// //版權聲明:本文為CSDN博主「cfqq1989」的原創文章,遵循CC 4.0 BY - SA版權協議,轉載請附上原文出處鏈接及本聲明。// //原文鏈接:https://blog.csdn.net/cfqq1989/article/details/128308808//}// EMCY:故障(從站故障)80h + 從站//if (item.ID > 0x700 && item.ID < (0x700 + 127)) //從站狀態//{// if (Wt_get!=null)// {// NMTslave slave=(NMTslave)p[0];// string sta = Enum.GetName(typeof(NMTslave), slave);// //string str = $"從站:{item.ID - 0x700}狀態{p[0].ToString("X2")}; ";// string str = $"從站:{item.ID - 0x700}_{sta}; ";// Wt_get(null, str);// }//}}return num;}/// <summary>/// 【1 4 8】DLC長度,幀id,數據包64bit【小端】/// </summary>/// <param name="DLC"></param>/// <param name="CANid"></param>/// <param name="byte8"></param>/// <returns></returns>/// <exception cref="Exception"></exception>public bool Set_Send(Byte DLC, UInt32 CANid, Int64 byte8)// 1 4 8{//int hand = 0x88;// 設備:USR-CANET200//int cobid = 0x12345678;// 11bit或29bit//Int64 byte8 = 0x0011223344556677;//wait_dataRX數據池();//can.send(hand8, cobid, byte8);//wait_dataRX數據池();if (DLC > 8) DLC = 8;// <=8string cmd = madeCode((byte)DLC, (UInt32)CANid, byte8);// Code編碼 "08 00000602 2B 5021 00 00000000"if (Help_rtx.TXs(cmd)==1)// 接口功能 "08000006022B50210000000000" // 單幀 13字節( 1 4 8 在接口解碼發送){return true;}else throw new Exception("發送失敗。檢查主站硬件狀態(是否開啟?)!");//return false;}
2? SDO功能碼:
void SDO(Region_Type regtype, UInt16 reg, Byte son, Int32 value)// 1操作類型,2寄存器編號,3子索引,4參數值{// SDO操作 600h+//========================================================// 準備發送Byte by0 = (Byte)regtype;//1 操作碼【u8】UInt16 by1 = (UInt16)reg;//2 寄存器【u16】Byte by2 = (Byte)son;//3 子索引【u8】Int64 by3 = (Int32)value;//4設定值【u32】// b0 b1b2 b3 b4b5b6b7Byte8 = by0 + (by1 << 8) + (by2 << 24) + (by3 << 32); // 23 2000 00 11223344 Set_Send(0x08, 0x600 + Address, Byte8);// 40 2000 00 11223344}
3? SDO讀:
讀的數據幀發出后,伺服回幀包含【寄存器數據類型】【寄存器值】
這里? 寄存器數據類型? 需要標記,因為寫寄存器時需要用到? 【寄存器數據類型】
public enum Region_Type : byte{讀 = 0x40, // 回幀0x60成功成功 = 0x60,失敗 = 0x80,寫b8 = 0x2F,寫b16 = 0x2B,寫b24 = 0x27,寫b32 = 0x23,//寄存器bitb8 = 0x4F,//回幀:4F 寄存器有效長度 8bitb16 = 0x4B,b24 = 0x47,b32 = 0x43}
/// <summary>/// 【讀】寄存器/// </summary>/// <param name="reg"></param>/// <param name="son"></param>/// <returns></returns>unsafe public Int32 SDO(UInt16 reg, Byte son)// 【讀】寄存器,子索引【0x0000~0xFFFF】{// 讀busy = true;//===1 get_數據類型=============//===2 get_Value===================SDO(Region_Type.讀, reg, son, 0);//讀//===2 get_幀===================#region get_ValueVCI_CAN_OBJ[] obj = new VCI_CAN_OBJ[2000];// 創芯科技CAN分析儀最大支持2000幀接收,廣成10239幀Rx13 = new byte[13];// 提取數據幀DelaySecond(0.010);//10ms // USB速度3~5msint num = Get_Receive(ref obj);busy = false;if (num > 0)// 數據幀{for (int i = num - 1; i >= 0; i--){if (obj[i].ID == 0x580 + Address && obj[i].Data[0] != 0x60)// SDO 600h+的回信【580h+】{// 580h+從站地址 回幀//=====580h 寄存器類型====================Rx13[5] = obj[i].Data[0];// 2001.00=50000; // 4B,01 20,00, 50 C3 00 00 // // u16寄存器Rx13[6] = obj[i].Data[1];// 寄存器4B(b16位) 2001-00= 0x 0000C350Rx13[7] = obj[i].Data[2];// u8子索引Rx13[8] = obj[i].Data[3];// int32數據值Rx13[9] = obj[i].Data[4];// 小端Rx13[10] = obj[i].Data[5];Rx13[11] = obj[i].Data[6];Rx13[12] = obj[i].Data[7];//=====2======================//VCI_CAN_OBJ one = obj[i]; //break;}// SDO應答幀(580h+)}}else{Region_Obj = 0x80;// 故障return -1;}// 回幀結果Region_Obj = Rx13[5];// 標記: b8 = 0x4F, b16 = 0x4B, b24 = 0x47, b32 = 0x43 //0x6040是16bitint value = get_Value_U32(Rx13);// 解析 43,4060,00,0000 0000// 日志====================================if (Region_Obj < 0x43 | Region_Obj > 0x4F)// u8~32 讀取失敗 // 參考 enum region_Type //| Region_Type>(int)region_Type.b32{// 0x05030000 80 string error = getError(value, reg, son, -1); // 故障碼,寄存器,子,值if (Wt_get != null){Wt_get(new byte[] { 0x00 }, "讀取寄存器錯誤:" + error);}// throw new Exception("讀取錯誤:" + error);// 提前終止}//錯誤else{//成功return value;}//正確#endregionreturn -1;}
4? SDO寫:
unsafe public bool SDO(UInt16 reg, Byte son, Int32 value)//【寫】{// 寫busy = true;//===1 get寄存器數據類型=============Int32 data = SDO(reg, son);//讀//===2 set_Value=====================if (Region_Obj >= 0x43 || Region_Obj <= 0x4F){SDO((Region_Type)Region_Obj - 0x20, reg, son, value);}else { return false; }//===2 get_幀===================#region get_ValueVCI_CAN_OBJ[] obj = new VCI_CAN_OBJ[2000];// 創芯科技CAN分析儀最大支持2000幀接收,廣成10239幀Rx13 = new byte[13];// 提取數據幀DelaySecond(0.010);//10ms // USB速度3~5msint num = Get_Receive(ref obj);busy = false;if (num > 0)// 數據幀{for (int i = num - 1; i >= 0; i--){if (obj[i].ID == 0x580 + Address && obj[i].Data[0] == 0x60)// SDO 600h+的回信【580h+】{// 580h+從站地址 回幀return true;}// SDO應答幀(580h+)}}#endregionRegion_Obj = 0x80;// 故障return false;}