Modbus函数:包括Modbus处理函数和Modbus功能服务函数
//Modbus处理函数
void Modbus_Work(void)
{
u8 t;
if(*Flag_of_Modbus_Ok==1)
{
if(USART_RX_BUF[0]==0x03) //判断设备地址码是否正确
{
if((CRC_16(USART_RX_BUF,RS485_RX_CNT))==0x0000) //判断CRC校验是否正确
{
switch(USART_RX_BUF[1]) //根据功能码选择服务函数
{
case 0x03: //功能码03
Modbus_03_Solve();
break;
case 0x10: //功能码16
Modbus_16_Solve();
break;
default: //未定义的功能码
USART_TX_BUF[0]=0x03;
USART_TX_BUF[1]=0x80 | USART_RX_BUF[1];
USART_TX_BUF[2]=0X01;
((u16)*(USART_TX_BUF+3))=CRC_16(USART_TX_BUF,3);
RS485_Send_Data(USART_TX_BUF,5);
break;
}
}
else //CRC校验不正确
{
USART_TX_BUF[0]=0x03;
USART_TX_BUF[1]=0x80 | USART_RX_BUF[1];
USART_TX_BUF[2]=0X04;
((u16)*(USART_TX_BUF+3))=CRC_16(USART_TX_BUF,3);
RS485_Send_Data(USART_TX_BUF,5);
}
}
else memset(USART_RX_BUF,0,sizeof(USART_RX_BUF)); //非设备地址码,清除接收
RS485_RX_CNT=0;
*Flag_of_Modbus_Ok=0;
}
}
//Modbus 03功能码处理函数
void Modbus_03_Solve(void)
{
u8 t;
if((USART_RX_BUF[2]==0x00)&&(USART_RX_BUF[3]<=0xff))
{
if((USART_RX_BUF[4]==0x00)&&(USART_RX_BUF[5]<=0xff))
{
USART_TX_BUF[0]=0x03;
USART_TX_BUF[1]=0x03;
USART_TX_BUF[2]=USART_RX_BUF[5]*2 ;
for(t=0;t<(USART_TX_BUF[2]);t++)
{
USART_TX_BUF[3+t]=(t%2==0)?(work_register[USART_RX_BUF[3]+(t/2)]/256):(work_register[USART_RX_BUF[3]+(t/2)]%256);
}
((u16)*(USART_TX_BUF+(3+USART_TX_BUF[2])))=(CRC_16(USART_TX_BUF,3+USART_TX_BUF[2]));
RS485_Send_Data(USART_TX_BUF,5+USART_TX_BUF[2]);
}
else
{
USART_TX_BUF[0]=0x03;
USART_TX_BUF[1]=0x80 | USART_RX_BUF[1];
USART_TX_BUF[2]=0x02;
((u16)*(USART_TX_BUF+3))=CRC_16(USART_TX_BUF,3);
RS485_Send_Data(USART_TX_BUF,5);
}
}
else
{
USART_TX_BUF[0]=0x03;
USART_TX_BUF[1]=0x80 | USART_RX_BUF[1];
USART_TX_BUF[2]=0x02;
((u16)*(USART_TX_BUF+3))=CRC_16(USART_TX_BUF,3);
RS485_Send_Data(USART_TX_BUF,5);
}
}
//Modbus 16功能码服务函数
void Modbus_16_Solve(void)
{
u8 t;
if((USART_RX_BUF[2]==0x00)&&(USART_RX_BUF[3]<=0xff))
{
if((USART_RX_BUF[4]==0x00)&&(USART_RX_BUF[5]<=0xff))
{
for(t=0;t<USART_RX_BUF[5];t=t+2)
{
work_register[USART_RX_BUF[3]+(t/2)]=USART_RX_BUF[6+t]*256+USART_RX_BUF[7+t];
}
USART_TX_BUF[0]=0x03;
USART_TX_BUF[1]=0x10;
USART_TX_BUF[2]=USART_RX_BUF[2];
USART_TX_BUF[3]=USART_RX_BUF[3];
USART_TX_BUF[4]=USART_RX_BUF[4];
USART_TX_BUF[5]=USART_RX_BUF[5];
((u16)*(USART_TX_BUF+6))=CRC_16(USART_TX_BUF,6);
RS485_Send_Data(USART_TX_BUF,8);
}
else
{
USART_TX_BUF[0]=0x03;
USART_TX_BUF[1]=0x80 | USART_RX_BUF[1];
USART_TX_BUF[2]=0x02;
((u16)*(USART_TX_BUF+3))=CRC_16(USART_TX_BUF,3);
RS485_Send_Data(USART_TX_BUF,5);
}
}
else
{
USART_TX_BUF[0]=0x03;
USART_TX_BUF[1]=0x80 | USART_RX_BUF[1];
USART_TX_BUF[2]=0x02;
((u16)*(USART_TX_BUF+3))=CRC_16(USART_TX_BUF,3);
RS485_Send_Data(USART_TX_BUF,5);
}
}
|