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

📄 main.c

📁 modbus的c语言版本应用于dos下
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
*
* (c) 2004 by BECK IPC GmbH
*
*******************************************************************************
*
* Module:   main.c
*
* Function: This program provides a serial modbus rtu client example for SC12/DK40 or
*           SC13/DK50 or DK60/SC1x3.
*
*           It shall be used to communicate via RS232 or RS485 with another IPC@CHIP,
*           which runs the modbus server example mb_ser_s.exe.
*           A small simple function menue provides testing of the different modbus function types.
*
*           The application programmer shall use the implemented  basic modbus rtu client
*           functions for his own modbus client application.
*           For understanding the source code and using it for own application the
*           following demands are required:
*           1. Good knowledge about the modbus protocol
*           2. Careful reading and understanding of this example program
*
*           Required hardware/software for testing:
*           1. DK60/SC1x3,DK50/SC13 or DK40/SC12 as modbus rtu master(client), running this program
*           2. DK60/SC1x3,DK50/SC13 or DK40/SC12 as modbus rtu slave(server), running the program mb_slv.exe
*           3. All targets must be connected via RS232 nullmodem cable or RS485 connection
*
*           The implementation based on the follwing documents from modbus.org
*           Please note: The server uses only a subset of the specified modbus features
*           1. Modbus over serial line Specification & Implementation V1.0
*           2. Modbus application protocol specification V1.1
*
*           Main files of this project:
*           1. Modbus.h  :  Contains several modbus specific defines and size
*           2. Main.c    :  Contains a small menue for sending several different
*                           modbus requests to a slave for demonstrating the usage
*                           of the different modbus request types, implemented at
*                           mb_ser.c .
*           3. mb_mst.c:  Contains the modbus client initialzation (serial port settings),
*                           implementation of different modbus rtu  request types.
*                           Supported functions: 1h,2h,3h,4h,5h,6h,Fh,10h,2Bh(only in parts)
*
*            Program parameters:
*            Usage   : mb_mst   port  baudrate   parity   ser_mode
*            Port    : serial port  0: EXT      1: COM
*            Parity  : serial parity settings:  0: None    1: Odd     2: Even
*            Ser_Mode: serial mode: 0: RS232 with RTS/CTS flow
*                                   1: RS232 no flowctrl
*                                   2: RS485
*            Example : mb_mst   1   19200   0   0
*
*
*            Please note: The recommended modbus timing specifications for
*            sending/receiving bytes/frames via the serial line are only
*            approximately implemented.
*
********************************************************************************
* Disclaimer: This program is an example and should be used as such.
*             If you wish to use this program or parts of it in your application,
*             you must validate the code yourself. BECK IPC GmbH can not be held
*             responsible for the correct functioning or coding of this example.
*******************************************************************************
*
* $Header: main.c, 3, 01.09.2005 17:13:40, Markus Bartat$
*
******************************************************************************/

/******************************************************************************
* Includes
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <mem.h>
#include <conio.h>

#include "clib.h"
#include "modbus.h"
#include "mb_mst.h"
/******************************************************************************
//Constants
******************************************************************************/
#define DKXX_REPLY_TIMEOUT  500 //wait at every request max. 500ms for reply from DKxx slave
#define MAX_OBJ_LENGTH       40
/******************************************************************************
//External vars
******************************************************************************/
extern long          baudrate;
extern unsigned char serial_mode;
extern unsigned char parity;
extern int           port;
extern unsigned char rs485;

/******************************************************************************/
//test buffers for reading/writing coils and registers
unsigned char coil_buf[MB_SER_MAX_BUF/8];
unsigned char coil_wr_buf[MB_SER_MAX_BUF/8];
unsigned int reg_buf[MB_SER_MAX_BUF/2];
unsigned int reg_wr_buf[MB_SER_MAX_BUF/2];

//test array for storing dev identification objects

unsigned char VendorName[MAX_OBJ_LENGTH];
unsigned char ProductCode[MAX_OBJ_LENGTH];
unsigned char MajorMinorRevision[MAX_OBJ_LENGTH];
unsigned char VendorURL[MAX_OBJ_LENGTH];
unsigned char ProductName[MAX_OBJ_LENGTH];
unsigned char ModelName[MAX_OBJ_LENGTH];
unsigned char ApplName[MAX_OBJ_LENGTH];


unsigned char *dev_id_data[7] = {VendorName,
                                 ProductCode,
                                 MajorMinorRevision,
                                 VendorURL,
                                 ProductName,
                                 ModelName,
                                 ApplName};
/******************************************************************************
//Program parameter usage message
******************************************************************************/
void usage(void)
{
   printf("\r\nInvalid or missing parameters!"
          "\r\nUsage   : mb_mst   port  baudrate   parity   ser_mode\r\n"
          "\r\nPort    : 0: EXT      1: COM"
          "\r\nParity  : 0: None    1: Odd     2: Even"
          "\r\nSer_Mode: 0: RS232 with RTS/CTS flow   1: RS232 no flowctrl    2: RS485\r\n"
          "\r\nExample : mb_mst   1   19200   0   0\r\n");
}
/******************************************************************************
//Reading/analyze arguments
******************************************************************************/
int parse_args(int argc, char *argv[])
{
   int result=0;
   int tmp_value;

   if(argc!=5)
   {
     result=-1;
   }
   else
   {
     //parse port
     port = atoi(argv[1]);
     if(port>1)
     {
       result=-1;
       goto END_PARSE_ARGS;
     }

     //parse baudrate
     baudrate = strtol(argv[2],NULL,10);
     if((baudrate==0) || (baudrate > 230400L))
     {
       result=-1;
       goto END_PARSE_ARGS;
     }
     //parse parity
     tmp_value = atoi(argv[3]);
     if((tmp_value < 0) || (tmp_value>2))
     {
       result=-1;
       goto END_PARSE_ARGS;
     }
     parity=(unsigned char)tmp_value;
     //parse serial mode
     tmp_value = atoi(argv[4]);
     if((tmp_value<0) || (tmp_value>2))
     {
       result=-1;
       goto END_PARSE_ARGS;
     }
     serial_mode = (unsigned char) tmp_value;
   }//elseif(argc!=5)
END_PARSE_ARGS:
   return result;
}



/******************************************************************************
* getUnsigned
*
* Reads an unsigned value from STDIN
*
* Parameters:
*  maximum - The maximum value that the user could enter
*  preset - The value that is extended to the user
*
* Result:
*  The value entered by the user or the preset value if the user simply pressed
*  return
******************************************************************************/
unsigned long getUnsigned(
                           unsigned long maximum,
                           unsigned long preset )
{
  int key,     // Key pressed by user
      length;  // Length of the current value


  // Print preset
  printf( "%lu%n", preset, &length );

  // Read cyphers until the user presses return
  do
  {
    // Get key
    key = getch();

    // Check key
    if( '0' <= key && key <= '9' &&
        preset * 10 + (unsigned int)( key - '0' ) <= maximum )  // It's a cypher and applying it doesn't exceed maximum
    {
      // Apply cypher
      preset *= 10;
      preset += (unsigned int)( key - '0' );

      printf( "%c", key );
      ++length;
    }

    // Backspace
    if( key == '\b' && length )
    {
      preset /= 10;
      printf( "\b \b" );
      --length;
    }
  }
  while( key != 13 );

  return preset;
}


/******************************************************************************
Testing "read bit values" (read coils(02) or read discrete inputs(01)
*******************************************************************************/
void read_coils(unsigned char function_code)
{
   unsigned int slave;
   unsigned int quantity;
   unsigned int address;
   unsigned char exception;
   int result,i;
   printf("\r\n\r\nRead bit values(coils), function code %d ",function_code);
   printf("\r\nEnter parameters:");
   printf("\r\nSlave   : ");
   if( ( slave = (unsigned int)getUnsigned( 247, 1 ) ) < 1 )
   {
     printf( "\r\nInvalid slave address (%u).", slave );
     return;
   }
   printf("\r\nAddress : ");
   address = (unsigned int)getUnsigned( 65535L, 0 );
   printf("\r\nQuantity: ");
   if( ( quantity = (unsigned int)getUnsigned( 2000, 1 ) ) < 1 )
   {
     printf( "\r\nInvalid quantity (%u).", quantity );
     return;
   }
   printf("\r\nSending request: Slave %02X, Address %04X, Quantity %d",
          slave,address,quantity);

   result=mb_ser_req_rd_coils( (unsigned char)slave,
                               function_code,
                               address,
                               quantity,
                               coil_buf,
                               &exception,
                               DKXX_REPLY_TIMEOUT);

   if(result==MB_ERROR)
   {
      printf("\r\nCommunication error or timeout");
   }
   else
   {
      if(exception==0)
      {
        printf("\r\nExecution sucessful\r\nCoils read from slave[address:value]:\r\n");
        for(i=address;i<quantity+address;i++)
        {
          printf("[%02d : %s] ",i,coil_buf[i]!=0?"ON":"OFF");
        }
      }
      else
      {
        printf("\r\nReceived exception code %d",exception);
      }
   }
}
/******************************************************************************
Testing "read multiple registers" (function 03 and function 04)
*******************************************************************************/
void read_multiple_registers(unsigned char function_code)
{
   unsigned int slave;
   unsigned int quantity;
   unsigned int address;
   unsigned char exception;
   int result,i;
   printf("\r\n\r\nRead multiple registers, function code %d ",function_code);
   printf("\r\nEnter parameters:");
   printf("\r\nSlave   : ");
   if( ( slave = (unsigned int)getUnsigned( 247, 1 ) ) < 1 )
   {
     printf( "\r\nInvalid slave address (%u).", slave );
     return;
   }
   printf("\r\nAddress : ");
   address = (unsigned int)getUnsigned( 65535L, 0 );
   printf("\r\nQuantity: ");
   if( ( quantity = (unsigned int)getUnsigned( 125, 1 ) ) < 1 )
   {
     printf( "\r\nInvalid quantity (%u).", quantity );
     return;
   }
   printf("\r\nSending request: Slave %02X, Address %04X, Quantity %d",
          slave,address,quantity);

   result=mb_ser_req_rd_regs( (unsigned char)slave,
                               function_code,
                               address,
                               quantity,
                               reg_buf,
                               &exception,
                               DKXX_REPLY_TIMEOUT);

   if(result==MB_ERROR)
   {
      printf("\r\nCommunication error or timeout");
   }
   else
   {
      if(exception==0)
      {
        printf("\r\nExecution sucessful\r\nRegisters read from slave[address:value]:\r\n");
        for(i=0;i<quantity;i++)
        {
          printf("[%02d : %04X] ",i,reg_buf[i]);
        }
      }
      else
      {
        printf("\r\nReceived exception code %d",exception);
      }
   }
}
/******************************************************************************
Testing "write single register" function 06
*******************************************************************************/
void write_single_register(void)
{
   unsigned int slave;
   unsigned int value;
   unsigned int address;
   unsigned char exception;
   int result;
   printf("\r\n\r\nWriting single register, function code 06 ");
   printf("\r\nEnter parameters:");
   printf("\r\nSlave   : ");
   if( ( slave = (unsigned int)getUnsigned( 247, 1 ) ) < 1 )
   {
     printf( "\r\nInvalid slave address (%u).", slave );
     return;
   }
   printf("\r\nAddress : ");
   address = (unsigned int)getUnsigned( 65535L, 0 );
   printf("\r\nValue   : ");
   value = (unsigned int)getUnsigned( 65535L, 0 );
   printf("\r\nSending request: Slave %02X, Address %04X, Value %04X",
          slave,address,value);

   result=mb_ser_req_wr_single_reg( (unsigned char)slave,
                                    address,
                                    value,
                                    &exception,
                                    DKXX_REPLY_TIMEOUT);

   if(result==MB_ERROR)
   {
      printf("\r\nCommunication error or timeout");
   }

⌨️ 快捷键说明

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