|
使用C51的MODBUS通讯
目前需要实现一个 04读取输入寄存器,然后有一个解析逻辑去分析这个寄存器的每一个位,实现故障码显示的功能
目前的问题有如下几个
1.if (S_H == 5 && R_OD5 == 1 && T_O5 == 0) 这个判断条件下,我的控件没有任何东西,似乎就是没接受完信息就开始解析了
2..if (S_H == 5)换成这个判断条件,会导致显示的故障信息是错误的,在这个寄存器所有位都是0的情况,还能读取到故障码,不正常
3.采用0x01的发送模式,会导致刷新很频繁,已经加了// 仅当故障值变化时更新显示if (fault_value != last_fault_value)的处理,不知道可行不可行。如果用0x04的发送模式,会导致重试两次直接失败,后续无法进行MODBUS通讯
如何合理的解决上诉问题
0x5A, 0x01, 0x04, 0x01, 0xA0, 0x01, 0x00, 0x05, 0x30, 0x00, 0x00, 0x06, //006 测试故障码
void Performance_Function()//功能函数
{
if( Sec_fang1==1)
{
Sec_fang1=0;
}
// 处理006指令(S_H==5,Modbus功能码04,读取从机0x0006寄存器)
if (S_H == 5 && R_OD5 == 1 && T_O5 == 0) {
u8 fault_buf[2] = {0, 0}; // 存储故障值的缓冲区,初始化为0
u16 fault_value;
u8 fault_str[255]; // 存储拼接的故障描述
u8 bit_pos;
bit fault_found = 0;
static u16 last_fault_value = 0xFFFF;
// 清空0x3000,避免旧数据干扰
u8 clear_buf[2] = {0, 0};
write_dgus_vp(0x3000, clear_buf, 2);
// 从0x3000读取故障值(2字节)
read_dgus_vp(0x3000, fault_buf, 2);
fault_value = (fault_buf[0] << 8) | fault_buf[1]; // 大端格式
// 仅当故障值变化时更新显示
if (fault_value != last_fault_value)
{
// 初始化字符串
fault_str[0] = '\0';
// 按位解析fault_value(16位)
for (bit_pos = 0; bit_pos < 16; bit_pos++)
{
if (fault_value & (1 << bit_pos)) // 该位为1,有故障
{
if (fault_found)
{
strcat(fault_str, ", "); // 添加分隔符
}
strcat(fault_str, fault_descriptions[bit_pos]); // 追加故障描述
fault_found = 1;
}
}
if (!fault_found)
{
strcpy(fault_str, "No Fault");
}
// 写入DGUS屏0x3000地址
str_len = strlen(fault_str) + 1; // 实际字符串长度(含\0)
if (str_len % 2 != 0) {
str_len++; // 补齐到偶数
fault_str[str_len - 1] = 0; // 补齐字节为0
}
write_dgus_vp(0x3000, fault_str, str_len);
// 更新上次故障值
last_fault_value = fault_value;
}
// 清空接收标志
R_OD5 = 0;
R_CN5 = 0;
}
}
|
|