报文设置扩展
This commit is contained in:
@@ -185,6 +185,7 @@ namespace ZLGUSBCANFD
|
||||
{
|
||||
_dbcHandles[通道号] = chDbcHandle;
|
||||
_isDbcLoadedArray[通道号] = true;
|
||||
ZLGDBCParser.ParseAndLoadToDatabase(chDbcHandle, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -507,20 +508,25 @@ namespace ZLGUSBCANFD
|
||||
|
||||
#endregion
|
||||
|
||||
#region 4.1 仿同星高性能智能报文/信号控制流 (新增扩展)
|
||||
|
||||
#region 4.1 报文设置与发送 (支持智能进制转换)
|
||||
/// <summary>
|
||||
/// 设置并发送指定信号值。
|
||||
/// 设置并发送指定信号值(帧 ID 支持 string 兼容模式)。
|
||||
/// 其余未指定信号使用 DBC 中定义的初始值填充,避免总线数据被意外清零。
|
||||
/// </summary>
|
||||
/// <param name="通道号">CAN/CANFD 通道索引</param>
|
||||
/// <param name="帧ID">对应报文的帧 ID</param>
|
||||
/// <param name="帧IDStr">对应报文的帧 ID(可以是 "26"、"0x1A"、"1A")</param>
|
||||
/// <param name="信号名称">DBC 中定义的英文信号名称(不区分大小写)</param>
|
||||
/// <param name="物理值">要写入的实际物理数值</param>
|
||||
/// <param name="循环发送间隔毫秒">0 = 单次发送;>0 = 周期循环发送(单位毫秒)</param>
|
||||
/// <returns>操作是否成功</returns>
|
||||
public virtual bool 设置报文(uint 通道号, uint 帧ID, string 信号名称, double 物理值, int 循环发送间隔毫秒 = 0)
|
||||
public virtual bool 设置报文(uint 通道号, string 帧IDStr, string 信号名称, double 物理值, int 循环发送间隔毫秒 = 0)
|
||||
{
|
||||
if (!TryParseFrameId(帧IDStr, out uint 帧ID))
|
||||
{
|
||||
Console.WriteLine($"[ZLGCANFD] 设置报文失败: 无法解析的帧 ID '{帧IDStr}'");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (通道号 >= _maxChannels || _channelHandles[通道号] == IntPtr.Zero) return false;
|
||||
if (!_isDbcLoadedArray[通道号]) return false;
|
||||
if (string.IsNullOrWhiteSpace(信号名称)) return false;
|
||||
@@ -534,15 +540,21 @@ namespace ZLGUSBCANFD
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送报文:以 DBC 中所有信号的初始值作为默认值发送。
|
||||
/// 发送报文:以 DBC 中所有信号的初始值作为默认值发送(帧 ID 支持 string 兼容模式)。
|
||||
/// 如果之前调用 设置报文 保存过覆盖值,则会优先使用覆盖值。
|
||||
/// </summary>
|
||||
/// <param name="通道号">CAN/CANFD 通道索引</param>
|
||||
/// <param name="帧ID">DBC 中定义的帧 ID</param>
|
||||
/// <param name="帧IDStr">DBC 中定义的帧 ID(可以是 "26"、"0x1A"、"1A")</param>
|
||||
/// <param name="循环发送间隔毫秒">0 = 单次发送;>0 = 周期循环发送(毫秒)</param>
|
||||
/// <param name="是否使用CANFD">1 = 以 CANFD 格式发送;0 = 经典 CAN 格式</param>
|
||||
public virtual bool 发送报文(uint 通道号, uint 帧ID, int 循环发送间隔毫秒 = 0, int 是否使用CANFD = 1)
|
||||
public virtual bool 发送报文(uint 通道号, string 帧IDStr, int 循环发送间隔毫秒 = 0, int 是否使用CANFD = 1)
|
||||
{
|
||||
if (!TryParseFrameId(帧IDStr, out uint 帧ID))
|
||||
{
|
||||
Console.WriteLine($"[ZLGCANFD] 发送报文失败: 无法解析的帧 ID '{帧IDStr}'");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (通道号 >= _maxChannels || _channelHandles[通道号] == IntPtr.Zero) return false;
|
||||
if (!_isDbcLoadedArray[通道号]) return false;
|
||||
if (循环发送间隔毫秒 < 0) throw new ArgumentOutOfRangeException(nameof(循环发送间隔毫秒));
|
||||
@@ -552,10 +564,10 @@ namespace ZLGUSBCANFD
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送自定义报文(原始字节)。
|
||||
/// 发送自定义报文(原始字节,帧 ID 支持 string 兼容模式)。
|
||||
/// </summary>
|
||||
/// <param name="通道号">CAN/CANFD 通道索引</param>
|
||||
/// <param name="帧ID">帧 ID;扩展帧会自动置位 0x80000000</param>
|
||||
/// <param name="帧IDStr">帧 ID(可以是 "26"、"0x1A"、"1A");扩展帧会自动置位 0x80000000</param>
|
||||
/// <param name="原始数据">原始帧数据</param>
|
||||
/// <param name="dlcLength">数据长度;CANFD 仅允许 0-8,12,16,20,24,32,48,64</param>
|
||||
/// <param name="是否是扩展帧">是否为 29 位扩展帧</param>
|
||||
@@ -563,13 +575,19 @@ namespace ZLGUSBCANFD
|
||||
/// <param name="开启波特率加速BRS">CANFD 是否开启波特率加速</param>
|
||||
public virtual bool 发送自定义报文(
|
||||
uint 通道号,
|
||||
uint 帧ID,
|
||||
string 帧IDStr,
|
||||
byte[] 原始数据,
|
||||
byte dlcLength,
|
||||
bool 是否是扩展帧 = false,
|
||||
bool 是否是CANFD = true,
|
||||
bool 开启波特率加速BRS = true)
|
||||
{
|
||||
if (!TryParseFrameId(帧IDStr, out uint 帧ID))
|
||||
{
|
||||
Console.WriteLine($"[ZLGCANFD] 发送自定义报文失败: 无法解析的帧 ID '{帧IDStr}'");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (通道号 >= _maxChannels || _channelHandles[通道号] == IntPtr.Zero) return false;
|
||||
if (原始数据 == null) return false;
|
||||
|
||||
@@ -649,7 +667,6 @@ namespace ZLGUSBCANFD
|
||||
string signalName = Encoding.Default.GetString(signal.strName).TrimEnd('\0');
|
||||
if (!string.IsNullOrEmpty(signalName) && signal.initialValueValid != 0)
|
||||
{
|
||||
// ZDBC 文档标注 initialValue 为“原始值”,但实际按 DBC 规范这里存放的是物理值
|
||||
dict[signalName] = signal.initialValue;
|
||||
}
|
||||
}
|
||||
@@ -693,6 +710,49 @@ namespace ZLGUSBCANFD
|
||||
/// <summary>
|
||||
/// 计算物理值也需要传入对应通道,使用通道专属的DBC句柄进行计算
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// 智能解析帧 ID 字符串,兼容 10 进制、16 进制(如 "0x1A", "1A", "26")
|
||||
/// </summary>
|
||||
/// <param name="idStr">输入的帧 ID 字符串</param>
|
||||
/// <param name="frameId">解析成功后的 uint 帧 ID</param>
|
||||
/// <returns>是否解析成功</returns>
|
||||
[Browsable(false)]
|
||||
public static bool TryParseFrameId(string idStr, out uint frameId)
|
||||
{
|
||||
frameId = 0;
|
||||
if (string.IsNullOrWhiteSpace(idStr)) return false;
|
||||
|
||||
idStr = idStr.Trim();
|
||||
|
||||
try
|
||||
{
|
||||
// 1. 处理带 0x 或 0X 的标准 16 进制
|
||||
if (idStr.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
frameId = Convert.ToUInt32(idStr.Substring(2), 16);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 2. 尝试当做纯 10 进制解析(如 "26")
|
||||
if (uint.TryParse(idStr, out frameId))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// 3. 如果不是纯数字,但符合 16 进制特征(如 "1A"、"ABC"),尝试按 16 进制解析
|
||||
// 使用 System.Globalization.NumberStyles.HexNumber
|
||||
if (uint.TryParse(idStr, System.Globalization.NumberStyles.HexNumber, null, out frameId))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public ulong 物理值转原始寄存器值(uint 通道号, ZDBC.DBCSignal 信号定义, double 实际物理值)
|
||||
|
||||
Reference in New Issue
Block a user