我使用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
答案 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;
}