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

📄 mb_mst.c

📁 modbus的c语言版本应用于dos下
💻 C
📖 第 1 页 / 共 3 页
字号:
   buf[7] = (unsigned char)(checksum);          //lo

   //PreSet coil buffer with 0
   memset(coils,0,quantity);

   #ifdef MB_PRINT_FRAME
   print_mb_frame("Sending ",buf,8);
   #endif
   //Send the frame
   if(MB_ERROR==mb_ser_send(buf,8))
   {
      #ifdef MB_SER_DEBUG
      printf("\r\nSend failed");
      #endif
      return MB_ERROR;
   }

   //Receive reply
   byte_count = quantity / 8;
   if(0!=(quantity % 8))
   {
     byte_count++;
   }
   if(MB_ERROR == mb_ser_recv_frame(buf,byte_count+5,timeout)) //3 byte header + 2 byte CRC + bit data
   {
      #ifdef MB_SER_DEBUG
      printf("\r\nReceive failed");
      #endif
      return MB_ERROR;
   }
   //got an exception?
   if(buf[1] & 0x80)
   {
     *exception = buf[2];
     return MB_NO_ERROR;
   }

   //Fill user provided coil buffer with values read
   for(i=shift=0,buf_index=3;i<quantity;i++)
   {
      if( (buf[buf_index] >> shift++) & 0x01)
      {
        coils[i] =0xFF;
      }
      if(shift==8)
      {
        shift=0;
        buf_index++;
      }
   }
   return MB_NO_ERROR;
}
/******************************************************************************
   Send a "write multiple coils" (0x0F) request and receive reply from slave
   Parameters:
   slave_addr    : input, slave address
   function_code : input, function code 0x01 or 0x02
   quantity      : input, number of coils to read
   start_address : input, address of first coil
   coils         : input, buffer provided by user with length: quantity
                   the user must provide each coil value in one byte of coils.
                   coils[0] must hold the value for the lowest address.
                   coils[quantity-1] must hold the value for the lowest address
                   coils[i]==0x00 means: value OFF, else ON
                   Buffer content is only valid if *exception==0!

   exception     : output, contains after execution the possible occured exception code
                   or 0 , if no exception has occured

   timeout       : input, wait max. timeout ms for reply from slave

   Return 0      : Sucessful, *exception has value 0 or exception code (see modbus.h)
   Return -1     : Communication error timeout
*******************************************************************************/
int mb_ser_req_wr_coils( unsigned char  slave_addr,
                         unsigned int  start_address,
                         unsigned int  quantity,
                         unsigned char * coils,
                         unsigned char * exception,
                         unsigned int timeout
                        )

{

   unsigned int checksum,i,shift,bufindex;
   unsigned char buf[MB_SER_MAX_BUF];
   unsigned int byte_count;

   #ifdef MB_SER_DEBUG
   printf("\r\nRequest Write bit values, Code 0x0F: Start %d , Items %d"
          ,start_address,quantity);
   #endif

   *exception=0;                            //assume no exception
   buf[0]=slave_addr;                       //set slave address
   buf[1]=MB_FORCE_MULTIPLE_COIL;           //insert function code
   buf[2]=(unsigned char)(start_address>>8);//Start address
   buf[3]=(unsigned char)start_address;
   buf[4]=(unsigned char)(quantity>>8);     //Number of items
   buf[5]=(unsigned char)(quantity);
   byte_count=quantity/8;
   if(quantity%8)
   {
     byte_count++;
   }
   buf[6]=(unsigned char)byte_count;      //byte_count, quantity *2

   //PreSet send buffer from data offset 7 to end with zeros
   memset(&buf[7],0,byte_count);
   for(i=shift=0,bufindex=7;i<quantity;i++)
   {
     if(coils[i])
     {
        buf[bufindex]|=1<<shift;
     }
     shift++;
     if(shift==8)
     {
       bufindex++;
       shift=0;
     }
   }

   //append crc
   checksum=CRC16(buf,7 + byte_count);
   buf[7 + byte_count]    = (unsigned char)(checksum>>8);
   buf[7 + byte_count+ 1] = (unsigned char)(checksum);

   #ifdef MB_PRINT_FRAME
   print_mb_frame("Sending ",buf,7 + byte_count + 2);
   #endif
   //Send the frame
   if(MB_ERROR==mb_ser_send(buf,7 + byte_count + 2))
   {
      #ifdef MB_SER_DEBUG
      printf("\r\nSend failed");
      #endif
      return MB_ERROR;
   }
   //Receive reply
   if(MB_ERROR == mb_ser_recv_frame(buf,8,timeout))
   {
      #ifdef MB_SER_DEBUG
      printf("\r\nReceive failed");
      #endif
      return MB_ERROR;
   }
   //got an exception?
   if(buf[1] & 0x80)
   {
     *exception = buf[2];   //take exception from reply frame
   }
   return MB_NO_ERROR;
}
/***********************************************************************************
   Send a "read multiple registers" request 03h or "read input register" request 04,
   and receive reply from slave
   Parameters:
   slave_addr    : input, slave address
   function_code : input, function code 0x03 or 0x04
   quantity      : input, number of registers to read
   start_address : input, address of first register
   register_data : output, 16 bit buffer provided by user with min. length: quantity
                   after execution, register_data contains the read register values
                   from slave (if *exception code==0)
                   register_data[0] == value of lowest register address,
                   register_data[quantity-1] holds highest register value.
   exception     : output, contains after execution the possible occured exception code
                   or 0 , if no exception has occured
   timeout       : input, wait max. timeout ms for reply from slave

   Return 0      : Sucessful, *exception has value 0 or exception code (see modbus.h)
   Return -1     : Communication error, timeout
************************************************************************************/
int mb_ser_req_rd_regs( unsigned char  slave_addr,
                        unsigned char  function_code,
                        unsigned int   start_address,
                        unsigned int   quantity,
                        unsigned int  * register_data,
                        unsigned char * exception,
                        unsigned int timeout
                      )
{
   unsigned int checksum,i,bufindex;
   unsigned char buf[MB_SER_MAX_BUF];

   #ifdef MB_SER_DEBUG
   printf("\r\nRequest Read multiple registers code %d Start %d, items %d"
          ,function_code,start_address,quantity);
   #endif

   *exception=0;                                //assume no exception
   buf[0]=slave_addr;                           //set slave address
   buf[1] = function_code;                      //insert function code
   buf[2] = (unsigned char)(start_address>>8);  //Start address
   buf[3] = (unsigned char)start_address;
   buf[4]=(unsigned char)(quantity>>8);         //Number of registers to read
   buf[5]=(unsigned char)(quantity);
   //append crc
   checksum=CRC16(buf,6);
   buf[6]  = (unsigned char)(checksum>>8);
   buf[7]  = (unsigned char)(checksum);

   #ifdef MB_PRINT_FRAME
   print_mb_frame("Sending ",buf,8);
   #endif
   //Send the frame
   if(MB_ERROR==mb_ser_send(buf,8))
   {
      #ifdef MB_SER_DEBUG
      printf("\r\nSend failed");
      #endif
      return MB_ERROR;
   }
   //Receive reply
   if(MB_ERROR == mb_ser_recv_frame(buf,5 + quantity*2,timeout))
   {
      #ifdef MB_SER_DEBUG
      printf("\r\nReceive failed");
      #endif
      return MB_ERROR;
   }
   //got an exception?
   if(buf[1] & 0x80)
   {
     *exception = buf[2];
     return MB_NO_ERROR;
   }
   //write received register data into user provided int buffer
   for(i=0,bufindex=3;i<quantity;i++)
   {
      register_data[i]=((unsigned int)buf[bufindex]<<8) + (unsigned int)buf[bufindex+1];
      bufindex+=2;
   }
   return MB_NO_ERROR;
}
/***********************************************************************************
   Send a "read device identification request 0x2B,
   and receive reply from slave
   Parameters:
   slave_addr    : input, slave address
   id_code       : input, read device id code (01 or 02)
   obj_id        : input, object id
   obj_data      : output, field of buffers provided by user
                   after execution, obj_data contains the list of objects as null terminated strings
                   from slave (if *exception code==0)
                   The buffer array must provided by the user
   max_single_obj_length: Max. storage length of an obj_data array
   more          : output, contains after execution value 0xFF (more follows) or 0x00
                   ,if no exception has occured
   how_many      :output. contains the number of received objects
   next_id       : output, contains next object id if more==0xFF

   exception     : output, contains after execution the possible occured exception code
                   or 0 , if no exception has occured
   timeout       : input, wait max. timeout ms for reply from slave

   Return 0      : Sucessful, *exception has value 0 or exception code (see modbus.h)
   Return -1     : Communication error, timeout
************************************************************************************/
int mb_ser_req_dev_id ( unsigned char  slave_addr,
                        unsigned char  id_code,
                        unsigned char  obj_id,
                        unsigned char  *more,
                        unsigned char  *next_id,
                        unsigned char  *how_many,
                        unsigned char  *obj_data[],
                        unsigned int   max_single_obj_length,
                        unsigned char  *exception,
                        unsigned int timeout
                      )
{
   unsigned int checksum,i,bufindex;
   unsigned char buf[MB_SER_MAX_BUF];

   #ifdef MB_SER_DEBUG
   printf("\r\nRequest Read device identification ID code %d, Obj_ID %d"
          ,id_code,obj_id);
   #endif

   *more     =
   *next_id  =
   *how_many =
   *exception= 0;                                //assume no exception
   buf[0] = slave_addr;                           //set slave address
   buf[1] = MB_RD_DEV_IDENT;                    //insert function code
   buf[2] = 0x0E;                               //MEI type
   buf[3] = id_code;
   buf[4] = obj_id;
   //append crc
   checksum=CRC16(buf,5);
   buf[5]  = (unsigned char)(checksum>>8);
   buf[6]  = (unsigned char)(checksum);

   #ifdef MB_PRINT_FRAME
   print_mb_frame("Sending ",buf,7);
   #endif
   //Send the frame
   if(MB_ERROR==mb_ser_send(buf,7))
   {
      #ifdef MB_SER_DEBUG
      printf("\r\nSend failed");
      #endif
      return MB_ERROR;
   }

   //Receive reply
   if(MB_ERROR == mb_ser_recv_frame(buf,MB_SER_MAX_BUF,timeout))
   {
      #ifdef MB_SER_DEBUG
      printf("\r\nReceive failed");
      #endif
      return MB_ERROR;
   }
   //got an exception?
   if(buf[1] & 0x80)
   {
     *exception = buf[3];
     return MB_NO_ERROR;
   }
   *how_many= buf[7]; //number of objects
   *more    = buf[5]; //more follows flag
   *next_id = buf[6]; //next obj id, if *more==0xFF
   //Fill received data into obj_data
   bufindex = 8;
   for(i=0;i<*how_many;i++)
   {
      //copy object value into user provided string array
      memcpy(obj_data[i],&buf[bufindex+2],
             buf[bufindex+1]<max_single_obj_length?buf[bufindex+1]:max_single_obj_length-1);
      obj_data[i][buf[bufindex+1]]='\0'; //terminate by zero
      bufindex+=buf[bufindex+1]+2; //point to next object
   }
   return MB_NO_ERROR;
}
//*****************************************************************************
//end of file

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -