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

📄 mb_dev.c

📁 modbus的c语言版本应用于dos下
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
*
* (c) 2004 by BECK IPC GmbH
*
*******************************************************************************
*
* Module:   mb_dev.c
* Function: General modbus server functions for read and write single/multiple
            coils or registers
*           Implemented modbus function codes: 01, 02, 05, 15, 04, 03, 06 , 43 (only in parts)
*
*           Basic functions for handle the different types of incoming
*           modbus requests. Inside of the several function handlers
*           the DK40/DK50/DK60 specific register/coil read/write functions
*           are inserted, according to the DKxx demo modbus
*           register and coil definition (see comment header at file mb_slv.c).
********************************************************************************
* 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: mb_dev.c, 3, 02.09.2005 11:06:29, Markus Bartat$
*
******************************************************************************/
/******************************************************************************
* Includes
******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <mem.h>
#include "clib.h"
#include "modbus.h"
#include "mb_dkxx.h"   //device specific include file DK40 or Dk50

/******************************************************************************
* Defines
******************************************************************************/
//#define MB_DEV_DEBUG


#define MB_DEV_OBJ_MAX_ID       7   //max. number of provided object strings
//******************************************************************************
// Object ID table (function 0x2B), Object-ID equals  array index
//******************************************************************************
char * mb_object_id_table[MB_DEV_OBJ_MAX_ID] = { "Beck IPC GmbH",   // Vendorname
                                                 "xxxxxx",          // Product code
                                                 "V1.00",           // MajorMinor revision
                                                 "www.beck-ipc.com",//Vendor url
                                                 "DKxx",            //Product name
                                                 "H01",             // Model
                                                 "IPC@CHIP DKxx modbus slave" //Appl. name
                                                };
/******************************************************************************/
//local helper function: Convert 16 Bit Big Endian to 16 Bit Little endian
/******************************************************************************/
static int near swap_int ( int w)
{
   asm mov ax,w
   asm xchg al,ah
   return _AX;
}
//******************************************************************************
// Initialize the device, must be called at start of application
// Return 0: succesful
//       -1: Device init error
//******************************************************************************
int mb_dev_init(void)
{
   //return errorcode of device specific init function
   return mb_dkxx_init();
}
//******************************************************************************
// DeInitialize the modbus device
//******************************************************************************
int mb_dev_deinit(void)
{
   //return errorcode of device specific deinit/close function
   return mb_dkxx_deinit();
}
/******************************************************************************
 Modbus device user specific "read coil function" addressed by parameter "address":
 Called by function mb_ser_process_request (mb_slv.c), if a modbus request with
 function code 01h comes in.
 At this example we call here our implemented DKxx read coil function from file mb_DKxx.c
 For own applications, the application developer must insert his own defined modbus
 coil functions, instead of the mb_dkxx_read_coil_xx functions.

 Returns the return value of the device specific function for the specified address
 or Exception 2 Illgal address
******************************************************************************/
int mb_read_coil_func(unsigned int address, unsigned char * value)
{
   switch (address)
   {
     case  0:  return mb_dkxx_read_coil_00(value);
     case  1:  return mb_dkxx_read_coil_01(value);
     case  2:  return mb_dkxx_read_coil_02(value);
     case  3:  return mb_dkxx_read_coil_03(value);
     case  4:  return mb_dkxx_read_coil_04(value);
     case  5:  return mb_dkxx_read_coil_05(value);
     case  6:  return mb_dkxx_read_coil_06(value);
     case  7:  return mb_dkxx_read_coil_07(value);
     case  8:  return mb_dkxx_read_coil_08(value);
     case  9:  return mb_dkxx_read_coil_09(value);
     case 10:  return mb_dkxx_read_coil_10(value);
     case 11:  return mb_dkxx_read_coil_11(value);
     case 12:  return mb_dkxx_read_coil_12(value);
     case 13:  return mb_dkxx_read_coil_13(value);
     case 14:  return mb_dkxx_read_coil_14(value);
     default:  return MB_ILL_DATA_ADDR ; //illegal address
   }
}
/******************************************************************************
 Modbus device user specific write coil function addressed by parameter address:
 Called by function mb_ser_process_request (mb_slv.c), if a modbus request with
 function code 05h or 0fh comes in.

 At this example we call here our implemented DKxx write coil function from file DKxx.c
 For own applications , the application developer must insert his own defined modbus
 coil functions
******************************************************************************/
int mb_write_coil_func(unsigned int address, unsigned char value)
{
   switch (address)
   {
     case  0:  return mb_dkxx_write_coil_00(value);
     case  1:  return mb_dkxx_write_coil_01(value);
     case  2:  return mb_dkxx_write_coil_02(value);
     case  3:  return mb_dkxx_write_coil_03(value);
     case  4:  return mb_dkxx_write_coil_04(value);
     case  5:  return mb_dkxx_write_coil_05(value);
     case  6:  return mb_dkxx_write_coil_06(value);
     case  7:  return mb_dkxx_write_coil_07(value);
     case  8:  return mb_dkxx_write_coil_08(value);
     case  9:  return mb_dkxx_write_coil_09(value);
     case 10:  return mb_dkxx_write_coil_10(value);
     case 11:  return mb_dkxx_write_coil_11(value);
     case 12:  return mb_dkxx_write_coil_12(value);
     case 13:  return mb_dkxx_write_coil_13(value);
     case 14:  return mb_dkxx_write_coil_14(value);
     default:  return MB_ILL_DATA_ADDR ; //illegal address
   }
}
/******************************************************************************
 Modbus device user specific read discrete input function (02) addressed by parameter address:
 Called by function mb_ser_process_request (mb_slv.c), if a modbus master request with
 function code 02h comes in.

 At this example we call here our implemented DKxx read coil function from file DKxx.c
 For own applications , the application developer must insert his own defined modbus
 read discrete input functions
 Returns the return value of the device specific function for the specified address
 or Exception 2 (Illegal address)
******************************************************************************/
int mb_read_discrete_inputs_func(unsigned int address, unsigned char * value)
{
   switch (address)
   {
     case  0:  return mb_dkxx_read_discr_inp_00(value);
     case  1:  return mb_dkxx_read_discr_inp_01(value);
     case  2:  return mb_dkxx_read_discr_inp_02(value);
     case  3:  return mb_dkxx_read_discr_inp_03(value);
     case  4:  return mb_dkxx_read_discr_inp_04(value);
     case  5:  return mb_dkxx_read_discr_inp_05(value);
     case  6:  return mb_dkxx_read_discr_inp_06(value);
     default:  return MB_ILL_DATA_ADDR ; //illegal address
   }
}
/******************************************************************************
 Modbus device user specific read holding register function addressed by parameter address:
 Called by function mb_ser_process_request (mb_slv.c), if a modbus master(client) request with
 function code 03h comes in.

 At this example we call here our implemented DKxx read holding register function from file DKxx.c
 For own applications , the application developer must insert his own defined modbus
 holding register functions.
 Returns return value of device specific function for the specified address
 or Exception 2 (Illegal address)
******************************************************************************/
int mb_read_holding_register_func(unsigned int address, unsigned int * value)
{
   switch (address)
   {
     case  0:  return mb_dkxx_read_register_00(value);
     case  1:  return mb_dkxx_read_register_01(value);
     case  2:  return mb_dkxx_read_register_02(value);
     case  3:  return mb_dkxx_read_register_03(value);
     default:  return MB_ILL_DATA_ADDR ; //illegal address
   }
}
/******************************************************************************
 Modbus device user specific write holding register function addressed by parameter address:
 Called by function mb_ser_process_request (mb_slv.c), if a modbus master(client) request with
 function code 06h or 10h comes in.

 At this example we call here our implemented DKxx write holding register function from file DKxx.c
 For own applications , the application developer must insert his own defined modbus
 holding registers functions
 Returns return value of device specific function for the specified address
 or Exception 2 (Illegal address)
******************************************************************************/
int mb_write_holding_register_func(unsigned int address, unsigned int value)
{
   switch (address)
   {
     case  0:  return mb_dkxx_write_register_00(value);
     case  1:  return mb_dkxx_write_register_01(value);
     case  2:  return mb_dkxx_write_register_02(value);
     case  3:  return mb_dkxx_write_register_03(value);
     default:  return MB_ILL_DATA_ADDR ; //illegal address
   }
}

/******************************************************************************
 Modbus device user specific read holding register function addressed by parameter address:
 Called by function mb_ser_process_request (mb_slv.c), if a modbus master(client) request with
 function code 04h comes in.

 At this example we call here our implemented DKxx read holding register function from file DKxx.c
 For own applications , the application developer must insert his own defined modbus
 holding register functions.
 Returns return value of device specific function for the specified address
 or Exception 2 (Illegal address)
******************************************************************************/
int mb_read_input_register_func(unsigned int address, unsigned int * value)
{
   switch (address)
   {
     case  0:  return mb_dkxx_read_inp_register_00(value);
     case  1:  return mb_dkxx_read_inp_register_01(value);
     case  2:  return mb_dkxx_read_inp_register_02(value);
     default:  return MB_ILL_DATA_ADDR ; //illegal address
   }
}
/******************************************************************************
   Bit access:   Called if modbus request function code == 0x01
   Handle a "multiple read coils" or read discrete input request
   Input parameters:
   start_address   : First coil address
   number_of_coils : requested quantity of coils to read
   Return 0: Sucessful
   Output parameters: the provided storage byte_count holds quantity of coils/8 (+1 if remainder!= 0)
                      the provided storage coil_status holds coil bit values in the order as described
                      at the "Modbus application protocol specification V1.1" from modbus.org
   Return!=0 is modbus errorcode (see modbus.h)
******************************************************************************/
int mb_read_coils(unsigned int start_address,
                  unsigned int number_of_coils,
                  unsigned char * byte_count,
                  unsigned char * coil_status )
{

    int i;
    int  retval;
    unsigned char coil_tmp,shift,byte_count_tmp;

    #ifdef MB_DEV_DEBUG
    printf("\r\nRead coils: start %d quantity %d",start_address, number_of_coils);
    #endif

    /*
      Read coils from the device
      If the application requires no interruption during the following read coil loop,
      insert here semaphore protection or  disable interrupts
    */
    *byte_count = number_of_coils / 8;
    if(number_of_coils % 8)
    {
      (*byte_count)++;
    }
    //Preset coil status buffer with zeros
    memset(coil_status,0,*byte_count);
    for(i=shift=byte_count_tmp=0;i<number_of_coils;i++)
    {

      retval = mb_read_coil_func(start_address + i,&coil_tmp);
      if(retval == MB_NO_ERROR)
      {
        if(coil_tmp)
        {
          coil_status[byte_count_tmp]|= 1<<shift;
        }
        shift++;
        if(shift==8)
        {
          byte_count_tmp++;
          shift=0;
        }
      }
      else
      {
        break;
      }
    }
    //Enable interupts or release semaphore here, if they were used above the read loop

    #ifdef MB_DEV_DEBUG
    printf("\r\nRead coils: Return %d ",retval);
    if(retval==MB_NO_ERROR)
    {
       printf("\r\nCoil_status: ");
       for(i=0;i<*byte_count;i++)
       {
          printf("%02X ",coil_status[i]);
       }
    }
    #endif
    return retval;
}
/******************************************************************************
   Bit access:   Called if modbus request function code == 0x02
   Handle a "read discrete input request"
   Input parameters:
   start_address   : address of the first dicrete input
   number_of_inputs: quantity of inputs to read
   Return 0: Sucessful
   Output parameters: the provided storage byte_count holds quantity of coils/8 (+1 if remainder!= 0)
                      the provided storage input_status holds input bit values in the order as described
                      at the "Modbus application protocol specification V1.1" from modbus.org
   Return!=0 is modbus errorcode (see modbus.h)
******************************************************************************/
int mb_read_discrete_inputs(unsigned int start_address,
                            unsigned int number_of_inputs,
                            unsigned char * byte_count,
                            unsigned char * input_status )
{

    int i;
    int retval;
    unsigned char input_tmp,shift,byte_count_tmp;

    #ifdef MB_DEV_DEBUG
    printf("\r\nRead discrete inputs: start %d quantity %d",start_address, number_of_inputs);
    #endif
    /*
      Read discrete inputs from the device
      If the application requires no interruption during the following read coil loop,
      insert here semaphore protection or  disable interrupts
    */
    *byte_count = number_of_inputs / 8;
    if(number_of_inputs % 8)
    {
      (*byte_count)++;
    }
    //Preset coil status buffer with zeros

⌨️ 快捷键说明

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