Arduino Modbus Slave

#define bufferSize 255  //一帧数据的最大字节数量
#define baudrate 9600  //定义通讯波特率
#define slaveID 9  //定义modbus RTU从站站号
#define modbusDataSize 100  //定义modbus数据库空间大小

void setup() 
{
  // put your setup code here, to run once:
    Serial.begin(9600); 
    Serial.println("CRC-16 bit test program");
    Serial.println("=======================");
}

void loop() {
  //延时
  unsigned int characterTime;
  //数据缓冲区定义
  unsigned char frame[bufferSize];

  //接收到的数据原始CRC
  unsigned int receivedCrc;
  //接收到的数据长度
  unsigned char address=0;
  int val;
  val=analogRead(0);
  //Serial.println(val,DEC);
  delay(100);

  //延时1.5个字符宽度
  characterTime = 15000000/baudrate;

  //如果串口缓冲区数据量大于0进入条件
  while(Serial.available()>0)  
  {
      //接收的数据量应小于一帧数据的最大字节数量
      if(address<bufferSize)  
      {
         frame[address]=Serial.read();
         address++;
      }
      else
      {
        //清空缓冲区
        Serial.read();
      }
      //延迟
      delayMicroseconds(characterTime);
      //数据读取完成
      if(Serial.available()==0)
      {
        //校验CRC
        unsigned short internalCrc = ModRTU_CRC((char*)frame, address-2);
        internalCrc >> 1;
        unsigned char high = internalCrc&0xFF;
        unsigned char low = internalCrc>>8;

        //校验通过
        if(low==frame[address - 1]&&high==frame[address - 2])
        {
          unsigned char slaveCode = frame[0];
          //设备号匹配,兼容广播模式
          if(slaveCode==slaveID||slaveCode==0)
          {
            //检查功能码
            unsigned char funcCode = frame[1];
            if(funcCode==3)
            {
              //组装返回的数据
              frame[2] = 0x04;
              frame[3] = 0x00;
              frame[4] = 0x00;
         frame[5] = 0x00;
              frame[6] = val;             
            }

            else
            {
              //组装返回的数据
              frame[2] = 0x00;
              frame[3] = 0x00;
              frame[4] = 0x00;
              //报错:未知功能码

              frame[5] = 0x01;
              }
          }       
        }

        else
        {       
              //组装返回的数据
              frame[2] = 0x00;
              frame[3] = 0x00;
              frame[4] = 0x00;
              //报错:CRC校验失败,真实环境不需要

              frame[5] = 0x02;             
         }

         internalCrc = ModRTU_CRC((char*)frame, 7);
         internalCrc >> 1;
         frame[7] = internalCrc&0xFF;
    //     frame[7] = internalCrc>>8;
    frame[8] = internalCrc>>8;
         Serial.write(&frame[0], 9);         
      }
  }
}

unsigned int ModRTU_CRC(char * buf, int len)
{
  unsigned int crc = 0xFFFF;
  for (int pos = 0; pos < len; pos++) {
    crc ^= (unsigned int)buf[pos];
    for (int i = 8; i != 0; i--) {
      if ((crc & 0x0001) != 0) {
        crc >>= 1;
        crc ^= 0xA001;
      }
      else
        crc >>= 1;
    }
  }
  return crc;  
}