📄 modbus.c
字号:
crc_tmp = *(src + fr_lenth-2); // crc 第一字节
crc_tmp = crc_tmp * 256 + *( src+fr_lenth-1); // CRC 值
crc_result = getCRC16(src, fr_lenth-2); // 计算CRC 值
if ( crc_tmp != crc_result )
{
return CRC_ERR;// CRC 校验错误
}
switch ( *(src+1) ) // 功能码
{
case READ_COIL://读取继电器状态 01
{
for ( i=0; i<*( src+2); i++)
{
shift = 1;
for ( j=0; j<8; j++)
{
*(dest+start_address+i*8+j) = shift & *( src+3);
*( src+3) >>= 1;
}
}
break;
}
case READ_DI://读取开关量输入 02
{
for ( i=0; i<*( src+2); i++)
{
shift = 1;
for (j=0; j<8; j ++)
{
*(dest+start_address+i*8+j) = shift & *( src+3);
*( src+3)>>=1;
}
}
break;
}
case READ_HLD_REGs://读取多个保持寄存器 03
{
for ( i=0; i<*( src+2); i+=2)
{
*(dest + start_address+ i/2)= *(src+i+3)*256 + *(src+i+4) ;
}
break ;
}
case READ_AI://读取模拟量输入 04
{
for ( i=0; i<*( src+2); i+=2)
{
*(dest + start_address+ i/2) = *( src+i+3)*256 + *( src+i+4) ;
}
break;
}
case SET_COIL://05强制单个线圈进行
{
break;
}
case SET_HLD_REG://06写单个寄存器
{
break;
}
case SET_COILs://15强制多个线圈进行
{
break;
}
case SET_HLD_REGs: //16写多个寄存器
{
break;
}
case READ_SET_HLD_REGs: //23读写多个寄存器
{
break;
}
default: //功能码错误
return(CMD_ERR);
break;
}
return(1);
}
/********************************************************************************************************
* 作者 :冯子龙
* 日期 :200709
* 名称 :Master_process_rtu()
* 功能 :RTU模式 接收分析
* 返回 :1,CMD_ERR
* 备注 :
*********************************************************************************************************/
char process_Slave_RTU( int *dest, uchar *src,uint start_address, uint fr_lenth)
{
uint crc_result, crc_tmp;
uchar i, j, shift;
crc_tmp = *(src + fr_lenth-2); // crc 第一字节
crc_tmp = crc_tmp * 256 + *( src+fr_lenth-1); // CRC 值
crc_result = getCRC16(src, fr_lenth-2); // 计算CRC 值
if ( crc_tmp != crc_result ) // CRC 校验错误
{
return CRC_ERR;
}
switch ( *(src+1) ) // 功能码
{
case READ_COIL://读取继电器状态 01
{
for ( i=0; i<*( src+2); i++)
{
shift = 1;
for ( j=0; j<8; j++)
{
*(dest+start_address+i*8+j) = shift & *( src+3);
*( src+3) >>= 1;
}
}
break;
}
case READ_DI://读取开关量输入 02
{
for ( i=0; i<*( src+2); i++)
{
shift = 1;
for (j=0; j<8; j ++)
{
*(dest+start_address+i*8+j) = shift & *( src+3);
*( src+3)>>=1;
}
}
break;
}
case READ_HLD_REGs://读取保持寄存器 03
{
for ( i=0; i<*( src+2); i+=2)
{
*(dest + start_address+ i/2)= *( src+i+3)*256 + *( src+i+4) ;
}
break ;
}
case READ_AI://读取模拟量输入 04
{
for ( i=0; i<*( src+2); i+=2)
{
*(dest + start_address+ i/2) = *( src+i+3)*256 + *( src+i+4) ;
}
break;
}
case SET_COIL://05强制单个线圈进行
{
break;
}
case SET_HLD_REG://06写单个寄存器
{
break;
}
case SET_COILs://15强制多个线圈进行
{
break;
}
case SET_HLD_REGs: //16写多个寄存器
{
break;
}
case READ_SET_HLD_REGs: //23读写多个寄存器
{
break;
}
default: //功能码错误
return(CMD_ERR);
break;
}
return(1);
}
/********************************************************************************************************
* 作者 :冯子龙
* 日期 :200709
* 名称 :process_Slave_ASCII()
* 功能 :ASCII模式 接收分析
* 返回 :FRM_ERR,CMD_ERR,1
* 备注 :分析结果存放在*dest中
*********************************************************************************************************/
char process_Master_ASCII( uint *dest,uchar *src,uint start_address)
{
uchar tmp[256];
uint lenth;
uint i, j;
char shift;
//将ASCII码串去除起始符和结束符后转换为二进制
lenth = ASCII2RTU(tmp,src);
if ( lenth==0) return FRM_ERR;
switch (tmp[1])//命令解析
{
case READ_COIL://01读取线圈状态
{
for ( i=0; i<tmp[2]; i++)
{
shift = 1;
for ( j=0; j<8; j++)
{
*(dest+start_address+i*8+j) = shift & tmp [i+3];
tmp [i+3] >>= 1;
}
}
break;
}
case READ_DI: //02读取开关量输入
{
for ( i=0; i<tmp[2]; i++)
{
shift = 1;
for (j=0; j<8; j ++)
{
*(dest+start_address+i*8+j)= shift & tmp [i+3];
tmp [i+3]>>=1;
}
}
break;
}
case READ_HLD_REGs://03读取保持寄存器
{
for (i=0; i<tmp[2]; i+=2)
{
*(dest + start_address+ i/2) = tmp[i+3]*256 + tmp[i+4] ;
}
break ;
}
case READ_AI://04读取模拟量输入
{
for (i=0; i<tmp[2]; i+=2)
{
*(dest+start_address+ i/2) = tmp[i+3]*256 + tmp[i+4] ;
}
break;
}
case SET_COIL://05强制单个线圈进行
{
break;
}
case SET_HLD_REG://06写单个寄存器
{
break;
}
case SET_COILs://15强制多个线圈进行
{
break;
}
case SET_HLD_REGs: //16写多个寄存器
{
break;
}
case READ_SET_HLD_REGs: //23读写多个寄存器
{
break;
}
default: //功能码错误
return(CMD_ERR);
break;
}
return(1);
}
/********************************************************************************************************
* 作者 :冯子龙
* 日期 :200709
* 名称 :process_Slave_ASCII()
* 功能 :ASCII模式 接收分析
* 返回 :FRM_ERR,CMD_ERR,1
* 备注 :分析结果存放在*dest中
*********************************************************************************************************/
char process_Slave_ASCII( uint *dest,uchar *src,uint start_address)
{
uchar tmp[256];
uint lenth;
uint i, j;
char shift;
//将ASCII码串去除起始符和结束符后转换为二进制
lenth = ASCII2RTU(tmp,src);
if ( lenth==0) return FRM_ERR;
switch (tmp[1])//命令解析
{
case READ_COIL://01读取线圈状态
{
for ( i=0; i<tmp[2]; i++)
{
shift = 1;
for ( j=0; j<8; j++)
{
*(dest+start_address+i*8+j) = shift & tmp [i+3];
tmp [i+3] >>= 1;
}
}
break;
}
case READ_DI: //02读取开关量输入
{
for ( i=0; i<tmp[2]; i++)
{
shift = 1;
for (j=0; j<8; j ++)
{
*(dest+start_address+i*8+j)= shift & tmp [i+3];
tmp [i+3]>>=1;
}
}
break;
}
case READ_HLD_REGs://03读取保持寄存器
{
for (i=0; i<tmp[2]; i+=2)
{
*(dest + start_address+ i/2) = tmp[i+3]*256 + tmp[i+4] ;
}
break ;
}
case READ_AI://04读取模拟量输入
{
for (i=0; i<tmp[2]; i+=2)
{
*(dest+start_address+ i/2) = tmp[i+3]*256 + tmp[i+4] ;
}
break;
}
case SET_COIL://05强制单个线圈进行
{
break;
}
case SET_HLD_REG://06写单个寄存器
{
break;
}
case SET_COILs://15强制多个线圈进行
{
break;
}
case SET_HLD_REGs: //16写多个寄存器
{
break;
}
case READ_SET_HLD_REGs: //23读写多个寄存器
{
break;
}
default: //功能码错误
return(CMD_ERR);
break;
}
return(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -