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

📄 mb_mst.c

📁 modbus的c语言版本应用于dos下
💻 C
📖 第 1 页 / 共 3 页
字号:

  Parameters:
  port        : serial port   0:Ext 1:COM port of SC12/SC13
  baud        : baudrate
  parity      : uart parity   0: None    1: Odd     2: Even
  serial_mode : 0: RS232 with RTS/CTS flow  1: RS232 no flowctrl  2: RS485

  Return 0 : sucess
         -1: failed
*******************************************************************************/
int mb_ser_init(int port,
                long baud,
                int parity,
                unsigned char serial_mode)
{
   if(0x1954!=fossil_init(port))
   {
      return MB_ERROR;
   }
   if(-1==fossil_setbaud(port,baud,parity,8,1))
   {
      return MB_ERROR;
   }
   switch(serial_mode)
   {
      case MB_RS485:
              fossil_set_rs485(port, FOSSIL_RS485_HIGHACTIVE);
              rs485=1; //set flag
              break;
      case MB_RS232_HWFLOW:
              fossil_set_flowcontrol (port, FOSSIL_FLOWCTRL_RTSCTS  );
              break;

   }
   /* Calculate the silent_interval
      Please note: The modbus serial specification recommends a max. time interval
      of 1.5 chars between two incoming bytes inside of frame, without defining
      a tolerance of this interval. Without a very high expense (e.g. hardware timer 0),
      it is not possible to measure exactly 1,5 chars time interval:
      Because of this behaviour, we set fixed approximated silent_intervals in
      dependency of the configured baudrate.
   */
   switch(baudrate)
   {
      case 300:  silent_interval = 40; //ms
                 break;
      case 600:  silent_interval = 20; //ms
                 break;
      case 1200: silent_interval = 10; //ms
                 break;
      case 2400: silent_interval = 5; //ms
                 break;
      case 4800: silent_interval = 3; //ms
                 break;
      default:   silent_interval = 2; //ms
                 break;
   }
   frame_wait_interval = silent_interval *2;
   return NO_ERROR;
}
/*******************************************************************************
  DeInit serial port
  Shall be called the end of application
  Parameter:
  port 0:Ext 1:COM port of SC12/SC13
********************************************************************************/
void mb_ser_deinit(int port)
{
  fossil_deinit (port );
}
/***********************************************************************************
   Send a "write multiple holding registers" request 10h, and receive reply from slave

   Parameters:
   slave_addr    : input, slave address
   start_address : input, address of first register
   quantity      : input, number of registers to change
   register_data : input, user provided storage, contains register values to write
   timeout       : input, wait max. timeout ms for reply from slave
   exception     : output, contains after execution the possible occured
                   exception code or  0, if no exception has occured


   Return 0      : Sucessful, *exception has value 0 or exception code (see modbus.h)
   Return -1     : Communication error timeout
************************************************************************************/
int mb_ser_req_wr_holding_regs( unsigned char  slave_addr,
                                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 Write multiple holding registers, Code 0x10, Start %d, Quantity %d"
          ,start_address,quantity);
   #endif

   //assume no exception
   *exception=0;

   buf[0]=slave_addr;                         //set slave address
   buf[1]=MB_WR_MULTIPLE_REG;                 //insert function code
   buf[2]=(unsigned char)(start_address>>8);  //Start address hi/lo
   buf[3]=(unsigned char)start_address;
   buf[4]=(unsigned char)(quantity>>8);       //Quantity hi/lo
   buf[5]=(unsigned char)(quantity);
   buf[6]=(unsigned char)(quantity<<1);       //no of byte (quantity*2)

   for(i=0,bufindex=7;i<quantity;i++,bufindex+=2)//write register data into frame
   {
      buf[bufindex]  =(unsigned char)(register_data[i]>>8);    //hi
      buf[bufindex+1]=(unsigned char)(register_data[i]);       //lo
   }

   //append crc
   checksum=CRC16(buf,bufindex);
   buf[bufindex++]= (unsigned char)(checksum>>8);       //hi
   buf[bufindex]  = (unsigned char)(checksum);          //lo

   #ifdef MB_PRINT_FRAME
   print_mb_frame("Sending ",buf,bufindex+1);
   #endif
   //Send the frame
   if(MB_ERROR==mb_ser_send(buf,bufindex+1))
   {
      #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 code frame reply frame
   }
   return MB_NO_ERROR;
}
/******************************************************************************
   Send a "write single holding register" request 6 and receive reply from slave

   Parameters:
   slave_addr    : input, slave address
   start_address : input, address of first register
   register_data : input, 16 bit value to write
   timeout       : input, wait max. timeout ms for reply from slave
   exception     : output, contains after execution the possible occured exception code
                   or 0 , if no exception has occured

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

   #ifdef MB_SER_DEBUG
   printf("\r\nRequest Write single holding register, Code 6, Start %d, value %d"
          ,start_address,register_data);
   #endif

   *exception=0;                              //assume no exception
   buf[0]=slave_addr;                         //set slave address
   buf[1]=MB_WR_SINGLE_REG;                   //insert function code
   buf[2]=(unsigned char)(start_address>>8);  //Start address
   buf[3]=(unsigned char)start_address;
   buf[4]= (unsigned char)(register_data>>8);//register data
   buf[5]= (unsigned char)(register_data);

   //append crc
   checksum=CRC16(buf,6);
   buf[6] = (unsigned char)(checksum>>8);       //hi
   buf[7] = (unsigned char)(checksum);          //lo

   #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,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 code frame reply frame
   }
   return MB_NO_ERROR;
}
/******************************************************************************
   Send a "write single coil" request 5 and receive reply from slave

   Parameters:
   slave_addr    : input, slave address
   start_address : input, address of first register
   coil          : input, bit value to write (coil==0x00: value OFF, else ON)
   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_single_coil ( unsigned char  slave_addr,
                                unsigned int   start_address,
                                unsigned char  coil,
                                unsigned char * exception,
                                unsigned int timeout
                              )
{

   unsigned int checksum;
   unsigned char buf[MB_SER_MAX_BUF];

   #ifdef MB_SER_DEBUG
   printf("\r\nRequest Write single coil, Code 5: Start %d , value %02X"
          ,start_address,coil);
   #endif

   *exception=0;                             //assume no exception
   buf[0]=slave_addr;                        //set slave address
   buf[1]=MB_FORCE_SINGLE_COIL;              //insert function code
   buf[2]=(unsigned char)(start_address>>8); //Start address
   buf[3]=(unsigned char)start_address;
   buf[4]=(coil!=0)?0xFF:0x00;             //coil value 0xFF00 or 0x0000
   buf[5]=0x00;

   //append crc
   checksum=CRC16(buf,6);
   buf[6] = (unsigned char)(checksum>>8);       //hi
   buf[7] = (unsigned char)(checksum);          //lo

   #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,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 code from reply frame
   }
   return MB_NO_ERROR;
}
/******************************************************************************
   Send a "read coils" (01)  or "read discrete input" (02) 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 register
   coils         : output, buffer provided by user (required length: quantity)
                   after exectuion coils contains the bit values read from slave
                   coils[0] holds lowest bit value coils[quantity-1] holds highest bit value
                   coils[i]==0x00 means value OFF,  coils[i]==0xFF means value 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_rd_coils( unsigned char  slave_addr,
                         unsigned char function_code, //01 or 02
                         unsigned int  start_address,
                         unsigned int  quantity,
                         unsigned char * coils,
                         unsigned char * exception,
                         unsigned int timeout
                        )

{

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

   #ifdef MB_SER_DEBUG
   printf("\r\nRequest Read bit values, 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 items
   buf[5] = (unsigned char)(quantity);

   //append crc
   checksum=CRC16(buf,6);
   buf[6] = (unsigned char)(checksum>>8);       //hi

⌨️ 快捷键说明

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