Я пишу класс VB.NET для реализации функциональности CH341DLL.DLL. Метод CH341StreamI2C() используется для потоковой записи и чтения в устройство. Таким образом, я импортировал метод CH341StreamI2C() из DLL:
<DllImport("CH341DLL.DLL", SetLastError:=True, CallingConvention:=CallingConvention.StdCall)>
Private Shared Function CH341StreamI2C(ByVal iIndex As Integer, ByVal iWriteLength As Integer, ByRef iWriteBuffer As IntPtr, ByVal iReadLength As Integer, ByRef oReadBuffer As IntPtr) As Boolean
End Function
Для проверки работы этого метода я использую датчик влажности и температуры I2C HTU21D. Его IIC-адрес — 40h, а регистр, в котором происходит получение температуры, — E3h. Поэтому я вызываю метод CH341StreamI2C() следующим образом:
Dim writeBuffer as Byte() = {&H40, &hE3} 'Address+Command
Dim s As String = Encoding.Unicode.GetString(writeBuffer)
Dim writeBufPtr As IntPtr = Marshal.StringToHGlobalAuto(s) 'Get pointer for write buffer
Dim wLen As Integer = writeBuffer.Length
Dim readBufPtr As IntPtr = IntPtr.Zero 'Init read pointer
Dim rLen as Integer = 3 'Sensor must return 3 bytes
Dim res As Boolean = CH341StreamI2C(0, wLen, writeBufPtr, rLen, readBufPtr)
Я использую логический анализатор, чтобы посмотреть, что находится на линиях SDA и SCL. И результат непредсказуем. Например, если вызвать предыдущий код 4 раза, это результат:
Видно, что физически устройство CH341 записывает в строку непредсказуемые значения. Это не ошибка DLL, потому что другие приложения используют этот метод и результат правильный. Для справки, другие методы, например. CH341ReadI2C() и CH341WriteI2C(), которые считывают/записывают только один байт за раз, работают правильно в моем коде.
Какова вероятная причина такого поведения? Может быть, я неправильно рассортировал буфер записи? Как правильно это сделать?
ByRef
из аргументов буфера, они передаются ByVal. Лучше объявить их как Byte(). - person Hans Passant   schedule 09.09.2018