发新帖我要提问
12
返回列表
打印
[应用相关]

基于STM32的Modbus TCP多主站数据监测

[复制链接]
楼主: kzlzqi
手机看帖
扫描二维码
随时随地手机跟帖
21
kzlzqi|  楼主 | 2024-3-31 23:48 | 只看该作者 回帖奖励 |倒序浏览
//w5500驱动  参考银杏科技
/*
* FILE                                                : w5500.c
* DESCRIPTION                : This file is iCore3 files.
* Author                                        : ysloveivy
* Copyright                        :
*
* History
* --------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* --------------------
*/

//--------------------------- Include ---------------------------//

#include "spi1.h"
#include "gpio.h"
#include "spi.h"
#include "w5500.h"
#include "main.h"
#include "socket.h"

//--------------------- Function Prototype ----------------------//
static void delay(int ms);
static int initialize(void);
static int setup(SOCKET s, unsigned char protocol, unsigned short int port, unsigned char flag);
//--------------------------- Variable --------------------------//
W5500_T w5500={
        .initialize=initialize,
        .setup=setup
};
static unsigned short int local_port;
unsigned char txsize[MAX_SOCK_NUM] = {2,2,2,2,2,2,2,2};
unsigned char rxsize[MAX_SOCK_NUM] = {2,2,2,2,2,2,2,2};
static unsigned char I_STATUS[MAX_SOCK_NUM];
static unsigned short int SSIZE[MAX_SOCK_NUM];                             /**< Max Tx buffer size by each channel */
static unsigned short int RSIZE[MAX_SOCK_NUM];                             /**< Max Rx buffer size by each channel */

//--------------------------- Function --------------------------//
/*
* Name                                                : getISR
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
unsigned char getISR(unsigned char s)
{
  return I_STATUS[s];
}
/*
* Name                                                : putISR
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void putISR(unsigned char s, unsigned char val)
{
   I_STATUS[s] = val;
}
/*
* Name                                                : getIINCHIP_RxMAX
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
unsigned short int getIINCHIP_RxMAX(unsigned char s)
{
   return RSIZE[s];
}
/*
* Name                                                : getIINCHIP_TxMAX
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
unsigned short int getIINCHIP_TxMAX(unsigned char s)
{
   return SSIZE[s];
}
/*
* Name                                                : IINCHIP_CSoff
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void IINCHIP_CSoff(void)
{
        SPI1_CS_OFF;
}
/*
* Name                                                : IINCHIP_CSon
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void IINCHIP_CSon(void)
{
        SPI1_CS_ON;
}
/*
* Name                                                : IINCHIP_SpiSendData
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
unsigned char  IINCHIP_SpiSendData(unsigned char dat)
{
   return(spi1.send_data(dat));
}
/*
* Name                                                : IINCHIP_WRITE
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void IINCHIP_WRITE( unsigned long int addrbsb,  unsigned char data)
{
   SPI1_CS_OFF;
   spi1.send_data( (addrbsb & 0x00FF0000)>>16);                                // Address byte 1
   spi1.send_data( (addrbsb & 0x0000FF00)>> 8);                                // Address byte 2
   spi1.send_data( (addrbsb & 0x000000F8) + 4);                                // Data write command and Write data length 1
   spi1.send_data(data);                                                       // Data write (write 1byte data)
         SPI1_CS_ON;
}
/*
* Name                                                : IINCHIP_READ
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
unsigned char IINCHIP_READ(unsigned long int addrbsb)
{
   unsigned char data = 0;

   SPI1_CS_OFF;
   spi1.send_data( (addrbsb & 0x00FF0000)>>16);                                // Address byte 1
   spi1.send_data( (addrbsb & 0x0000FF00)>> 8);                                // Address byte 2
   spi1.send_data( (addrbsb & 0x000000F8))    ;                                // Data read command and Read data length 1
   data = spi1.send_data(0x00);                                                // Data read (read 1byte data)
         SPI1_CS_ON;

   return data;  
}
/*
* Name                                                : wiz_write_buf
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
unsigned short int wiz_write_buf(unsigned long int addrbsb,unsigned char* buf,unsigned short int len)
{
         unsigned short int idx = 0;
         
   SPI1_CS_OFF;
   spi1.send_data( (addrbsb & 0x00FF0000)>>16);                                // Address byte 1
   spi1.send_data( (addrbsb & 0x0000FF00)>> 8);                                // Address byte 2
   spi1.send_data( (addrbsb & 0x000000F8) + 4);                                // Data write command and Write data length 1
   for(idx = 0; idx < len; idx++)                                              // Write data in loop
   {
     spi1.send_data(buf[idx]);
   }
         SPI1_CS_ON;
   return len;
}
/*
* Name                                                : wiz_read_buf
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
unsigned short int wiz_read_buf(unsigned long int addrbsb, unsigned char* buf,unsigned short int len)
{
  unsigned short int idx = 0;

  SPI1_CS_OFF;
        spi1.send_data( (addrbsb & 0x00FF0000)>>16);                                 // Address byte 1
  spi1.send_data( (addrbsb & 0x0000FF00)>> 8);                                 // Address byte 2
  spi1.send_data( (addrbsb & 0x000000F8));                                     // Data write command and Write data length 1
  for(idx = 0; idx < len; idx++)                                               // Write data in loop
  {
    buf[idx] = spi1.send_data(0x00);
  }
        SPI1_CS_ON;
       
  return len;
}

/*
* Name                                                : iinchip_init
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void iinchip_init(void)
{
  setMR( MR_RST );
}
/*
* Name                                                : sysinit
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void sysinit( unsigned char * tx_size, unsigned char * rx_size  )
{
  short int i;
  short int ssum,rsum;
  ssum = 0;
  rsum = 0;

  for (i = 0 ; i < MAX_SOCK_NUM; i++)                      // Set the size, masking and base address of Tx & Rx memory by each channel
  {
                IINCHIP_WRITE( (Sn_TXMEM_SIZE(i)), tx_size[i]);
                IINCHIP_WRITE( (Sn_RXMEM_SIZE(i)), rx_size[i]);
         
    SSIZE[i] = (int16)(0);
    RSIZE[i] = (int16)(0);


    if (ssum <= 16384)
    {
         switch( tx_size[i] )
      {
      case 1:
        SSIZE[i] = (int16)(1024);
        break;
      case 2:
        SSIZE[i] = (int16)(2048);
        break;
      case 4:
        SSIZE[i] = (int16)(4096);
        break;
      case 8:
        SSIZE[i] = (int16)(8192);
        break;
      case 16:
        SSIZE[i] = (int16)(16384);
      break;
      default :
        RSIZE[i] = (int16)(2048);
        break;
      }
    }

   if (rsum <= 16384)
    {
         switch( rx_size[i] )
      {
      case 1:
        RSIZE[i] = (int16)(1024);
        break;
      case 2:
        RSIZE[i] = (int16)(2048);
        break;
      case 4:
        RSIZE[i] = (int16)(4096);
        break;
      case 8:
        RSIZE[i] = (int16)(8192);
        break;
      case 16:
        RSIZE[i] = (int16)(16384);
        break;
      default :
        RSIZE[i] = (int16)(2048);
        break;
      }
    }
    ssum += SSIZE[i];
    rsum += RSIZE[i];

  }
}

/*
* Name                                                : setGAR
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void setGAR(unsigned char * addr)
{
    wiz_write_buf(GAR0, addr, 4);
}

/*
* Name                                                : getGWIP
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void getGWIP(unsigned char * addr)
{
    wiz_read_buf(GAR0, addr, 4);
}

/*
* Name                                                : setSUBR
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void setSUBR(unsigned char * addr)
{   
    wiz_write_buf(SUBR0, addr, 4);
}
/*
* Name                                                : setSHAR
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void setSHAR(unsigned char * addr)
{
  wiz_write_buf(SHAR0, addr, 6);  
}

/*
* Name                                                : setSIPR
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void setSIPR(unsigned char * addr)
{
    wiz_write_buf(SIPR0, addr, 4);  
}
/*
* Name                                                : getGAR
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void getGAR(unsigned char * addr)
{
    wiz_read_buf(GAR0, addr, 4);
}
/*
* Name                                                : getSUBR
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void getSUBR(unsigned char * addr)
{
    wiz_read_buf(SUBR0, addr, 4);
}
/*
* Name                                                : getSHAR
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void getSHAR(unsigned char * addr)
{
    wiz_read_buf(SHAR0, addr, 6);
}
/*
* Name                                                : getSIPR
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void getSIPR(unsigned char * addr)
{
    wiz_read_buf(SIPR0, addr, 4);
}
/*
* Name                                                : setMR
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void setMR(unsigned char val)
{
  IINCHIP_WRITE(MR,val);
}
/*
* Name                                                : getIR
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
unsigned char getIR( void )
{
   return IINCHIP_READ(IR);
}
/*
* Name                                                : setRTR
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void setRTR(unsigned short int timeout)
{
  IINCHIP_WRITE(RTR0,(unsigned char)((timeout & 0xff00) >> 8));
  IINCHIP_WRITE(RTR1,(unsigned char)(timeout & 0x00ff));
}
/*
* Name                                                : setRCR
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void setRCR(unsigned char retry)
{
  IINCHIP_WRITE(WIZ_RCR,retry);
}
/*
* Name                                                : clearIR
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void clearIR(unsigned char mask)
{
  IINCHIP_WRITE(IR, ~mask | getIR() ); // must be setted 0x10.
}
/*
* Name                                                : setSn_MSS
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void setSn_MSS(SOCKET s, unsigned short int Sn_MSSR)
{
  IINCHIP_WRITE( Sn_MSSR0(s), (unsigned char)((Sn_MSSR & 0xff00) >> 8));
  IINCHIP_WRITE( Sn_MSSR1(s), (unsigned char)(Sn_MSSR & 0x00ff));
}
/*
* Name                                                : setSn_TTL
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void setSn_TTL(SOCKET s, unsigned char ttl)
{   
   IINCHIP_WRITE( Sn_TTL(s) , ttl);
}
/*
* Name                                                : getSn_IR
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
unsigned char getSn_IR(SOCKET s)
{
   return IINCHIP_READ(Sn_IR(s));
}
/*
* Name                                                : getSn_SR
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
unsigned char getSn_SR(SOCKET s)
{
   return IINCHIP_READ(Sn_SR(s));
}
/*
* Name                                                : getSn_TX_FSR
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
unsigned short int getSn_TX_FSR(SOCKET s)
{
  unsigned short int val=0,val1=0;
  do
  {
    val1 = IINCHIP_READ(Sn_TX_FSR0(s));
    val1 = (val1 << 8) + IINCHIP_READ(Sn_TX_FSR1(s));
      if (val1 != 0)
    {
        val = IINCHIP_READ(Sn_TX_FSR0(s));
        val = (val << 8) + IINCHIP_READ(Sn_TX_FSR1(s));
    }
  } while (val != val1);
   return val;
}
/*
* Name                                                : getSn_RX_RSR
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
unsigned short int getSn_RX_RSR(SOCKET s)
{
  unsigned short int val=0,val1=0;
  do
  {
    val1 = IINCHIP_READ(Sn_RX_RSR0(s));
    val1 = (val1 << 8) + IINCHIP_READ(Sn_RX_RSR1(s));
    if(val1 != 0)
    {
        val = IINCHIP_READ(Sn_RX_RSR0(s));
        val = (val << 8) + IINCHIP_READ(Sn_RX_RSR1(s));
    }
  } while (val != val1);
   return val;
}
/*
* Name                                                : send_data_processing
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void send_data_processing(SOCKET s, unsigned char *data, unsigned short int len)
{
  unsigned short int ptr = 0;
  unsigned long int addrbsb = 0;
  ptr = IINCHIP_READ( Sn_TX_WR0(s) );
  ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_TX_WR1(s));

  addrbsb = ((uint32)ptr<<8) + (s<<5) + 0x10;
  wiz_write_buf(addrbsb, data, len);

  ptr += len;
  IINCHIP_WRITE( Sn_TX_WR0(s) ,(uint8)((ptr & 0xff00) >> 8));
  IINCHIP_WRITE( Sn_TX_WR1(s),(uint8)(ptr & 0x00ff));
}
/*
* Name                                                : recv_data_processing
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void recv_data_processing(SOCKET s, unsigned char *data, unsigned short int len)
{
  unsigned short int ptr = 0;
  unsigned long int addrbsb = 0;
  
  ptr = IINCHIP_READ( Sn_RX_RD0(s) );
  ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ( Sn_RX_RD1(s) );

  addrbsb = ((uint32)ptr<<8) + (s<<5) + 0x18;
  wiz_read_buf(addrbsb, data, len);
  ptr += len;

  IINCHIP_WRITE( Sn_RX_RD0(s), (uint8)((ptr & 0xff00) >> 8));
  IINCHIP_WRITE( Sn_RX_RD1(s), (uint8)(ptr & 0x00ff));
}
/*
* Name                                                : setSn_IR
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
void setSn_IR(unsigned char s, unsigned char val)
{
    IINCHIP_WRITE(Sn_IR(s), val);
}
/*
* Name                                                : initialize
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
static int initialize(void)                                   //初始化设置
{
  unsigned char mac[6]={0x00,0x98,0xdc,0x42,0x61,0x11};
  unsigned char lip[4]={192,168,0,10};
  unsigned char sub[4]={255,255,255,0};
  unsigned char gw[4]={192,168,0,1};       
       
        delay(2000);
        while((IINCHIP_READ(PHYCFGR)& LINK)==0);                    //等待以太网连接完成
       
        setMR( MR_RST );
        delay(100);       
       
        setSHAR(mac);
        setSUBR(sub);
        setGAR(gw);
        setSIPR(lip);

  sysinit(txsize,rxsize);       
       
        setRTR(2000);                                              /*设置溢出时间值*/
        setRCR(8);                                                 /*设置最大重新发送次数*/
       
        IINCHIP_WRITE( IMR,IM_IR7 | IM_IR6);
        IINCHIP_WRITE( SIMR, S0_IMR);  
        IINCHIP_WRITE( Sn_IMR(0), IMR_SENDOK | IMR_TIMEOUT | IMR_RECV | IMR_DISCON | IMR_CON);

        return 0;
}
/*
* Name                                                : setup
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
static int setup(SOCKET s, uint8 protocol, uint16 port, uint8 flag)
{

        if(s > 7)return -1;
       
        w5500.flag[s].send_ok=1;
       
        uint8 ret;
   if (
        ((protocol&0x0F) == Sn_MR_TCP)    ||
        ((protocol&0x0F) == Sn_MR_UDP)    ||
        ((protocol&0x0F) == Sn_MR_IPRAW)  ||
        ((protocol&0x0F) == Sn_MR_MACRAW) ||
        ((protocol&0x0F) == Sn_MR_PPPOE)
      )
   {
      close(s);
      IINCHIP_WRITE(Sn_MR(s) ,protocol | flag);
      if (port != 0) {
         IINCHIP_WRITE( Sn_PORT0(s) ,(uint8)((port & 0xff00) >> 8));
         IINCHIP_WRITE( Sn_PORT1(s) ,(uint8)(port & 0x00ff));
      } else {
         local_port++;                                                      // if don't set the source port, set local_port number.
         IINCHIP_WRITE(Sn_PORT0(s) ,(uint8)((local_port & 0xff00) >> 8));
         IINCHIP_WRITE(Sn_PORT1(s) ,(uint8)(local_port & 0x00ff));
      }
      IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_OPEN);                                 // run sockinit Sn_CR

      /* wait to process the command... */
      while( IINCHIP_READ(Sn_CR(s))!= 0);                       
      /* ------- */
      ret = 1;
                        if( (IINCHIP_READ(Sn_SR(s)) & 0xff ) != SOCK_INIT){
                        IINCHIP_WRITE(Sn_CR(s), Sn_CR_CLOSE);
                        }

                        IINCHIP_WRITE(Sn_CR(s) , Sn_CR_LISTEN);
       
                        while(IINCHIP_READ(Sn_CR(s)) != 0);
       
                        if( (IINCHIP_READ(Sn_SR(s)) &0XFF )!= SOCK_LISTEN){               
                        IINCHIP_WRITE(Sn_CR(s), Sn_CR_CLOSE);                       
                        }               
   }
   else
   {
      ret = 0;
   }
   return ret;
}
/*
* Name                                                : delay
* Description                : ---
* Author                                        : ysloveivy.
*
* History
* ----------------------
* Rev                                                : 0.00
* Date                                                : 12/20/2015
*
* create.
* ----------------------
*/
static void delay(int ct) //ms
{
        int i, j;

        for (i = 0; i < ct; i++)
        {
                for (j = 0; j < 10000; j++) ;
        }
}

使用特权

评论回复
22
kzlzqi|  楼主 | 2024-3-31 23:48 | 只看该作者
//Modbus TCP代码
/*
* FILE                 : modbus_tcp.c
* DESCRIPTION          :--
* Author               : ysloveivy.
* Copyright            :
*
* History
* --------------------
* Rev                  : 1.00
* Date                 : 12/20/2015
*
* create.
* --------------------
*/
//-----------------Include files-------------------------//

#include "modbus_tcp.h"
#include "main.h"
#include "socket.h"
#include "w5500.h"

#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
//---------------------- Define ---------------------//

//---------------- Function prototype ---------------//
static char process(void);

static int mb_rsq_pdu(unsigned char *receive_buffer_temp,int cnt);
static int mb_excep_rsq_pdu(unsigned char *receive_buffer_temp,int error_code);
static int function_1(unsigned char *receive_buffer_temp);
static int function_2(unsigned char *receive_buffer_temp);
static int function_3(unsigned char *receive_buffer_temp);
static int function_4(unsigned char *receive_buffer_temp);
static int function_5(unsigned char *receive_buffer_temp,int cnt);
static int function_6(unsigned char *receive_buffer_temp,int cnt);
static int broadcast(unsigned char *receive_buffer_temp);

//---------------- varitable -----------------------//
MODBUS_TCP_T modbus_tcp = {
  .process = process,
};

char discrete_input[32] = {0x55,0x55,0x55};         
char coil[32] = {0x55,0x55,0x55};                  
char input_reg[20] = {0,1,0,2,0,3,0,4,0,5,0,6,0,7,0,8,0,9,0,10};  
char hold_reg[512] = {0};
unsigned char receive_buffer_temp[100];

//---------------- Function ------------------------//
/*
* Name                 : process
* Description          : ---
* Author               : ysloveivy.
*
* History
* ----------------------
* Rev                  : 1.00
* Date                 : 12/20/2015
*
* create.
* ----------------------
*/
static char process(void)
{
  memcpy(receive_buffer_temp,buffer,12);
  memset(buffer,0,12);
        mb_rsq_pdu(receive_buffer_temp,12);
       
  return 0;
}
/*
* Name                 : mb_rsq_pdu
* Description          : ---
* Author               : ysloveivy.
*
* History
* ----------------------
* Rev                  : 1.00
* Date                 : 12/20/2015
*
* create.
* ----------------------
*/
static int mb_rsq_pdu(unsigned char *receive_buffer_temp,int counter_temp)
{
   if(receive_buffer_temp[0 + 6] == 0x01){
     switch(receive_buffer_temp[1 + 6]){
       case 1:
               function_1(receive_buffer_temp);
               break;
       case 2:
               function_2(receive_buffer_temp);
               break;
       case 3:
               function_3(receive_buffer_temp);
               break;
       case 4:
               function_4(receive_buffer_temp);
               break;
       case 5:
               function_5(receive_buffer_temp,counter_temp);
               break;
       case 6:
               function_6(receive_buffer_temp,counter_temp);
               break;
       default :
               mb_excep_rsq_pdu(receive_buffer_temp,1);
               break;
     }
  }else if(receive_buffer_temp[0 + 6] == 0){
      broadcast(receive_buffer_temp);
    }
  return 0;
}
/*
* Name                 : function_1
* Description          : ---
* Author               : ysloveivy.
*
* History
* ----------------------
* Rev                  : 1.00
* Date                 : 12/20/2015
*
* create.
* ----------------------
*/
static int function_1(unsigned char *receive_buffer_temp)
{
  int i;
  unsigned short cnt;
  unsigned short coil_num;
  unsigned short start_address;
        int temp = 0;

  start_address = (receive_buffer_temp[2 + 6] << 8) | receive_buffer_temp[3 + 6];

  coil_num = receive_buffer_temp[4 + 6] << 8| receive_buffer_temp[5 + 6];
  
  if((start_address + coil_num) > 255){
    mb_excep_rsq_pdu(receive_buffer_temp,2);
    return 1;
  }

  receive_buffer_temp[2 + 6] = ((coil_num % 8 )? (coil_num / 8 + 1) : (coil_num / 8));
  cnt = receive_buffer_temp[2 + 6] + 5 - 2;
  if(coil_num % 8){
    if(coil_num < 8){
      for(i = 0;i < coil_num;i ++)temp |= 1 << i;
      receive_buffer_temp[3 + 6] = ((coil[start_address / 8]) >> (start_address % 8) | (coil[start_address / 8 + 1]) << (8 - (start_address % 8))) & temp;
    }else {
      for(i = 0;i < receive_buffer_temp[2 + 6] - 1;i++)receive_buffer_temp[3 + i + 6] = (coil[i + start_address / 8]) >> (start_address % 8) | (coil[i + start_address / 8 + 1]) << (8 - (start_address % 8));
      receive_buffer_temp[3 + i + 6] = (coil[i + start_address / 8] << ((8 - (coil_num % 8 - start_address % 8) % 8)) & 0xff) >> (8 - (coil_num % 8));
    }
  }else {
      for(i = 0;i < receive_buffer_temp[2 + 6];i++)receive_buffer_temp[3 + i + 6] = (coil[i + start_address / 8]) >> (start_address % 8) | (coil[i + start_address / 8 + 1]) << (8 - (start_address % 8));
  }
       
        receive_buffer_temp[4] = (cnt & 0xff00) >> 8;
        receive_buffer_temp[5] = (cnt & 0x00ff);
        cnt = cnt + 6;
  send(0,receive_buffer_temp,cnt);

  return 0;
}
/*
* Name                 : function_2
* Description          : ---
* Author               : ysloveivy.
*
* History
* ----------------------
* Rev                  : 1.00
* Date                 : 12/20/2015
*
* create.
* ----------------------
*/
static int function_2(unsigned char *receive_buffer_temp)
{
  int i;
  unsigned short cnt;
  unsigned short discrete_num;
  unsigned short start_address;
        int temp = 0;

  start_address = (receive_buffer_temp[2 + 6] << 8) | receive_buffer_temp[3 + 6];

  discrete_num = receive_buffer_temp[4 + 6] << 8| receive_buffer_temp[5 + 6];

  if((start_address + discrete_num) > 255){
    mb_excep_rsq_pdu(receive_buffer_temp,2);
    return 1;
  }

  receive_buffer_temp[2 + 6] = ((discrete_num % 8 )? (discrete_num / 8 + 1) : (discrete_num / 8));
  cnt = receive_buffer_temp[2 + 6] + 5 - 2;
  if(discrete_num % 8){
    if(discrete_num < 8){
      for(i = 0;i < discrete_num;i ++)temp |= 1 << i;
      receive_buffer_temp[3 + 6] = ((discrete_input[start_address / 8]) >> (start_address % 8) | (discrete_input[start_address / 8 + 1]) << (8 - (start_address % 8))) & temp;
    }else {
      for(i = 0;i < receive_buffer_temp[2 + 6] - 1;i++)receive_buffer_temp[3 + i + 6] = (discrete_input[i + start_address / 8]) >> (start_address % 8) | (discrete_input[i + start_address / 8 + 1]) << (8 - (start_address % 8));
      receive_buffer_temp[3 + i + 6] = (discrete_input[i + start_address / 8] << ((8 - (discrete_num % 8 - start_address % 8) % 8)) & 0xff) >> (8 - (discrete_num % 8));
    }
  }else {
      for(i = 0;i < receive_buffer_temp[2 + 6];i++)receive_buffer_temp[3 + i + 6] = (discrete_input[i + start_address / 8]) >> (start_address % 8) | (discrete_input[i + start_address / 8 + 1]) << (8 - (start_address % 8));
  }
       
        receive_buffer_temp[4] = (cnt & 0xff00) >> 8;
        receive_buffer_temp[5] = (cnt & 0x00ff);
        cnt = cnt + 6;
  send(0,receive_buffer_temp,cnt);

  return 0;
}
/*
* Name                 : function_3
* Description          : ---
* Author               : ysloveivy.
*
* History
* ----------------------
* Rev                  : 1.00
* Date                 : 12/20/2015
*
* create.
* ----------------------
*/
static int function_3(unsigned char *receive_buffer_temp)
{  
  int i;
  int cnt;
  unsigned short int start_address;

  start_address = (receive_buffer_temp[2 + 6] << 8) | receive_buffer_temp[3 + 6];

  receive_buffer_temp[2 + 6] = receive_buffer_temp[5 + 6] * 2;
  
  if(receive_buffer_temp[2 + 6] > 48){
    mb_excep_rsq_pdu(receive_buffer_temp,2);
    return 1;
  }

  if((start_address * 2 + receive_buffer_temp[2]) > 512){
    mb_excep_rsq_pdu(receive_buffer_temp,2);
    return 1;
  }

  cnt = receive_buffer_temp[2 + 6] + 5 - 2;
  for(i = 0;i < receive_buffer_temp[2 + 6];i++)receive_buffer_temp[i + 3 + 6] = hold_reg[start_address * 2 + i];

        receive_buffer_temp[4] = (cnt & 0xff00) >> 8;
        receive_buffer_temp[5] = (cnt & 0x00ff);
       
        cnt = cnt + 6;
  send(0,receive_buffer_temp,cnt);
  send(1,receive_buffer_temp,cnt);
  return 0;
}
/*
* Name                 : function_4
* Description          : ---
* Author               : ysloveivy.
*
* History
* ----------------------
* Rev                  : 1.00
* Date                 : 12/20/2015
*
* create.
* ----------------------
*/
static int function_4(unsigned char *receive_buffer_temp)
{
  int i;
  int cnt;
  unsigned short int start_address;

  start_address = (receive_buffer_temp[2 + 6] << 8) | receive_buffer_temp[3 + 6];

  receive_buffer_temp[2 + 6] = receive_buffer_temp[5 + 6] * 2;

  if((start_address * 2 + receive_buffer_temp[2 + 6]) > 20){
    mb_excep_rsq_pdu(receive_buffer_temp,2);
    return 1;
  }

  cnt = receive_buffer_temp[2] + 5 - 2;
  for(i = 0;i < receive_buffer_temp[2 + 6];i++)receive_buffer_temp[i + 3 + 6] = input_reg[start_address * 2 + i];

        receive_buffer_temp[4] = (cnt & 0xff00) >> 8;
        receive_buffer_temp[5] = (cnt & 0x00ff);
        cnt = cnt + 6;
  send(0,receive_buffer_temp,cnt);
  return 0;
}
/*
* Name                 : function_5
* Description          : ---
* Author               : ysloveivy.
*
* History
* ----------------------
* Rev                  : 1.00
* Date                 : 12/20/2015
*
* create.
* ----------------------
*/
static int function_5(unsigned char *receive_buffer_temp,int counter_temp)
{
  unsigned short start_address;

  start_address = (receive_buffer_temp[2 + 6] << 8) | receive_buffer_temp[3 + 6];

  if(start_address > 255){
    mb_excep_rsq_pdu(receive_buffer_temp,2);
    return 1;
  }

  if((receive_buffer_temp[4 + 6] == 0xff) && (receive_buffer_temp[5 + 6] == 0x00)){
     coil[(start_address / 8)] |= 1 << start_address % 8;
  }else if((receive_buffer_temp[4 + 6] == 0x00) && (receive_buffer_temp[5 + 6] == 0x00)){
     coil[(start_address / 8)] &= ~(1 << start_address % 8);
  }else {
     mb_excep_rsq_pdu(receive_buffer_temp,3);
  }

        receive_buffer_temp[4] = (6 & 0xff00) >> 8;
        receive_buffer_temp[5] = (6 & 0x00ff);
       
        send(0,receive_buffer_temp,counter_temp);
  return 0;
}
/*
* Name                 : function_6
* Description          : ---
* Author               : ysloveivy.
*
* History
* ----------------------
* Rev                  : 1.00
* Date                 : 12/20/2015
*
* create.
* ----------------------
*/
static int function_6(unsigned char *receive_buffer_temp,int counter_temp)
{
  unsigned short start_address;

  start_address = (receive_buffer_temp[2 + 6] << 8) | receive_buffer_temp[3 + 6];

  if(start_address > 255){
    mb_excep_rsq_pdu(receive_buffer_temp,2);
    return 1;
  }

  hold_reg[start_address * 2] = receive_buffer_temp[4 + 6];
  hold_reg[start_address * 2 + 1] = receive_buffer_temp[5 + 6];

        receive_buffer_temp[4] = (6 & 0xff00) >> 8;
        receive_buffer_temp[5] = (6 & 0x00ff);
  send(0,receive_buffer_temp,counter_temp);
  return 0;
}
/*
* Name                 : mb_excep_rsq_pdu
* Description          : ---
* Author               : ysloveivy.
*
* History
* ----------------------
* Rev                  : 1.00
* Date                 : 12/20/2015
*
* create.
* ----------------------
*/
static int mb_excep_rsq_pdu(unsigned char *receive_buffer_temp,int error_code)
{
   receive_buffer_temp[1 + 6] |= 0x80;
   switch(error_code) {
     case 1:
             receive_buffer_temp[2 + 6] = 1;
             break;
     case 2:
             receive_buffer_temp[2 + 6] = 2;
             break;
     case 3:
             receive_buffer_temp[2 + 6] = 3;
             break;
     case 4:
             receive_buffer_temp[2 + 6] = 4;
             break;
     default :
             break;
   }
   
               
        receive_buffer_temp[4] = (3 & 0xff00) >> 8;
        receive_buffer_temp[5] = (3 & 0x00ff);
       
        send(0,receive_buffer_temp,9);
        return 0;
}
/*
* Name                 : broadcast
* Description          : ---
* Author               : ysloveivy.
*
* History
* ----------------------
* Rev                  : 1.00
* Date                 : 12/20/2015
*
* create.
* ----------------------
*/
static int broadcast(unsigned char *receive_buffer_temp)
{
   int start_address;
   switch(receive_buffer_temp[1 + 6]){
     case 5:
             start_address = (receive_buffer_temp[2 + 6] << 8) | receive_buffer_temp[3 + 6];
             if(start_address > 255){
                return 1;
             }
             if((receive_buffer_temp[4 + 6] == 0xff) && (receive_buffer_temp[5 + 6] == 0x00)){
                coil[(start_address / 8)] |= 1 << start_address % 8;
             }else if((receive_buffer_temp[4 + 6] == 0x00) && (receive_buffer_temp[5 + 6] == 0x00)){
                coil[(start_address / 8)] &= ~(1 << start_address % 8);
             }
             break;
    case 6:       
            start_address = (receive_buffer_temp[2 + 6] << 8) | receive_buffer_temp[3 + 6];
            if(start_address > 255){
               return 1;
            }
            hold_reg[start_address * 2] = receive_buffer_temp[4 + 6];
            hold_reg[start_address * 2 + 1] = receive_buffer_temp[5 + 6];
            break;
    }
   return 0;
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则