⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modbus.c

📁 富士通单片机MB90F387上实现MODBUS
💻 C
📖 第 1 页 / 共 5 页
字号:
  
    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 + -