C51 COMPILER V9.56.0.0   MODBUSRTUSLAVE                                                    02/14/2025 12:21:42 PAGE 1   


C51 COMPILER V9.56.0.0, COMPILATION OF MODULE MODBUSRTUSLAVE
OBJECT MODULE PLACED IN .\Objects\ModBusRTUSlave.obj
COMPILER INVOKED BY: C:\Keil_v5\C51\BIN\C51.EXE ..\app\ModBusRTUSlave.c LARGE OPTIMIZE(8,SPEED) BROWSE INCDIR(..\bsp;..\
                    -app) DEBUG OBJECTEXTEND PRINT(.\Listings\ModBusRTUSlave.lst) TABS(2) OBJECT(.\Objects\ModBusRTUSlave.obj)

line level    source

   1          #include "ModbusRTUSlave.h"
   2          
   3          uchar ModBus_Addr=1;//本从机地址
   4          
   5          u8 *ModBus_RX_BUFF;//接收缓冲区
   6          //u16 ModBus_RX_CNT=0;//接收数据长度
   7          u8 *ModBus_TX_BUFF;//发送缓冲区
   8          //u16 ModBus_TX_CNT=0;//发送数据长度
   9          
  10          
  11          //Modbus寄存器和单片机寄存器的映射关系
  12          u8 Modbus_InputIO[38]={0};//输入开关量寄存器
  13          u8 Modbus_OutputIO[3]={0};//输出开关量寄存器
  14          u16 Modbus_HoldReg[243]={0};//保持寄存器
  15          bit HoldReg_Changed=0;
  16          u8 HoldReg_BoardId=0xFF;
  17          u8 HoldReg_Board_stationId=0xFF;
  18          u8 HoldReg_Board_addr=0xFF;
  19          u16 HoldReg_new_value;
  20          void (*SendModbusData)(uchar len);
  21          void Modbus_RTU_Init(u8* rxbuf,u8* txbuf,void (*f)(uchar len))
  22          {
  23   1        ModBus_RX_BUFF = rxbuf;
  24   1        ModBus_TX_BUFF = txbuf;
  25   1        SendModbusData=f;
  26   1      }
  27          void Set_InputIO_Value(u16 index,bit value)
  28          {
  29   1        u16 byteindex;
  30   1        u8 bitindex;
  31   1        byteindex = index / 8;
  32   1        bitindex = index % 8;
  33   1        if(value==1)
  34   1          Modbus_InputIO[byteindex] |= 1 << (bitindex);
  35   1        else
  36   1          Modbus_InputIO[byteindex] &= ~(1<< (bitindex));
  37   1      }
  38          u16 startRegAddr;
  39          u16 RegNum;
  40          u16 calCRC;
  41          void Modbus_01_Solve(void)
  42          {
  43   1              u16 ByteNum;
  44   1              u16 i;
  45   1              RegNum= (((u16)ModBus_RX_BUFF[4])<<8)|ModBus_RX_BUFF[5];//???????
  46   1              if((startRegAddr+RegNum)<=18)//?????+??????
  47   1              {
  48   2                      ModBus_TX_BUFF[0]=ModBus_RX_BUFF[0];
  49   2                      ModBus_TX_BUFF[1]=ModBus_RX_BUFF[1];
  50   2                      ByteNum=RegNum/8;//???
  51   2                      if(RegNum%8) ByteNum+=1;//????????,????+1
  52   2                      ModBus_TX_BUFF[2]=ByteNum;//?????????
  53   2                      for(i=0;i<RegNum;i++)
  54   2                      {
C51 COMPILER V9.56.0.0   MODBUSRTUSLAVE                                                    02/14/2025 12:21:42 PAGE 2   

  55   3                              if(i%8==0) ModBus_TX_BUFF[3+i/8]=0x00;
  56   3                              ModBus_TX_BUFF[3+i/8]>>=1;//?????
  57   3                              ModBus_TX_BUFF[3+i/8]|=((Modbus_OutputIO[(startRegAddr+i)/8])<<(7-(startRegAddr+i)
             -%8))&0x80;
  58   3                              if(i==RegNum-1)//?????????
  59   3                              {
  60   4                                      if(RegNum%8) ModBus_TX_BUFF[3+i/8]>>=8-(RegNum%8);//????????????,???MSB??0
  61   4                              }
  62   3                      }
  63   2                      calCRC=crc16(ModBus_TX_BUFF,ByteNum+3);
  64   2                      ModBus_TX_BUFF[ByteNum+3]=(calCRC>>8)&0xFF;
  65   2                      ModBus_TX_BUFF[ByteNum+4]=calCRC&0xFF;
  66   2                      SendModbusData(ByteNum+5);
  67   2              }
  68   1              else//?????+??????
  69   1              {
  70   2                      ModBus_TX_BUFF[0]=ModBus_RX_BUFF[0];
  71   2                      ModBus_TX_BUFF[1]=ModBus_RX_BUFF[1]|0x80;
  72   2                      ModBus_TX_BUFF[2]=0x02; //???
  73   2                      SendModbusData(3);
  74   2              }
  75   1      }
  76          void Modbus_02_Solve(void)
  77          {
  78   1          u16 ByteNum;
  79   1          u16 i;
  80   1          RegNum= (((u16)ModBus_RX_BUFF[4])<<8)|ModBus_RX_BUFF[5];//???????
  81   1          if((startRegAddr+RegNum)<=304)//?????+??????
  82   1          {
  83   2              ModBus_TX_BUFF[0]=ModBus_RX_BUFF[0];
  84   2              ModBus_TX_BUFF[1]=ModBus_RX_BUFF[1];
  85   2              ByteNum=RegNum/8;//???
  86   2              if(RegNum%8) ByteNum+=1;//????????,????+1
  87   2              ModBus_TX_BUFF[2]=ByteNum;//?????????
  88   2              for(i=0;i<RegNum;i++)
  89   2              {
  90   3                  if(i%8==0) ModBus_TX_BUFF[3+i/8]=0x00;
  91   3                  ModBus_TX_BUFF[3+i/8]>>=1;//?????
  92   3                  ModBus_TX_BUFF[3+i/8]|=(Modbus_InputIO[(startRegAddr+i)/8]<<(7-(startRegAddr+i)%8))&0x80;
  93   3                  if(i==RegNum-1)//?????????
  94   3                  {
  95   4                      if(RegNum%8) ModBus_TX_BUFF[3+i/8]>>=8-(RegNum%8);//????????????,???MSB??0
  96   4                  }
  97   3              }
  98   2              calCRC=crc16(ModBus_TX_BUFF,ByteNum+3);
  99   2              ModBus_TX_BUFF[ByteNum+3]=(calCRC>>8)&0xFF;
 100   2              ModBus_TX_BUFF[ByteNum+4]=calCRC&0xFF;
 101   2              SendModbusData(ByteNum+5);
 102   2          }
 103   1          else//?????+??????
 104   1          {
 105   2              ModBus_TX_BUFF[0]=ModBus_RX_BUFF[0];
 106   2              ModBus_TX_BUFF[1]=ModBus_RX_BUFF[1]|0x80;
 107   2              ModBus_TX_BUFF[2]=0x02; //???
 108   2              SendModbusData(3);
 109   2          }
 110   1      }
 111          //读保持寄存器
 112          void Modbus_03_Solve(void)
 113          {
 114   1              u8 i;
 115   1              RegNum= (((u16)ModBus_RX_BUFF[4])<<8)|ModBus_RX_BUFF[5];
C51 COMPILER V9.56.0.0   MODBUSRTUSLAVE                                                    02/14/2025 12:21:42 PAGE 3   

 116   1              if(RegNum>100){//长度过大，返回错误
 117   2                  ModBus_TX_BUFF[0]=ModBus_RX_BUFF[0];
 118   2                  ModBus_TX_BUFF[1]=ModBus_RX_BUFF[1]|0x80;
 119   2                  ModBus_TX_BUFF[2]=0x02; 
 120   2                  SendModbusData(3);
 121   2                  return;
 122   2              }
 123   1              if((startRegAddr+RegNum)<=243)
 124   1              {
 125   2                      ModBus_TX_BUFF[0]=ModBus_RX_BUFF[0];
 126   2                      ModBus_TX_BUFF[1]=ModBus_RX_BUFF[1];
 127   2                      ModBus_TX_BUFF[2]=RegNum*2;
 128   2                      for(i=0;i<RegNum;i++)
 129   2                      {
 130   3                              ModBus_TX_BUFF[3+i*2]=(Modbus_HoldReg[startRegAddr+i]>>8)&0xFF;//高位在前
 131   3                              ModBus_TX_BUFF[4+i*2]=Modbus_HoldReg[startRegAddr+i]&0xFF; //低位在后
 132   3                      }
 133   2                      calCRC=crc16(ModBus_TX_BUFF,RegNum*2+3);
 134   2                      ModBus_TX_BUFF[RegNum*2+4]=calCRC&0xFF;
 135   2                      ModBus_TX_BUFF[RegNum*2+3]=(calCRC>>8)&0xFF;
 136   2                      SendModbusData(RegNum*2+5);
 137   2              }
 138   1              else
 139   1              {
 140   2                      ModBus_TX_BUFF[0]=ModBus_RX_BUFF[0];
 141   2                      ModBus_TX_BUFF[1]=ModBus_RX_BUFF[1]|0x80;
 142   2                      ModBus_TX_BUFF[2]=0x02; 
 143   2                      SendModbusData(3);
 144   2              }
 145   1      }
 146          //读输入寄存器
 147          void Modbus_04_Solve(void)
 148          {
 149   1              u8 i;
 150   1              RegNum= (((u16)ModBus_RX_BUFF[4])<<8)|ModBus_RX_BUFF[5];
 151   1              if((startRegAddr+RegNum)<=19)
 152   1              {
 153   2                      ModBus_TX_BUFF[0]=ModBus_RX_BUFF[0];
 154   2                      ModBus_TX_BUFF[1]=ModBus_RX_BUFF[1];
 155   2                      ModBus_TX_BUFF[2]=RegNum*2;
 156   2                      for(i=0;i<RegNum;i++)
 157   2                      {
 158   3                              ModBus_TX_BUFF[3+i*2]=Modbus_InputIO[(startRegAddr+i)*2+1];//高位在前
 159   3                              ModBus_TX_BUFF[4+i*2]=Modbus_InputIO[(startRegAddr+i)*2]; //低位在后
 160   3                      }
 161   2                      calCRC=crc16(ModBus_TX_BUFF,RegNum*2+3);
 162   2                      ModBus_TX_BUFF[RegNum*2+4]=calCRC&0xFF;
 163   2                      ModBus_TX_BUFF[RegNum*2+3]=(calCRC>>8)&0xFF;
 164   2                      SendModbusData(RegNum*2+5);
 165   2              }
 166   1              else
 167   1              {
 168   2                      ModBus_TX_BUFF[0]=ModBus_RX_BUFF[0];
 169   2                      ModBus_TX_BUFF[1]=ModBus_RX_BUFF[1]|0x80;
 170   2                      ModBus_TX_BUFF[2]=0x02; 
 171   2                      SendModbusData(3);
 172   2              }
 173   1      }
 174          //写单个输出线圈
 175          void Modbus_05_Solve(void)
 176          {
 177   1              if(startRegAddr<18)//?????????
C51 COMPILER V9.56.0.0   MODBUSRTUSLAVE                                                    02/14/2025 12:21:42 PAGE 4   

 178   1              {
 179   2                      if((ModBus_RX_BUFF[4]==0xFF)||(ModBus_RX_BUFF[5]==0xFF)) Modbus_OutputIO[startRegAddr/8] |
             -= 0x01<<(startRegAddr%8);
 180   2                      else Modbus_OutputIO[startRegAddr/8] &= ~(0x01<<(startRegAddr%8));
 181   2                      ModBus_TX_BUFF[0]=ModBus_RX_BUFF[0];
 182   2                      ModBus_TX_BUFF[1]=ModBus_RX_BUFF[1];
 183   2                      ModBus_TX_BUFF[2]=ModBus_RX_BUFF[2];
 184   2                      ModBus_TX_BUFF[3]=ModBus_RX_BUFF[3];
 185   2                      ModBus_TX_BUFF[4]=ModBus_RX_BUFF[4];
 186   2                      ModBus_TX_BUFF[5]=ModBus_RX_BUFF[5];
 187   2                     
 188   2                      calCRC=crc16(ModBus_TX_BUFF,6);
 189   2                      ModBus_TX_BUFF[6]=(calCRC>>8)&0xFF;
 190   2                      ModBus_TX_BUFF[7]=calCRC&0xFF;
 191   2                      SendModbusData(8);
 192   2              }
 193   1              else//?????????
 194   1              {
 195   2                      ModBus_TX_BUFF[0]=ModBus_RX_BUFF[0];
 196   2                      ModBus_TX_BUFF[1]=ModBus_RX_BUFF[1]|0x80;
 197   2                      ModBus_TX_BUFF[2]=0x02; //???
 198   2                      SendModbusData(3);
 199   2              }
 200   1      }
 201          //写单个保持寄存器
 202          void Modbus_06_Solve(void)
 203          {
 204   1          if(startRegAddr<243)
 205   1          {
 206   2            HoldReg_new_value = ModBus_RX_BUFF[5];//?????
 207   2            HoldReg_new_value |= ((u16)ModBus_RX_BUFF[4])<<8;//?????
 208   2            
 209   2            ModBus_TX_BUFF[0]=ModBus_RX_BUFF[0];
 210   2            ModBus_TX_BUFF[1]=ModBus_RX_BUFF[1];
 211   2            ModBus_TX_BUFF[2]=ModBus_RX_BUFF[2];
 212   2            ModBus_TX_BUFF[3]=ModBus_RX_BUFF[3];
 213   2            ModBus_TX_BUFF[4]=ModBus_RX_BUFF[4];
 214   2            ModBus_TX_BUFF[5]=ModBus_RX_BUFF[5];
 215   2            
 216   2            calCRC=crc16(ModBus_TX_BUFF,6);
 217   2            ModBus_TX_BUFF[7]=calCRC&0xFF;
 218   2            ModBus_TX_BUFF[6]=(calCRC>>8)&0xFF;
 219   2            SendModbusData(8);
 220   2            HoldReg_Changed = 1;
 221   2            HoldReg_BoardId = startRegAddr / 81 +1;
 222   2            if((startRegAddr % 81)<11){
 223   3              HoldReg_Board_stationId = 1;
 224   3              HoldReg_Board_addr = startRegAddr % 81;
 225   3            }else{
 226   3              HoldReg_Board_stationId = ((startRegAddr % 81) - 11) / 14 + 2;
 227   3              HoldReg_Board_addr = ((startRegAddr % 81) - 11) % 14;
 228   3            }
 229   2            //HoldReg_Board_stationId = (startRegAddr % 81) / 14 +1;
 230   2            //HoldReg_Board_addr = (startRegAddr % 81) % 14;
 231   2          }
 232   1          else
 233   1          {
 234   2              ModBus_TX_BUFF[0]=ModBus_RX_BUFF[0];
 235   2              ModBus_TX_BUFF[1]=ModBus_RX_BUFF[1]|0x80;
 236   2              ModBus_TX_BUFF[2]=0x02;
 237   2              SendModbusData(3);      
 238   2          }
C51 COMPILER V9.56.0.0   MODBUSRTUSLAVE                                                    02/14/2025 12:21:42 PAGE 5   

 239   1      }
 240          //写多个保持寄存器，10H
 241          void Modbus_16_Solve(void)
 242          {
 243   1              u8 i;
 244   1              RegNum= (((u16)ModBus_RX_BUFF[4])<<8)|ModBus_RX_BUFF[5];//???????
 245   1              if((startRegAddr+RegNum)<=195)//?????+??????
 246   1              {
 247   2                      for(i=0;i<RegNum;i++)
 248   2                      {
 249   3                          Modbus_HoldReg[startRegAddr+i]=ModBus_RX_BUFF[8+i*2]; //?????
 250   3                          Modbus_HoldReg[startRegAddr+i]|=((u16)ModBus_RX_BUFF[7+i*2])<<8; //?????
 251   3                      }
 252   2                     
 253   2                      ModBus_TX_BUFF[0]=ModBus_RX_BUFF[0];
 254   2                      ModBus_TX_BUFF[1]=ModBus_RX_BUFF[1];
 255   2                      ModBus_TX_BUFF[2]=ModBus_RX_BUFF[2];
 256   2                      ModBus_TX_BUFF[3]=ModBus_RX_BUFF[3];
 257   2                      ModBus_TX_BUFF[4]=ModBus_RX_BUFF[4];
 258   2                      ModBus_TX_BUFF[5]=ModBus_RX_BUFF[5];
 259   2                     
 260   2                      calCRC=crc16(ModBus_TX_BUFF,6);
 261   2                      ModBus_TX_BUFF[7]=calCRC&0xFF;
 262   2                      ModBus_TX_BUFF[6]=(calCRC>>8)&0xFF;
 263   2                      SendModbusData(8);
 264   2              }
 265   1              else//?????+??????
 266   1              {
 267   2                      ModBus_TX_BUFF[0]=ModBus_RX_BUFF[0];
 268   2                      ModBus_TX_BUFF[1]=ModBus_RX_BUFF[1]|0x80;
 269   2                      ModBus_TX_BUFF[2]=0x02; //???
 270   2                      SendModbusData(3);
 271   2              }
 272   1      }
 273          //MODBUSRTU SLAVE服务程序，放在主循环内使用
 274          
 275          void ModBusRtuSlave_Service(u8 framelen)
 276          {
 277   1        u16 recCRC;
 278   1        u16 calCRC;
 279   1        if(ModBus_RX_BUFF[0]==ModBus_Addr)//????
 280   1        {
 281   2          if((ModBus_RX_BUFF[1]==0x01)||(ModBus_RX_BUFF[1]==0x02)|| (ModBus_RX_BUFF[1]==03) || (ModBus_RX_BUFF[1]=
             -=04) ||(ModBus_RX_BUFF[1]==0x05)|| (ModBus_RX_BUFF[1]==0x10)|| (ModBus_RX_BUFF[1]==0x06))//允许的功能码
 282   2          {
 283   3            startRegAddr=(((u16)ModBus_RX_BUFF[2])<<8)|ModBus_RX_BUFF[3];//起始地址
 284   3            calCRC=crc16(ModBus_RX_BUFF,framelen-2);//CRC计算
 285   3            recCRC=ModBus_RX_BUFF[framelen-1]|(((u16)ModBus_RX_BUFF[framelen-2])<<8);//接收到的CRC
 286   3            if(calCRC==recCRC)//CRC校验
 287   3            {
 288   4                    ///////////////////////////////////////////////////////////////////////////////////////////////////
             -//////////////////////////////////
 289   4              switch(ModBus_RX_BUFF[1])//????????????
 290   4              {       
 291   5                case 01: //读取多个输出线圈
 292   5                {
 293   6                  Modbus_01_Solve();
 294   6                  break;
 295   6                }
 296   5                case 02: //读取多个输入线圈
 297   5                {
 298   6                  Modbus_02_Solve();
C51 COMPILER V9.56.0.0   MODBUSRTUSLAVE                                                    02/14/2025 12:21:42 PAGE 6   

 299   6                  break;
 300   6                }
 301   5                case 03: //读取多个保持寄存器
 302   5                {
 303   6                  Modbus_03_Solve();
 304   6                  break;
 305   6                }
 306   5                 case 04: //读取多个输入寄存器
 307   5                {
 308   6                  Modbus_04_Solve();
 309   6                  break;
 310   6                }                                                              
 311   5                case 05: //写单个输出线圈
 312   5                {
 313   6                  Modbus_05_Solve();
 314   6                  break;
 315   6                }
 316   5                case 06: //写单个保持寄存器
 317   5                {
 318   6                  Modbus_06_Solve();
 319   6                  break;
 320   6                }
 321   5                case 16://写多个保持寄存器
 322   5                  Modbus_16_Solve();
 323   5                break;                                       
 324   5              }
 325   4                    ///////////////////////////////////////////////////////////////////////////////////////////////////
             -///////////////////////////////////
 326   4            }
 327   3            else//CRC校验失败
 328   3            {
 329   4              ModBus_TX_BUFF[0]=ModBus_RX_BUFF[0];
 330   4              ModBus_TX_BUFF[1]=ModBus_RX_BUFF[1]|0x80;
 331   4              ModBus_TX_BUFF[2]=0x04;
 332   4              SendModbusData(3);
 333   4            }                                                       
 334   3          }
 335   2          else//错误的功能码
 336   2          {
 337   3            ModBus_TX_BUFF[0]=ModBus_RX_BUFF[0];
 338   3            ModBus_TX_BUFF[1]=ModBus_RX_BUFF[1]|0x80;
 339   3            ModBus_TX_BUFF[2]=0x01;
 340   3            SendModbusData(3);
 341   3          }
 342   2        }
 343   1      }


MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =   4627    ----
   CONSTANT SIZE    =   ----    ----
   XDATA SIZE       =    548      25
   PDATA SIZE       =   ----    ----
   DATA SIZE        =   ----    ----
   IDATA SIZE       =   ----    ----
   BIT SIZE         =      1       1
END OF MODULE INFORMATION.


C51 COMPILATION COMPLETE.  0 WARNING(S),  0 ERROR(S)
