在一个远程设备中,使用15功能码强制线圈序列中的每个线圈为 ON
或
OFF
。请求
PDU
说明了强制的线圈参考。从零开始寻址线圈。因此,寻址线圈 1
为
0
。 请求数据域的内容说明了被请求的 ON/OFF
状态。域比特位置中的逻辑“
1
”请求相应输出为 ON。域比特位置中的逻辑“
0
”请求相应输出为
OFF
。 正常响应返回功能码、起始地址和强制的线圈数量。
具体的代码实现如下所示:
void CMD_0F_Handle(u8 * Buf)
{
u16 Addr = 0;
u16 Temp = 0; //保存输出数据
u8 j = 0;
TX1_Buffer[0] = Buf[0]; //发送的设备地址
Addr = Buf[2]<<8 | Buf[3];
Temp = Buf[8]<<8 | Buf[7]; //大小端转化
if(Addr<=Ouput16_Register_Addres && Buf[0]==Device_Address)
{
if(Addr+Buf[5]<=0x0010 && Buf[5]<=0x10 && Buf[4]==0x00 && Buf[6]!=0x00)
{
TX1_Buffer[1] = Buf[1];
TX1_Buffer[2] = Buf[2];
TX1_Buffer[3] = Buf[3];
TX1_Buffer[4] = Buf[4];
TX1_Buffer[5] = Buf[5];
for(j=0;j<Buf[5];j++)
{
switch(Addr+j)
{
case Ouput1_Register_Addres:
{
if((Temp&(0x0001>>Buf[3]))==(0x0001>>Buf[3]))
Output_Value |= 0x01;
else
Output_Value &= 0xfe;
}break;
case Ouput2_Register_Addres:
{
if((Temp&(0x0002>>Buf[3]))==(0x0002>>Buf[3]))
Output_Value |= 0x02;
else
Output_Value &= 0xfd;
}break;
case Ouput3_Register_Addres:
{
if((Temp&(0x0004>>Buf[3]))==(0x0004>>Buf[3]))
Output_Value |= 0x04;
else
Output_Value &= 0xfb;
}break;
case Ouput4_Register_Addres:
{
if((Temp&(0x0008>>Buf[3]))==(0x0008>>Buf[3]))
Output_Value |= 0x08;
else
Output_Value &= 0xf7;
}break;
case Ouput5_Register_Addres:
{
if((Temp&(0x0010>>Buf[3]))==(0x0010>>Buf[3]))
Output_Value |= 0x10;
else
Output_Value &= 0xef;
}break;
case Ouput6_Register_Addres:
{
if((Temp&(0x0020>>Buf[3]))==(0x0020>>Buf[3]))
Output_Value |= 0x20;
else
Output_Value &= 0xdf;
}break;
case Ouput7_Register_Addres:
{
if((Temp&(0x0040>>Buf[3]))==(0x0040>>Buf[3]))
Output_Value |= 0x40;
else
Output_Value &= 0xbf;
}break;
case Ouput8_Register_Addres:
{
if((Temp&(0x0080>>Buf[3]))==(0x0080>>Buf[3]))
Output_Value |= 0x80;
else
Output_Value &= 0x7f;
}break;
case Ouput9_Register_Addres:
{
if((Temp&(0x0100>>Buf[3]))==(0x0100>>Buf[3]))
OutPut_Data_IO |= 0x01;
else
OutPut_Data_IO &= 0xfe;
}break;
case Ouput10_Register_Addres:
{
if((Temp&(0x0200>>Buf[3]))==(0x0200>>Buf[3]))
OutPut_Data_IO |= 0x02;
else
OutPut_Data_IO &= 0xfd;
}break;
case Ouput11_Register_Addres:
{
if((Temp&(0x0400>>Buf[3]))==(0x0400>>Buf[3]))
OutPut_Data_IO |= 0x04;
else
OutPut_Data_IO &= 0xfb;
}break;
case Ouput12_Register_Addres:
{
if((Temp&(0x0800>>Buf[3]))==(0x0800>>Buf[3]))
OutPut_Data_IO |= 0x08;
else
OutPut_Data_IO &= 0xf7;
}break;
case Ouput13_Register_Addres:
{
if((Temp&(0x1000>>Buf[3]))==(0x1000>>Buf[3]))
OutPut_Data_IO |= 0x10;
else
OutPut_Data_IO &= 0xef;
}break;
case Ouput14_Register_Addres:
{
if((Temp&(0x2000>>Buf[3]))==(0x2000>>Buf[3]))
OutPut_Data_IO |= 0x20;
else
OutPut_Data_IO &= 0xdf;
}break;
case Ouput15_Register_Addres:
{
if((Temp&(0x4000>>Buf[3]))==(0x4000>>Buf[3]))
OutPut_Data_IO |= 0x40;
else
OutPut_Data_IO &= 0xbf;
}break;
case Ouput16_Register_Addres:
{
if((Temp&(0x8000>>Buf[3]))==(0x8000>>Buf[3]))
OutPut_Data_IO |= 0x80;
else
OutPut_Data_IO &= 0x7f;
}break;
default:break;
}
}
Output_Data(OutPut_Data_IO); //高八位
SendTo595(Output_Value); //低八位
SendLegth = 6;
}
else
{
TX1_Buffer[1] = 0x8F; //功能码最高位置1
TX1_Buffer[2] = 0x03; //设置异常码为03-无效数值
SendLegth = 3;
}
}
else
{
TX1_Buffer[1] = 0x8F; //功能码最高位置1
TX1_Buffer[2] = 0x02; //设置异常码为02-无效地址
SendLegth = 3;
}
}
测试多次,非常稳定,希望对大家有帮助。