CH341DLL.DLL + I2C не работает должным образом с VB.NET - PullRequest
0 голосов
/ 09 сентября 2018

Я пишу класс 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 раза, это будет результат:

Lines SDA and SCL while CH341StreamI2C() calling

Видно, что физически устройство CH341 записывает непредсказуемые значения в строке. Это не ошибка DLL, потому что другие приложения используют этот метод, и результат правильный. Для заметки, другие методы, например CH341ReadI2C () и CH341WriteI2C () , который читает / записывает только один байт за раз, работает правильно в моем коде.

Какова, вероятно, причина такого поведения? Может быть, я неправильно записал буфер записи? Как правильно сделать это?

1 Ответ

0 голосов
/ 09 сентября 2018

Если это , которое вы используете, исходное объявление:

BOOL WINAPI CH341StreamI2C(ULONG iIndex, ULONG iWriteLength, PVOID iWriteBuffer, ULONG iReadLength, PVOID oReadBuffer);

Поскольку параметры буфера PVOID s, вы можете просто перенаправить их в байтовые массивы:

<DllImport("CH341DLL.DLL", SetLastError:=True, CallingConvention:=CallingConvention.StdCall)>
Private Shared Function CH341StreamI2C(ByVal iIndex As Integer, ByVal iWriteLength As Integer, ByVal iWriteBuffer As Byte(), ByVal iReadLength As Integer, ByVal oReadBuffer As Byte()) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function

Массивы являются ссылочными типами (классами), что означает, что вы всегда обращаетесь к ним через указатель их памяти. Таким образом, когда вы передаете их функции (вызванной или нет), вы на самом деле передаете указатель массива , а не сам массив. Это действительно полезно при P / Invoking, поскольку часто позволяет передавать массивы как есть.

...