Immer wenn ich von meinem VCNL4200 über I2C lese, ist das 16-Bit-Wort, das ich zurückbekomme, immer 0x0000. Dies ist völlig unabhängig von dem Register, das ich lese, und passiert immer noch beim Lesen des Geräte-ID-Registers, das einen festen Wert ungleich Null hat. Dies ist bei beiden Sensorchips passiert, die ich ausprobiert habe.
Soweit ich sagen kann, liest das Gerät I2C-Befehle korrekt, da ich es sondiert und überprüft habe, dass das Gerät das tut, was meine Setup-Funktion ihm sagt. Es verhält sich auch korrekt mit ACK/NACK-Bits (für ACK während des Schreibens auf Low ziehen, SDA für das Mikro zum ACK während des Lesens floaten lassen).
Die Scope-Traces für SDA und SCL, wenn ich versuche, das Geräte-ID-Register zu lesen, sind unten.
Code, den ich zum Lesen/Einrichten des Sensors verwende:
//count is number of bits, stop is whether or not there is a stop condition at the end
int i2cWrite(int8 address, int8 *data, int8 count, int1 stop);
int i2cRead(int8 address, int8 *data, int8 count);
int16 VCNL4200_Read(void) {
int8 data[2] = {0};
int8 psDataRegister[1] = {0x0E}; //0x08 is the address of the data, 0x0E for device ID
i2cWrite(VCNL4200_I2C_ADDRESS, psDataRegister, 1, 1);
i2cRead(VCNL4200_I2C_ADDRESS, data, 2);
return make16(data[1], data[0]);
}
void VCNL4200_Setup(void) {
int8 configWords[5][2] = {
{0xF0, 0x00}, //PS_CONF1 , PS_CONF2
{0x00, 0x20}, //PS_CONF3 , PS_MS
{0x00, 0x00}, //PS_CANC_L, PS_CANC_H
{0x00, 0x00}, //PS_THDL_L, PS_THDL_H
{0x01, 0x00} //PS_THDH_L, PS_THDH_H
};
int8 configWordCurrent[3];
for(int8 i = 0; i < 5; i++){
configWordCurrent[0] = i+3; //1st byte, register address. Sequential from 0x03 to 0x07
configWordCurrent[1] = configWords[i][0]; //2nd byte, lower byte of config word
configWordCurrent[2] = configWords[i][1]; //3rd byte, upper byte of config word
i2cWrite(VCNL4200_I2C_ADDRESS, configWordCurrent, 3, 1);//Send over I2C
}
}
Die Funktionen i2cWrite
und i2cRead
wurden auf anderen Geräten als funktionsfähig verifiziert. Ich verwende einen PIC16F1776 mit CCS C-Compiler.
Es sieht so aus, als ob der VCNL4200 einen Wiederholungsstart zwischen den beiden I2C-Befehlen erwartet , und Sie haben zwei separate Befehle mit einem Stopp dazwischen.
Aus dem Datenblatt ist es nicht sehr offensichtlich, aber dieser Arduino-Treiber sendet die Stoppnachricht nicht auf WireEndTransmisson .
Ich vermute, das ist das Äquivalent zum i2cWrite(VCNL4200_I2C_ADDRESS, psDataRegister, 1, 1);
Werden i2cWrite(VCNL4200_I2C_ADDRESS, psDataRegister, 1, 0);
in Ihrem Code.
Ron Beyer
Fliehen
#use i2c(master, sda=PIN_B5, scl=PIN_B4, force_hw, fast=100000)
(siehe CCS-Handbuch für Details). Der VCNL4200 kann mit 100 kHz betrieben werden