C51 COMPILER V9.56.0.0   MODBUSRTUSLAVE                                                    03/14/2025 20:27:24 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 ..\source\app\ModBusRTUSlave.c LARGE OPTIMIZE(8,SPEED) BROWSE INCDIR(..\
                    -source\app;..\source\bsp) DEBUG OBJECTEXTEND PRINT(.\Listings\ModBusRTUSlave.lst) TABS(2) OBJECT(.\Objects\ModBusRTUSlav
                    -e.obj)

line level    source

   1          #include "ModbusRTUSlave.h"
   2          #include "bsp_uart.h"
   3          ui8 ModBus_Addr=3;//本从机地址
   4          extern u16 avg_advalue[14];
   5          
   6          ui8 Modbus_InputIO[2]={0};//输入开关量寄存器
   7          bit Modbus_OutputIO=0;
   8          ui16 Modbus_HoldReg[16]={0};//保持寄存器
   9          //void (*bsp_uart_send_buff)(uchar len);
  10          void Flash_EraseBlock(unsigned int fui_Address)
  11          {
  12   1        while(1)
  13   1        {
  14   2          LVDC &=~ 0x08;        //清除LVD中断标志位
  15   2          P0_0=0;   
  16   2          if((LVDC&0x08)==0)    break;
  17   2        }
  18   1        EA=0;
  19   1        INSCON =0x80; 
  20   1        IAP_CMD = 0xF00F;       //Flash解锁
  21   1        IAP_ADDR = fui_Address; //写入擦除地址
  22   1        IAP_CMD = 0xD22D;       //选择操作方式， 扇区擦除
  23   1        IAP_CMD = 0xE11E;       //触发后IAP_ADDRL&IAP_ADDRH指向0xFF，同时自动锁定
  24   1        INSCON =0x00; 
  25   1        EA=1;
  26   1      }
  27          /**
  28            * @说明   写入一个字节数据到Flash里面
  29            *         该函数需绝对地址编译，详情请查阅IAP操作应用手册
  30            * @参数   fui_Address ：FLASH地址
  31            * @参数   fucp_SaveData：写入的数据
  32            * @返回值 无
  33            * @注     写之前必须先对操作的扇区进行擦除
  34            */
  35          void FLASH_WriteData(unsigned char fuc_SaveData, unsigned int fui_Address)
  36          {
  37   1        while(1)
  38   1        {
  39   2          LVDC &=~ 0x08;         //清除LVD中断标志位
  40   2          P0_0=0;   
  41   2          if((LVDC&0x08)==0)    break;
  42   2        }
  43   1        EA=0;
  44   1        INSCON =0x80; 
  45   1        IAP_DATA = fuc_SaveData;
  46   1        IAP_CMD=0xF00F;          //Flash解锁
  47   1        IAP_ADDR = fui_Address;
  48   1        IAP_CMD=0xB44B;          //字节编程
  49   1        IAP_CMD=0xE11E;          //触发一次操作
  50   1        INSCON =0x00; 
  51   1        EA=1;
  52   1      }
  53          /**
C51 COMPILER V9.56.0.0   MODBUSRTUSLAVE                                                    03/14/2025 20:27:24 PAGE 2   

  54            * @说明   写入任意长度的数据到FLASH里面
  55            *         该函数需绝对地址编译，详情请查阅IAP操作应用手册
  56            * @参数   fui_Address ：FLASH起始地址
  57            * @参数   fuc_Length ： 写入数据长度
  58            *         取值范围：0x00-0xFF
  59            * @参数  *fucp_SaveArr：写入的数据存放区域的首地址
  60            * @返回值 无
  61            * @注     写之前必须先对操作的扇区进行擦除
  62            */
  63          void Flash_WriteArr(unsigned int fui_Address,unsigned char fuc_Length,unsigned char *fucp_SaveArr)
  64          {
  65   1        unsigned char fui_i = 0;
  66   1        EA=0;
  67   1        for(fui_i=0;fui_i<fuc_Length;fui_i++)
  68   1        {
  69   2          FLASH_WriteData(*(fucp_SaveArr++), fui_Address++); 
  70   2        }
  71   1        EA=1;
  72   1      }
  73          
  74          /**
  75            * @说明   从FLASH里面读取任意长度的数据
  76            * @参数   fui_Address ：FLASH起始地址
  77            * @参数   fuc_Length ：读取数据长度
  78            *         取值范围：0x00-0xFF
  79            * @参数  *fucp_SaveArr：读取数据存放的区域首地址
  80            * @返回值 无
  81            * @注     无
  82            */
  83          void Flash_ReadArr(unsigned int fui_Address,unsigned char fuc_Length,unsigned char *fucp_SaveArr)
  84          {
  85   1        INSCON =0x80; 
  86   1        while(fuc_Length--)
  87   1        *(fucp_SaveArr++)=*((unsigned char code *)(fui_Address++));//读取数据
  88   1        INSCON =0x00;
  89   1      }
  90          void Modbus_RTU_Init(void)//u8* rxbuf,u8* txbuf,void (*f)(uchar len)
  91          {
  92   1        u8 i=0;
  93   1      //  guc_Uartbuf = guc_Uartbuf;//rxbuf;
  94   1      //  guc_UartTxbuf = guc_UartTxbuf;//txbuf;
  95   1        //bsp_uart_send_buff=bsp_uart_send_buff;//f;
  96   1        Flash_ReadArr(0x0000,32,(u8*)Modbus_HoldReg);
  97   1        if(Modbus_HoldReg[14] !=0) ModBus_Addr=Modbus_HoldReg[14];
  98   1        for(i=0;i<14;i++)
  99   1        {
 100   2          if(Modbus_HoldReg[i] == 0) 
 101   2                Modbus_HoldReg[i]=1024;
 102   2        }
 103   1      }
 104          
 105          void Set_InputIO_Value(u16 index,bit value)
 106          {
 107   1        u8 byteindex;
 108   1        u8 bitindex;
 109   1        byteindex = index / 8;
 110   1        bitindex = index % 8;
 111   1        if(value==1)
 112   1          Modbus_InputIO[byteindex] |= 1 << (bitindex);
 113   1        else
 114   1          Modbus_InputIO[byteindex] &= ~(1<< (bitindex));
 115   1      }
C51 COMPILER V9.56.0.0   MODBUSRTUSLAVE                                                    03/14/2025 20:27:24 PAGE 3   

 116          u16 startRegAddr;
 117          u16 RegNum;
 118          u16 calCRC;
 119          
 120          void Modbus_02_Solve(void)
 121          {
 122   1          u16 ByteNum;
 123   1          u16 i;
 124   1          RegNum= (((u16)guc_Uartbuf[4])<<8)|guc_Uartbuf[5];//???????
 125   1          if((startRegAddr+RegNum)<=14)//?????+??????
 126   1          {
 127   2              guc_UartTxbuf[0]=guc_Uartbuf[0];
 128   2              guc_UartTxbuf[1]=guc_Uartbuf[1];
 129   2              ByteNum=RegNum/8;//???
 130   2              if(RegNum%8) ByteNum+=1;//????????,????+1
 131   2              guc_UartTxbuf[2]=ByteNum;//?????????
 132   2              for(i=0;i<RegNum;i++)
 133   2              {
 134   3                  if(i%8==0) guc_UartTxbuf[3+i/8]=0x00;
 135   3                  guc_UartTxbuf[3+i/8]>>=1;//?????
 136   3                  guc_UartTxbuf[3+i/8]|=(Modbus_InputIO[(startRegAddr+i)/8]<<(7-(startRegAddr+i)%8))&0x80;
 137   3                  if(i==RegNum-1)//?????????
 138   3                  {
 139   4                      if(RegNum%8) guc_UartTxbuf[3+i/8]>>=8-(RegNum%8);//????????????,???MSB??0
 140   4                  }
 141   3              }
 142   2              calCRC=crc16(guc_UartTxbuf,ByteNum+3);
 143   2              guc_UartTxbuf[ByteNum+3]=(calCRC>>8)&0xFF;
 144   2              guc_UartTxbuf[ByteNum+4]=calCRC&0xFF;
 145   2              bsp_uart_send_buff(ByteNum+5);
 146   2          }
 147   1          else//?????+??????
 148   1          {
 149   2              guc_UartTxbuf[0]=guc_Uartbuf[0];
 150   2              guc_UartTxbuf[1]=guc_Uartbuf[1]|0x80;
 151   2              guc_UartTxbuf[2]=0x02; //???
 152   2              bsp_uart_send_buff(3);
 153   2          }
 154   1      }
 155          //读保持寄存器
 156          void Modbus_03_Solve(void)
 157          {
 158   1              u8 i;
 159   1              RegNum= (((u16)guc_Uartbuf[4])<<8)|guc_Uartbuf[5];
 160   1              if((startRegAddr+RegNum)<=16)
 161   1              {
 162   2                      guc_UartTxbuf[0]=guc_Uartbuf[0];
 163   2                      guc_UartTxbuf[1]=guc_Uartbuf[1];
 164   2                      guc_UartTxbuf[2]=RegNum*2;
 165   2                      for(i=0;i<RegNum;i++)
 166   2                      {
 167   3                              guc_UartTxbuf[3+i*2]=(Modbus_HoldReg[startRegAddr+i]>>8)&0xFF;//高位在前
 168   3                              guc_UartTxbuf[4+i*2]=Modbus_HoldReg[startRegAddr+i]&0xFF; //低位在后
 169   3                      }
 170   2                      calCRC=crc16(guc_UartTxbuf,RegNum*2+3);
 171   2                      guc_UartTxbuf[RegNum*2+4]=calCRC&0xFF;
 172   2                      guc_UartTxbuf[RegNum*2+3]=(calCRC>>8)&0xFF;
 173   2                      bsp_uart_send_buff(RegNum*2+5);
 174   2              }
 175   1              else
 176   1              {
 177   2                      guc_UartTxbuf[0]=guc_Uartbuf[0];
C51 COMPILER V9.56.0.0   MODBUSRTUSLAVE                                                    03/14/2025 20:27:24 PAGE 4   

 178   2                      guc_UartTxbuf[1]=guc_Uartbuf[1]|0x80;
 179   2                      guc_UartTxbuf[2]=0x02; 
 180   2                      bsp_uart_send_buff(3);
 181   2              }
 182   1      }
 183          //写单个输出线圈
 184          void Modbus_05_Solve(void)
 185          {
 186   1        u8 i;
 187   1              if(startRegAddr==0)//?????????
 188   1              {
 189   2                      if((guc_Uartbuf[4]==0xFF)||(guc_Uartbuf[5]==0xFF)) Modbus_OutputIO=1;
 190   2                      else Modbus_OutputIO=0;
 191   2                      guc_UartTxbuf[0]=guc_Uartbuf[0];
 192   2                      guc_UartTxbuf[1]=guc_Uartbuf[1];
 193   2                      guc_UartTxbuf[2]=guc_Uartbuf[2];
 194   2                      guc_UartTxbuf[3]=guc_Uartbuf[3];
 195   2                      guc_UartTxbuf[4]=guc_Uartbuf[4];
 196   2                      guc_UartTxbuf[5]=guc_Uartbuf[5];
 197   2                      guc_UartTxbuf[6]=guc_Uartbuf[6];
 198   2                      guc_UartTxbuf[7]=guc_Uartbuf[7];
 199   2                      if(Modbus_OutputIO == 1)
 200   2                      {
 201   3                        if(ModBus_Addr == 1){
 202   4                          for(i=0;i<11;i++){
 203   5                            Modbus_HoldReg[i] = avg_advalue[i+3];
 204   5                          }
 205   4                        }else{
 206   4                          for(i=0;i<14;i++){
 207   5                            Modbus_HoldReg[i] = avg_advalue[i];
 208   5                          }
 209   4                        }
 210   3                        for(i=0;i<8;i++){
 211   4                          
 212   4                          Flash_EraseBlock((u16)(i*4));
 213   4                          Flash_WriteArr((u16)(i*4),4,(u8*)&Modbus_HoldReg[i*2]);
 214   4                        }
 215   3                      }
 216   2                      bsp_uart_send_buff(8);
 217   2              }
 218   1              else//?????????
 219   1              {
 220   2                      guc_UartTxbuf[0]=guc_Uartbuf[0];
 221   2                      guc_UartTxbuf[1]=guc_Uartbuf[1]|0x80;
 222   2                      guc_UartTxbuf[2]=0x02; //???
 223   2                      bsp_uart_send_buff(3);
 224   2              }
 225   1      }
 226          
 227          //写单个保持寄存器
 228          void Modbus_06_Solve(void)
 229          {
 230   1        u16 EEPROM_ADDR;
 231   1          if(startRegAddr<14)
 232   1          {
 233   2            Modbus_HoldReg[startRegAddr] = guc_Uartbuf[5];//?????
 234   2            Modbus_HoldReg[startRegAddr] |= ((u16)guc_Uartbuf[4])<<8;//?????
 235   2            
 236   2            guc_UartTxbuf[0]=guc_Uartbuf[0];
 237   2            guc_UartTxbuf[1]=guc_Uartbuf[1];
 238   2            guc_UartTxbuf[2]=guc_Uartbuf[2];
 239   2            guc_UartTxbuf[3]=guc_Uartbuf[3];
C51 COMPILER V9.56.0.0   MODBUSRTUSLAVE                                                    03/14/2025 20:27:24 PAGE 5   

 240   2            guc_UartTxbuf[4]=guc_Uartbuf[4];
 241   2            guc_UartTxbuf[5]=guc_Uartbuf[5];
 242   2            
 243   2            calCRC=crc16(guc_UartTxbuf,6);
 244   2            guc_UartTxbuf[7]=calCRC&0xFF;
 245   2            guc_UartTxbuf[6]=(calCRC>>8)&0xFF;
 246   2      
 247   2            EEPROM_ADDR=startRegAddr/2*4;
 248   2            Flash_EraseBlock(EEPROM_ADDR);
 249   2            Flash_WriteArr(EEPROM_ADDR,4,(u8*)&Modbus_HoldReg[startRegAddr/2*2]);
 250   2            bsp_uart_send_buff(8);
 251   2          }
 252   1      //    else if(startRegAddr == 14){
 253   1      //        ModBus_Addr = guc_Uartbuf[5];
 254   1      //        Modbus_HoldReg[14]=guc_Uartbuf[5];
 255   1      //        guc_UartTxbuf[0]=guc_Uartbuf[0];
 256   1      //        guc_UartTxbuf[1]=guc_Uartbuf[1];
 257   1      //        guc_UartTxbuf[2]=guc_Uartbuf[2];
 258   1      //        guc_UartTxbuf[3]=guc_Uartbuf[3];
 259   1      //        guc_UartTxbuf[4]=guc_Uartbuf[4];
 260   1      //        guc_UartTxbuf[5]=guc_Uartbuf[5];
 261   1      //        
 262   1      //        calCRC=crc16(guc_UartTxbuf,6);
 263   1      //        guc_UartTxbuf[7]=calCRC&0xFF;
 264   1      //        guc_UartTxbuf[6]=(calCRC>>8)&0xFF;
 265   1      
 266   1      //        EEPROM_ADDR=startRegAddr/2*4;
 267   1      //        Flash_EraseBlock(EEPROM_ADDR);
 268   1      //        Flash_WriteArr(EEPROM_ADDR,4,(u8*)&Modbus_HoldReg[startRegAddr/2*2]);
 269   1      //        bsp_uart_send_buff(8);          
 270   1      //    }
 271   1          else
 272   1          {
 273   2              guc_UartTxbuf[0]=guc_Uartbuf[0];
 274   2              guc_UartTxbuf[1]=guc_Uartbuf[1]|0x80;
 275   2              guc_UartTxbuf[2]=0x02;
 276   2              bsp_uart_send_buff(3);      
 277   2          }
 278   1      }
 279          
 280          //MODBUSRTU SLAVE服务程序，放在主循环内使用
 281          
 282          void ModBusRtuSlave_Service(u8 framelen)
 283          {
 284   1        u16 recCRC;
 285   1        u16 calCRC;
 286   1        //u16 EEPROM_ADDR;
 287   1        if(guc_Uartbuf[0]==ModBus_Addr)//???? && ModBus_Addr !=0xFF
 288   1        {
 289   2          if((guc_Uartbuf[1]==0x02)|| (guc_Uartbuf[1]==03) ||(guc_Uartbuf[1]==05) || (guc_Uartbuf[1]==0x06))//允许
             -的功能码
 290   2          {
 291   3            startRegAddr=(((u16)guc_Uartbuf[2])<<8)|guc_Uartbuf[3];//起始地址
 292   3            calCRC=crc16(guc_Uartbuf,framelen-2);//CRC计算
 293   3            recCRC=guc_Uartbuf[framelen-1]|(((u16)guc_Uartbuf[framelen-2])<<8);//接收到的CRC
 294   3            if(calCRC==recCRC)//CRC校验
 295   3            {
 296   4              //////////////////////////////////////////////////////////////////////////////////////////////////////
             -///////////////////////////////
 297   4              switch(guc_Uartbuf[1])//????????????
 298   4              {       
 299   5                case 02: //读取多个输入线圈
C51 COMPILER V9.56.0.0   MODBUSRTUSLAVE                                                    03/14/2025 20:27:24 PAGE 6   

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


MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =   1839    ----
   CONSTANT SIZE    =   ----    ----
   XDATA SIZE       =      6      21
   PDATA SIZE       =   ----    ----
   DATA SIZE        =   ----    ----
   IDATA SIZE       =     35    ----
   BIT SIZE         =      1       1
END OF MODULE INFORMATION.


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