接收到的数据在程序范围内是正确的

时间:2019-07-19 08:56:52

标签: arduino spi

我使用Arduino /* MLX90316 Rotary Position Sensor */ int readAngle(); int pinSS = 10; // Green Wire int pinDATA = 11; // Yellow Wire int pinSCK = 13; // Grey Wire unsigned int r1=0; unsigned int r2=0; unsigned int r3=0; unsigned int r4=0; int angle; void setup(){ delayMicroseconds(16000); // 16ms slave start-up pinMode(pinSS,OUTPUT); // Pin Slave Select pinMode(pinSCK, OUTPUT); // Pin Clock digitalWrite(pinSS, HIGH); // de-select chip Serial.begin(115200); Serial.println("MLX90316 Rotary Position Sensor"); } void loop() { angle = readAngle(); Serial.println(""); Serial.print("r1=");Serial.println(r1,HEX); Serial.print("r2=");Serial.println(r2,HEX); Serial.print("r3=");Serial.println(r3,HEX); Serial.print("r4=");Serial.println(r4,HEX); delay(10000); } int readAngle() { // Start with clock LOW digitalWrite(pinSCK, LOW); // Data pin in write mode pinMode(pinDATA, OUTPUT); // take the SS pin low to select the chip: digitalWrite(pinSS, LOW); delayMicroseconds(30); // Send START bytes shiftOut(pinDATA, pinSCK, MSBFIRST, 0xAA); delayMicroseconds(25); shiftOut(pinDATA, pinSCK, MSBFIRST, 0xFF); delayMicroseconds(30); // 30 us between START bytes and DATA // Data pin in read mode pinMode(pinDATA, INPUT_PULLUP); // Receive data r1 = shiftIn(pinDATA, pinSCK, MSBFIRST); delayMicroseconds(25); r2 = shiftIn(pinDATA, pinSCK, MSBFIRST); delayMicroseconds(25); r3 = shiftIn(pinDATA, pinSCK, MSBFIRST); delayMicroseconds(30); r4 = shiftIn(pinDATA, pinSCK, MSBFIRST); // take the SS pin high to de-select the chip: delayMicroseconds(5); digitalWrite(pinSS, HIGH); } 指令从MLX90316接收数据。
MOSI和MISO使用一根导线。
数据包含4个字节(2 + 2)
前2个字节是角度值。后2个字节是角度的反转值(第一个补码)
前2个字节在范围和程序上正确(0x00和0x22)
后2个字节在范围(0xFF和0XDD)上是正确的,但是在程序中(0xFF和0xDC或0xFF和0xCC ...)经常(并非总是)错误

实际上,当我打印最后一个字节时有时是错误的。

我尝试将串行速度更改为9600 bps(相同的结果)
我试图在上次shiftIn之前更改delayMicroseconds值(结果相同)

{{1}}

我希望输出为0x00 0x22 0xFF 0xDD

1 个答案:

答案 0 :(得分:2)

我不知道您使用的是哪个Arduino,但是移入和移出功能是非常简单的软件实现。

uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) {
    uint8_t value = 0;
    uint8_t i;

    for (i = 0; i < 8; ++i) {
        digitalWrite(clockPin, HIGH);
        if (bitOrder == LSBFIRST)
            value |= digitalRead(dataPin) << i;
        else
            value |= digitalRead(dataPin) << (7 - i);
        digitalWrite(clockPin, LOW);
    }
    return value;
}

MLX90316仅允许时钟频率为145kHz,因此这种直接端口访问速度可能太快,并且在您读取数据时未准备好数据。 但是,由于您有可用的示波器,因此可以简单地检查时间并在必要时编写自己的shiftIn

我认为此“版本”应适用于您的芯片(未经测试)

uint8_t shiftIn2(uint8_t dataPin, uint8_t clockPin) {
    uint8_t value = 0;
    uint8_t i;

    for (i = 0; i < 8; ++i) {
        digitalWrite(clockPin, HIGH);
        delayMicroseconds(4);
        digitalWrite(clockPin, LOW);
        value |= digitalRead(dataPin) << (7 - i);
        delayMicroseconds(4);           
    }
    return value;
}