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

📄 modbus_client.c

📁 modbus 源代码,RS485 通信,实现PC与RTU通信
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************************

Written by:  Haemish Kyd

      It is hereby certified that the author of this code specified above
      has made reference only to information that is in the public domain
      or is available to FieldServer Technologies via a duly signed
      Non-Disclosure Agreement. This code is guaranteed free and clear of
      any claim upon it by any Third Party.

      The basis for this certification includes:
         Original work performed by Eddie Hague.

   Copyright (c) 1991-2003, FieldServer Technologies.
   1991 Tarob Court, Milpitas, CA 95035, USA
   (408) 262 2299

********************************************************************************

 Versions
  1.00aA   15 Oct 04 HLK   Created
  1.00aB   09 Nov 04 HLK   Beautified and organised

*******************************************************************************/
#include <fst.h>
#include <ProtoMod.h>
#include <SIOAPI.H>

extern BYTE UART_RX_buf[MX_RX_TX_BUFFERSIZE] ; // buffer for PIC UART transmit
extern BYTE UART_TX_Buffer[MX_RX_TX_BUFFERSIZE] ;   //Transmit Buffer
extern BYTE UART_rcv_count;

extern MAP_DESC_TYP  coil_map[MX_COILS] ;
extern MAP_DESC_TYP  discrete_inputs_map[MX_DI] ;
extern MAP_DESC_TYP  register_map[MX_REG] ;

BYTE coil_write=0;
BYTE discrete_input_read=0;
BYTE register_write=0;
BYTE coil_read=0;
BYTE register_read=0;
BYTE current_node_ref;
BYTE poll_control=0;

/*============================================================================*/
// Builds the modbus message
VOID build_modbus_poll ( BYTE node_id, BYTE function, UINT16 address, INT16 amount )
{
   UINT16 crc ;

   /******************************************************************/
   /*      NODE ID TO MESSAGE                                        */
   /******************************************************************/
   UART_TX_Buffer[0]=node_id;
   /******************************************************************/
   /*      FUNCTION TO MESSAGE                                       */
   /******************************************************************/
   UART_TX_Buffer[1]=function;
   /******************************************************************/
   /*      ADDRESS TO MESSAGE HIGH THEN LOW                          */
   /******************************************************************/
   UART_TX_Buffer[2]=(BYTE)((address>>8)&0xff) ;
   UART_TX_Buffer[3]=(BYTE)((address)&0xff) ;
   /******************************************************************/
   /*      LENGTH/DATA TO MESSAGE HIGH THEN LOW                      */
   /******************************************************************/
   UART_TX_Buffer[4]=(BYTE)((amount>>8)&0xff) ;
   UART_TX_Buffer[5]=(BYTE)((amount)&0xff) ;
   /******************************************************************/
   /*      CHECKSUM TO MESSAGE  HIGH THEN LOW                        */
   /******************************************************************/
   crc = modrtuChecksum (UART_TX_Buffer, 6) ;
   UART_TX_Buffer[6]=(BYTE)((crc >> 8) & 0xff) ;
   UART_TX_Buffer[7]=(BYTE)((crc) & 0xff) ;

   current_node_ref=node_id;

   (VOID)sioapi_puts(P6720SER2,(BYTE *) UART_TX_Buffer,8);
}


/*============================================================================*/
// Prepares the read message for the message build
VOID build_and_submit_modbus_read_poll ( BYTE node_id, UINT16 address, BYTE read_type, BYTE amount )
{
   if ( amount<(BYTE)1 )
      {
      amount=1;
      }
   build_modbus_poll (node_id, read_type , (UINT16)(address-1), amount ) ;

}


/*============================================================================*/
// Prepares the write message for the message build
VOID build_and_submit_modbus_write_poll ( BYTE node_id, UINT16 address, BYTE function, INT16 write_value )
{
   if ( function == (BYTE)(MODBUS_WRITE_COIL ) )
      {

      if ( write_value == (INT16)0 )
         {
         write_value = (INT16)COIL_OFF ;
         }
      else
         {
         write_value = (INT16)COIL_ON ;
         }
      }
   build_modbus_poll (node_id, function, (UINT16)(address-1) , write_value) ;
}

/*============================================================================*/
// Sends message to be built depending on the function
VOID poll_modbus( MAP_DESC_TYP *temp_md )
{
   switch ( temp_md->function )
      {
      case MODBUS_READ_COILS:
      case MODBUS_READ_DISCRETEINPUTS:
      case MODBUS_READ_INPUTREGISTERS:
         build_and_submit_modbus_read_poll(temp_md->node_id,temp_md->address,temp_md->function,1);
         break;
      case MODBUS_WRITE_COIL:
      case MODBUS_WRITE_REGISTER:
         build_and_submit_modbus_write_poll (temp_md->node_id,temp_md->address,temp_md->function,(INT16)temp_md->data);
         break;
      default:
         break;
      }
}

/*============================================================================*/
// Checks for the next message to be sent
MAP_DESC_TYP *check_for_next_modbus_message ( VOID )
{
   BYTE  i;
   MAP_DESC_TYP *temp_md;

   RTICK:

   switch ( poll_control )
      {
      case 0 :
         /******************************************************************/
         /*      WRITE COILS                                               */
         /******************************************************************/
         for ( i = 0 ; i < (BYTE)(MX_COILS) ; i++ )
            {
            // Wrap
            if ( (BYTE)coil_write >= (BYTE)MX_COILS ) coil_write = 0 ;
            if ( coil_map[coil_write].function == (BYTE)MODBUS_WRITE_COIL )
               {
               break;
               }
            coil_write++;
            }

         if ( i==(BYTE)MX_COILS )
            {
            poll_control++;
            goto RTICK;
            }

         temp_md=&coil_map[coil_write];
         da_get_BIT(temp_md);

         temp_md->old_data=temp_md->data;
         poll_control++;

         return temp_md;
         //break;

      case 1:
         /******************************************************************/
         /*      WRITE REGISTER                                            */
         /******************************************************************/

         for ( i = 0 ; i < (BYTE)MX_REG ; i++ )
            {
            // Wrap
            if ( (BYTE)register_write >= (BYTE)MX_REG ) register_write = 0 ;
            if ( register_map[register_write].function == (BYTE)MODBUS_WRITE_REGISTER )
               {
               break;
               }
            register_write++;
            }

         if ( i==(BYTE)MX_REG )
            {
            poll_control++;
            goto RTICK;
            }

         temp_md=&register_map[register_write];
         da_get_UINT16(temp_md);
         if ( (temp_md->data&0x01)==(temp_md->old_data&0x01) )
            {
            poll_control++;
            goto RTICK;
            }
         temp_md->old_data=temp_md->data;
         poll_control++;

         return temp_md;
         //break;

      case 2 :
         /******************************************************************/
         /*      READ COILS                                                */
         /******************************************************************/

         for ( i=0; i<(BYTE)MX_COILS; i++ )
            {
            // Wrap
            if ( (BYTE)coil_read >= (BYTE)MX_COILS ) coil_read = 0 ;
            if ( coil_map[coil_read].function==(BYTE)MODBUS_READ_COILS )
               {
               break;
               }
            coil_read++;
            }

         if ( i == (BYTE)MX_COILS )
            {
            poll_control++;
            goto RTICK ;
            }

         temp_md=&coil_map[coil_read];
         poll_control++;

         return temp_md;

         //break ;

      case 3 :
         /******************************************************************/
         /*      READ DISCRETE INPUTS                                      */
         /******************************************************************/

         for ( i=0; i<(BYTE)MX_DI; i++ )
            {
            // Wrap
            if ( (BYTE)discrete_input_read >= (BYTE)MX_DI ) discrete_input_read = 0 ;
            if ( discrete_inputs_map[discrete_input_read].function==(BYTE)MODBUS_READ_DISCRETEINPUTS )
               {
               break;
               }
            discrete_input_read++;
            }

⌨️ 快捷键说明

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