接收到的数据在范围内是正确的,而不是在程序中
Received data are correct on scope not in program
我使用 Arduino shiftIn
指令从 MLX90316 接收数据。
它使用一根电线用于 MOSI 和 MISO。
数据由 4 个字节组成 (2+2)
前 2 个字节是角度值。第二个2字节是角度的反转值(第一个补码)
前 2 个字节在范围和程序上是正确的(0x00 和 0x22)
第二个 2 字节在范围(0xFF 和 0XDD)上是正确的,但在程序中经常(不总是)错误(0xFF 和 0xDC 或 0xFF 和 0xCC...)
事实上,当我打印它时,有时只有最后一个字节是错误的。
我尝试将串行速度更改为 9600 bps(结果相同)
我试图在最后一个 shiftIn 之前更改 delayMicroseconds 值(相同的结果)
/* 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);
}
我期望输出 0x00 0x22 0xFF 0xDD
我不知道你用的是哪个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
。
我认为这个 "version" 应该适用于您的芯片(未经测试)
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;
}
我使用 Arduino shiftIn
指令从 MLX90316 接收数据。
它使用一根电线用于 MOSI 和 MISO。
数据由 4 个字节组成 (2+2)
前 2 个字节是角度值。第二个2字节是角度的反转值(第一个补码)
前 2 个字节在范围和程序上是正确的(0x00 和 0x22)
第二个 2 字节在范围(0xFF 和 0XDD)上是正确的,但在程序中经常(不总是)错误(0xFF 和 0xDC 或 0xFF 和 0xCC...)
事实上,当我打印它时,有时只有最后一个字节是错误的。
我尝试将串行速度更改为 9600 bps(结果相同)
我试图在最后一个 shiftIn 之前更改 delayMicroseconds 值(相同的结果)
/* 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);
}
我期望输出 0x00 0x22 0xFF 0xDD
我不知道你用的是哪个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
。
我认为这个 "version" 应该适用于您的芯片(未经测试)
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;
}