if语句在Nucleo64上不起作用,但在Maple mini上起作用

时间:2019-07-23 13:54:09

标签: c++ arduino stm32 nucleo

我有一个可以在Maple Mini上运行的代码,但是我必须将硬件更改为Nucleo F030r8,因为它具有更多的ADC,并且完全糟透了。 在modbus_update()函数中,检查inputBuffer的大小,并且仅当此变量的值大于0时,以下代码才应运行。

  if (inputBuffer > 0 && micros() - microsFlag >= T3_5) {
  ...
  }

但是即使inputBuffer的值正好为0,它也可以运行。奇怪的是,此代码(具有不同的串行端口打开方法)可以在Maple Mini上完美运行。有谁知道可能是什么问题?

这是整个代码:

#define BAUDRATE 19200
#define RE_PIN PC12
#define TE_PIN PF4
#define LED_PIN LED_BUILTIN
#define SLAVE_ID 1
#define BUFFER_SIZE 256             // max frame size
#define READ_INTERNAL_REGISTERS 4   // function code
#define MIN_REGISTER_ADDRESS 30001
#define MAX_REGISTER_ADDRESS 30020
#define MAX_SENSORS_PER_ROW 10
#define SENSORS_PER_ROW 7
#define MAX_ROWS 2
#define ROWS 1
#define DEBUG true
#define INVALID_VALUE 0x7FFF

const byte INPUTS[] = {PA0, PA1, PA4, PB0, PC1, PC0};
unsigned char frame[BUFFER_SIZE];
unsigned char functionCode;
unsigned int T1;
unsigned int T1_5; // inter character time out
unsigned int T3_5; // frame delay
unsigned long millisFlag = 0;
unsigned long microsFlag = 0;
unsigned char inputBuffer = 0;
int dlyCounter = 0;
int16_t sensorVals[MAX_SENSORS_PER_ROW * MAX_ROWS];
/*
HardwareSerial *modbus = &Serial;
HardwareSerial Serial1(PA10, PA9);
HardwareSerial *debug = &Serial1;
*/
HardwareSerial debug(PA10, PA9);
void setup() {
  pinMode(LED_PIN, OUTPUT);
  for (int i = 0; i < SENSORS_PER_ROW; i++) {
    pinMode(INPUTS[i], INPUT_PULLUP);
  }
  debug.begin(BAUDRATE, SERIAL_8E1);
  modbus_configure(BAUDRATE, 0); // baud rate, low latency
  microsFlag = micros();
}

void loop() {
  readSensorVals(100);
  modbus_update();
}

unsigned int modbus_update() {
  unsigned char overflow = 0;

  while (Serial.available()) {
    if (overflow) {
      Serial.read(); // empty the input buffer
    } else {
      if (inputBuffer == BUFFER_SIZE) {
        overflow = 1;
      } else {
        frame[inputBuffer] = Serial.read();
        inputBuffer++;
      }
    }
    microsFlag = micros();
  }
  // If an overflow occurred return to the main sketch
  // without responding to the request i.e. force a timeout
  if (overflow) {
    debug.println("Error: input buffer overflow");
    return 0;
  }

  // if inter frame delay occurred, check the incoming package
  if (inputBuffer > 0 && micros() - microsFlag >= T3_5) {
    debug.println("\nIncoming frame:");
    for (int i = 0; i < inputBuffer; i++) {
      debug.print(frame[i], HEX);
      debug.print(" ");
    }
    debug.println();

    // check CRC
    unsigned int crc = ((frame[inputBuffer - 2] << 8) | frame[inputBuffer - 1]); // combine the crc Low & High bytes
    if (calculateCRC(frame, inputBuffer - 2) != crc) {
      debug.println("Error: checksum failed");
      inputBuffer = 0;
      return 0;
    }
    debug.println("CRC OK");

    // check ID
    unsigned char id = frame[0];
    if (id > 242) {
      debug.println("Error: Invalid ID");
      inputBuffer = 0;
      return 0;
    }

    // check if it's a broadcast message
    if (id == 0) {
      debug.println("Broadcast message");
      inputBuffer = 0;
      return 0;
    }

    if (id != SLAVE_ID) {
      debug.println("Not my ID");
      inputBuffer = 0;
      return 0;
    }
    debug.println("ID OK");

    // check function code
    functionCode = frame[1];
    if (functionCode != READ_INTERNAL_REGISTERS) {
      debug.println("Exception: illegal function");
      exceptionResponse(1);
      inputBuffer = 0;
      return 0;
    }
    debug.println("Function code OK");

    // check frame size (function 4 frame MUST be 8 bytes long)
    if (inputBuffer != 8) {
    // some workaround here:
    //if (inputBuffer != 8 || !(inputBuffer == 9 && frame[inputBuffer] == 0)) {
      debug.println("Error: inaccurate frame length");
      inputBuffer = 0;
      return 0;
    }
    debug.println("Frame size OK");

    // check data address range
    unsigned int noOfRegisters = ((frame[4] << 8) | frame[5]); // combine the number of register bytes
    if (noOfRegisters > 125) {
      debug.println("Exception: illegal data address");
      exceptionResponse(2);
      inputBuffer = 0;
      return 0;
    }

    unsigned int firstRegAddress = ((frame[2] << 8) | frame[3]); // combine the starting address bytes
    debug.print("First address: ");
    debug.println(firstRegAddress);

    unsigned int lastRegAddress = firstRegAddress + noOfRegisters - 1;
    debug.print("Last address: ");
    debug.println(lastRegAddress);

    unsigned char noOfBytes = noOfRegisters * 2;
    unsigned char responseFrameSize = 5 + noOfBytes; // ID, functionCode, noOfBytes, (dataLo + dataHi) * number of registers, crcLo, crcHi
    unsigned char responseFrame[responseFrameSize];
    responseFrame[0] = SLAVE_ID;
    responseFrame[1] = 0x04;
    responseFrame[2] = noOfBytes;
    unsigned char address = 3; // PDU starts at the 4th byte
    for (int index = (int)(firstRegAddress - MIN_REGISTER_ADDRESS); index <= (int)(lastRegAddress - MIN_REGISTER_ADDRESS); index++) {
      int16_t temp = (index >= 0 && index < MAX_ROWS * MAX_SENSORS_PER_ROW) ? sensorVals[index] : INVALID_VALUE;
      responseFrame[address] = temp >> 8; // split the register into 2 bytes
      address++;
      responseFrame[address] = temp & 0xFF;
      address++;
    }
    unsigned int crc16 = calculateCRC(responseFrame, responseFrameSize - 2);
    responseFrame[responseFrameSize - 2] = crc16 >> 8; // split crc into 2 bytes
    responseFrame[responseFrameSize - 1] = crc16 & 0xFF;
    debug.println("Frame to send:");
    for (int i = 0; i < responseFrameSize; i++) {
      debug.print(responseFrame[i], HEX);
      debug.print(" ");
    }
    debug.println();
    sendPacket(responseFrame, responseFrameSize);

    inputBuffer = 0;

    while (Serial.available()) { // empty input buffer
      Serial.read();
    }
  }
}

void modbus_configure(long baud, unsigned char _lowLatency) {
  Serial.begin(baud, SERIAL_8E1);
  pinMode(TE_PIN, OUTPUT);
  pinMode(RE_PIN, OUTPUT);
  rxEnable(); // pin 0 & pin 1 are reserved for RX/TX. To disable set TE and RE pin < 2

  if (baud == 1000000 && _lowLatency) {
    T1 = 1;
    T1_5 = 1;
    T3_5 = 10;
  } else if (baud >= 115200 && _lowLatency) {
    T1 = 50;
    T1_5 = 75;
    T3_5 = 175;
  } else if (baud > 19200) {
    T1 = 500;
    T1_5 = 750;
    T3_5 = 1750;
  } else {
    T1 = 10000000 / baud;
    T1_5 = 15000000 / baud; // 1T * 1.5 = T1.5
    T3_5 = 35000000 / baud; // 1T * 3.5 = T3.5
  }
}

void exceptionResponse(unsigned char exception) {
  unsigned char responseFrameSize = 5;
  unsigned char responseFrame[responseFrameSize];
  responseFrame[0] = SLAVE_ID;
  responseFrame[1] = (functionCode | 0x80); // set the MSB bit high, informs the master of an exception
  responseFrame[2] = exception;
  unsigned int crc16 = calculateCRC(responseFrame, 3); // ID, functionCode + 0x80, exception code == 3 bytes
  responseFrame[3] = crc16 >> 8;
  responseFrame[4] = crc16 & 0xFF;
  sendPacket(responseFrame, responseFrameSize); // exception response is always 5 bytes (ID, functionCode + 0x80, exception code, 2 bytes crc)
}

unsigned int calculateCRC(unsigned char f[], byte bufferSize) {
  unsigned int temp, temp2, flag;
  temp = 0xFFFF;
  for (unsigned char i = 0; i < bufferSize; i++)  {
    temp = temp ^ f[i];
    for (unsigned char j = 1; j <= 8; j++)   {
      flag = temp & 0x0001;
      temp >>= 1;
      if (flag)
        temp ^= 0xA001;
    }
  }
  // Reverse byte order.
  temp2 = temp >> 8;
  temp = (temp << 8) | temp2;
  temp &= 0xFFFF;
  return temp; // the returned value is already swapped - crcLo byte is first & crcHi byte is last
}

void rxEnable() {
  if (TE_PIN > 1 && RE_PIN > 1) {
    digitalWrite(TE_PIN, LOW);
    digitalWrite(RE_PIN, LOW);
    digitalWrite(LED_PIN, LOW);
  }
}

void txEnable() {
  if (TE_PIN > 1 && RE_PIN > 1) {
    digitalWrite(TE_PIN, HIGH);
    digitalWrite(RE_PIN, HIGH);
    digitalWrite(LED_PIN, HIGH);
  }
}

void sendPacket(unsigned char f[], unsigned char bufferSize) {
  txEnable();
  delayMicroseconds(T3_5);
  for (unsigned char i = 0; i < bufferSize; i++) {
    Serial.write(f[i]);
  }
  Serial.flush();
  delayMicroseconds(T3_5); // allow frame delay to indicate end of transmission
  rxEnable();
}

// @param dly delay between sensor readings in milliseconds
void readSensorVals(int dly) {
  if (millis() != millisFlag) {
    dlyCounter++;
    millisFlag = millis();
  }
  if (dlyCounter >= dly) { // read sensor values
    for (int i = 0; i < MAX_ROWS; i++) {
      for (int j = 0; j < MAX_SENSORS_PER_ROW; j++) {
        int actualIndex = i * MAX_SENSORS_PER_ROW + j;
        if (i < ROWS && j < SENSORS_PER_ROW) {
          sensorVals[actualIndex] = random(20, 30);
          //sensorVals[actualIndex] = (4096 - analogRead(INPUTS[j])) / 20 - 133;
        } else {
          sensorVals[actualIndex] = INVALID_VALUE;
        }
      }
    }
    dlyCounter = 0;
  }
}

0 个答案:

没有答案