你好!
最近使用CH341实现上位机与数据芯片I2C通信时遇到以下问题:
1、使用USBIO_StreamI2C读取数据时跳字节读取。如数据为{48,50,76,87,48,49},读取到2个数据为50,76,下一次读到的是48,49;
2、使用USBIO_OpenDevice->USBIO_StreamI2C->USBIO_CloseDevice的顺序读取,为什么每次都是从上次读取位置向后读取,只有拔插设备后才从头读取?
望解答
你好!
最近使用CH341实现上位机与数据芯片I2C通信时遇到以下问题:
1、使用USBIO_StreamI2C读取数据时跳字节读取。如数据为{48,50,76,87,48,49},读取到2个数据为50,76,下一次读到的是48,49;
2、使用USBIO_OpenDevice->USBIO_StreamI2C->USBIO_CloseDevice的顺序读取,为什么每次都是从上次读取位置向后读取,只有拔插设备后才从头读取?
望解答
这个问题没有回复的吗
设备地址0X50,读的时候USBIO_StreamI2C的iWriteBuffer首字节写的0XA1,第二个字节看其他贴说写单元地址,但是无论写什么进去都是跳字节读取,也就是第一个字节数据读取不到,能帮忙解决这个问题吗
您好,如上操作流程没问题,您的I2C外设本身是否需要填写I2C单元地址。如果需要则没问题。芯片没有缓存I2C数据的功能,每次执行结果均为此次交互的内容。这样,您看下手里有没有逻辑分析仪等工具,可以抓下如上通讯的波形,看下物理上返回的内容是否有问题。此外,也可以直接用我们提供的官方工具读取对比。链接:https://www.wch.cn/downloads/CH341EVT_ZIP.html
后面通过尝试发现,只发送iWriteBuffer的首字节(0XA1)就能成功读取。但是这样就无法指定起始位置进行读取了?
您好,这个取决于您这边的外设是否需要单独输入单元地址的。您看下手册的描述,是否和当前的代码操作相匹配。
外设寄存器地址是16位应该怎么输入呢
您好,16位的I2C地址,发送缓冲区WriteBuffer,往后进行填充即可。如下可作参考:
BOOL ? ?WINAPI ?CH341WriteEEPROM( ?// 向EEPROM中写入数据块
? ? ULONG ? ? ? ? ? iIndex, ?// 指定CH341设备序号
? ? EEPROM_TYPE ? ? iEepromID, ?// 指定EEPROM型号
? ? ULONG ? ? ? ? ? iAddr, ?// 指定数据单元的地址
? ? ULONG ? ? ? ? ? iLength, ?// 准备写出的数据字节数
? ? PUCHAR ? ? ? ? ?iBuffer ) ?// 指向一个缓冲区,放置准备写出的数据
{
? ? ULONG ? mLen;
? ? UCHAR ? mWrBuf[256];
? ? if ( iEepromID >= ID_24C01 && iEepromID <= ID_24C16 ) { ?// 7位-11位地址
? ? ? ? while ( iLength ) {
? ? ? ? ? ? mWrBuf[0] = (UCHAR)( 0xA0 | ( iAddr >> 7 ) & 0x0E ); ?// I2C目标设备地址,最低位为0则进行写操作
? ? ? ? ? ? mWrBuf[1] = (UCHAR)iAddr; ?// 低8位地址
? ? ? ? ? ? mLen = iEepromID >= ID_24C04 ? 16 - ( iAddr & 15 ) : 8 - ( iAddr & 7 ); ?// 不超过页长度
? ? ? ? ? ? if ( mLen > iLength ) mLen = iLength;
? ? ? ? ? ? CopyMemory( &mWrBuf[2], iBuffer, mLen );
? ? ? ? ? ? if ( CH341StreamI2C( iIndex, 2 + mLen, mWrBuf, 0, NULL ) == FALSE ) return( FALSE ); ?// 处理I2C数据流
? ? ? ? ? ? CH341SetDelaymS( iIndex, 10 ); ?// 设置10毫秒硬件异步延时
? ? ? ? ? ? iAddr += mLen;
? ? ? ? ? ? iLength -= mLen;
? ? ? ? ? ? iBuffer += mLen;
? ? ? ? }
? ? }
? ? else if ( iEepromID >= ID_24C32 && iEepromID <= ID_24C4096 ) { ?// 12位-19位地址
? ? ? ? while ( iLength ) {
? ? ? ? ? ? mWrBuf[0] = (UCHAR)( 0xA0 | ( iAddr >> 15 ) & 0x0E ); ?// I2C目标设备地址,最低位为0则进行写操作
? ? ? ? ? ? mWrBuf[1] = (UCHAR)( iAddr >> 8 ); ?// 高8位地址
? ? ? ? ? ? mWrBuf[2] = (UCHAR)iAddr; ?// 低8位地址
? ? ? ? ? ? mLen = iEepromID >= ID_24C512 ? 128 - ( iAddr & 127 ) : ( iEepromID >= ID_24C128 ? 64 - ( iAddr & 63 ) : 32 - ( iAddr & 31 ) ); ?// 不超过页长度
? ? ? ? ? ? if ( mLen > iLength ) mLen = iLength;
? ? ? ? ? ? CopyMemory( &mWrBuf[3], iBuffer, mLen );
? ? ? ? ? ? if ( CH341StreamI2C( iIndex, 3 + mLen, mWrBuf, 0, NULL ) == FALSE ) return( FALSE ); ?// 处理I2C数据流
? ? ? ? ? ? CH341SetDelaymS( iIndex, 10 ); ?// 设置10毫秒硬件异步延时
? ? ? ? ? ? iAddr += mLen;
? ? ? ? ? ? iLength -= mLen;
? ? ? ? ? ? iBuffer += mLen;
? ? ? ? }
? ? }
? ? else return( FALSE );
? ? return( TRUE );
}