CH341 IIC通訊時鐘速率問題

一年前咨詢過,因?yàn)閕ic 從機(jī)為MCU硬件,在處理主機(jī)讀取數(shù)據(jù)時,速度比較慢,會出現(xiàn)連續(xù)讀取數(shù)據(jù)時,在上一byte的ACK回復(fù)完后1個clk時間內(nèi)不能釋放scl的問題。

現(xiàn)在自己重新寫讀取函數(shù)實(shí)現(xiàn)了,如下:

但是此函數(shù)因?yàn)閕ic數(shù)據(jù)流包大小被限制在32byte,所以當(dāng)我的讀取數(shù)據(jù)連續(xù)超過12個byte時,iic數(shù)據(jù)流超出了32個字節(jié)

當(dāng)我使用兩個數(shù)據(jù)流寶來實(shí)現(xiàn)時,兩個包之間的時間有200-1200us間隔不等,請問有好的解決辦法沒有?

public bool MulReadIIC(UInt32 iIndex, byte addr, byte reg, Byte[] data, uint data_Len)

? ? ? ? {

? ? ? ? ? ? byte i = 0;

? ? ? ? ? ? Byte[] mBuffer = new Byte[64];

? ? ? ? ? ? UInt32 mLength, mInLen;

? ? ? ? ? ? mBuffer[i++] = USBIOXdll.mCH341A_CMD_I2C_STREAM;? // 命令碼

? ? ? ? ? ? mBuffer[i++] = USBIOXdll.mCH341A_CMD_I2C_STM_STA;? // 產(chǎn)生起始位

? ? ? ? ? ? mBuffer[i++] = USBIOXdll.mCH341A_CMD_I2C_STM_OUT | 2;? //??

? ? ? ? ? ? mBuffer[i++] = addr;? //?

? ? ? ? ? ? mBuffer[i++] = reg;? //?

? ? ? ? ? ? mBuffer[i++] = USBIOXdll.mCH341A_CMD_I2C_STM_STA;? // 產(chǎn)生起始位

? ? ? ? ? ? mBuffer[i++] = USBIOXdll.mCH341A_CMD_I2C_STM_OUT;? //??

? ? ? ? ? ? mBuffer[i++] = (byte)(addr + 1);? // 產(chǎn)生起始位

? ? ? ? ? ? for(byte count=0;count< data_Len-1; count++)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? mBuffer[i++] = USBIOXdll.mCH341A_CMD_I2C_STM_US + 4;? // 延時4us

? ? ? ? ? ? ? ? mBuffer[i++] = USBIOXdll.mCH341A_CMD_I2C_STM_IN + 1;? // 輸入數(shù)據(jù),位5-位0為長度,0長度則只接收一個字節(jié)并發(fā)送無應(yīng)答

? ? ? ? ? ? }

? ? ? ? ? ? mBuffer[i++] = USBIOXdll.mCH341A_CMD_I2C_STM_US + 4;? // 延時4us

? ? ? ? ? ? mBuffer[i++] = USBIOXdll.mCH341A_CMD_I2C_STM_IN;? // 輸入數(shù)據(jù),位5-位0為長度,0長度則只接收一個字節(jié)并發(fā)送無應(yīng)答

? ? ? ? ? ? mBuffer[i++] = USBIOXdll.mCH341A_CMD_I2C_STM_END;? // 當(dāng)前包提前結(jié)束

? ? ? ? ? ? mLength = i;

? ? ? ? ? ? mInLen = 0;


? ? ? ? ? ? USBIOXdll.USBIO_WriteRead(iIndex, mLength, mBuffer, 0x3F, 1, ref mInLen, mBuffer);? // 寫出數(shù)據(jù)塊

? ? ? ? ? ? return true;

? ? ? ? }


您好,可嘗試按照如下方式組包,實(shí)現(xiàn)發(fā)送I2C設(shè)備地址后延遲一段時間讀數(shù)據(jù),以及連續(xù)讀取數(shù)據(jù)的時鐘之間插入微秒級延遲。如下函數(shù)支持長包讀寫,也即將需要讀寫的過程拼成長包處理。也可以發(fā)郵件給我們獲取完整工程用于測試。郵箱:tech@wch.cn?

BOOL ? ?WINAPI ?CH341StreamI2C_Delay( ?// 處理I2C數(shù)據(jù)流,2線接口,時鐘線為SCL引腳,數(shù)據(jù)線為SDA引腳(準(zhǔn)雙向I/O),速度約56K字節(jié)

? ? ULONG ? ? ? ? ? iIndex, ?// 指定CH341設(shè)備序號

? ? ULONG ? ? ? ? ? iWriteLength, ?// 準(zhǔn)備寫出的數(shù)據(jù)字節(jié)數(shù)

? ? PVOID ? ? ? ? ? iWriteBuffer, ?// 指向一個緩沖區(qū),放置準(zhǔn)備寫出的數(shù)據(jù),首字節(jié)通常是I2C設(shè)備地址及讀寫方向位

? ? ULONG ? ? ? ? ? iReadLength, ?// 準(zhǔn)備讀取的數(shù)據(jù)字節(jié)數(shù)

? ? PVOID ? ? ? ? ? oReadBuffer, ? // 指向一個緩沖區(qū),返回后是讀入的數(shù)據(jù)

? ? UCHAR ? ? ? ? ? iReadDelay1, ? //地址后的延時,單位US,數(shù)值范圍:0~15

? ? UCHAR ? ? ? ? ? iReadDelay2) ? //讀間隔延時,單位US,數(shù)值范圍:0~15

{

? ? UCHAR ? ? ? ? ? mBuffer[ mDEFAULT_COMMAND_LEN + mDEFAULT_COMMAND_LEN / 8 ];

? ? ULONG ? ? ? ? ? i, j, mLength;

? ? PUCHAR ? ? ? ? ?mWrBuf;

? ? //if ( dllCH341VerIC[ iIndex ] < 0x20 ) return( FALSE ); ?// not CH341A

? ? mLength = max( iWriteLength, iReadLength );

? ? if ( mLength > mMAX_BUFFER_LENGTH ) return( FALSE );

? ? if ( mLength <= mDEFAULT_BUFFER_LEN ) mWrBuf = (PUCHAR)mBuffer; ?// 不超過默認(rèn)緩沖區(qū)長度

? ? else { ?// 超過則需要另外分配內(nèi)存

? ? ? ? mWrBuf = (PUCHAR)LocalAlloc( LMEM_FIXED, mMAX_COMMAND_LENGTH + mMAX_COMMAND_LENGTH / 8 ); ?// 分配內(nèi)存

? ? ? ? if ( mWrBuf == NULL ) return( FALSE ); ?// 分配內(nèi)存失敗

? ? }

? ? i = 0;

? ? mWrBuf[ i++ ] = mCH341A_CMD_I2C_STREAM; ?// 命令碼

? ? //if ( ( dllCH341StreamMode[ iIndex ] & 0x03 ) == 0 ) {

? ? // ?mWrBuf[ i++ ] = mCH341A_CMD_I2C_STM_US | 10; ?// 延時10微秒

? ? // ?mWrBuf[ i++ ] = mCH341A_CMD_I2C_STM_US | 10; ?// 延時10微秒

? ? //}

? ? mWrBuf[ i++ ] = mCH341A_CMD_I2C_STM_STA; ?// 產(chǎn)生起始位

? ? if ( iWriteLength ) {

? ? ? ? for ( j = 0; j < iWriteLength; ) {

? ? ? ? ? ? mLength = mCH341_PACKET_LENGTH - i % mCH341_PACKET_LENGTH; ?// 當(dāng)前包剩余長度,

? ? ? ? ? ? if ( mLength <= 2 ) {

? ? ? ? ? ? ? ? while ( mLength-- ) mWrBuf[ i++ ] = mCH341A_CMD_I2C_STM_END; ?// 當(dāng)前包提前結(jié)束

? ? ? ? ? ? ? ? mLength = mCH341_PACKET_LENGTH;

? ? ? ? ? ? }

? ? ? ? ? ? if ( mLength >= mCH341_PACKET_LENGTH ) {

? ? ? ? ? ? ? ? mWrBuf[ i++ ] = mCH341A_CMD_I2C_STREAM; ?// 新包的命令碼

? ? ? ? ? ? ? ? mLength = mCH341_PACKET_LENGTH - 1;

? ? ? ? ? ? }

? ? ? ? ? ? mLength--; ?// 去掉尾部的提前結(jié)束碼

? ? ? ? ? ? mLength--; ?// 去掉輸出數(shù)據(jù)的命令碼

? ? ? ? ? ? if ( mLength > iWriteLength - j ) mLength = iWriteLength - j; ?// 本次輸出有效數(shù)據(jù)長度

? ? ? ? ? ? mWrBuf[ i++ ] = (UCHAR)( mCH341A_CMD_I2C_STM_OUT | mLength ); ?// 輸出數(shù)據(jù),位5-位0為長度

? ? ? ? ? ? while ( mLength-- ) mWrBuf[ i++ ] = *( (PUCHAR)iWriteBuffer + j++ ); ?// 復(fù)制數(shù)據(jù)

? ? ? ? }

? ? }

? ? if ( iReadLength ) {

? ? ? ? mLength = mCH341_PACKET_LENGTH - i % mCH341_PACKET_LENGTH; ?// 當(dāng)前包剩余長度,

? ? ? ? if ( mLength <= 3 ) {

? ? ? ? ? ? while ( mLength-- ) mWrBuf[ i++ ] = mCH341A_CMD_I2C_STM_END; ?// 當(dāng)前包提前結(jié)束

? ? ? ? ? ? mLength = mCH341_PACKET_LENGTH;

? ? ? ? }

? ? ? ? if ( mLength >= mCH341_PACKET_LENGTH ) mWrBuf[ i++ ] = mCH341A_CMD_I2C_STREAM; ?// 新包的命令碼

? ? ? ? if ( iWriteLength > 1 ) { ?// 先輸出

? ? ? ? ? ? mWrBuf[ i++ ] = mCH341A_CMD_I2C_STM_STA; ?// 產(chǎn)生起始位

? ? ? ? ? ? mWrBuf[ i++ ] = (UCHAR)( mCH341A_CMD_I2C_STM_OUT | 1 ); ?// 輸出數(shù)據(jù),位5-位0為長度

? ? ? ? ? ? mWrBuf[ i++ ] = *(PUCHAR)iWriteBuffer | 0x01; ?// I2C目標(biāo)設(shè)備地址,最低位為1則進(jìn)行讀操作

? ? ? ? }

? ? ? ? else if ( iWriteLength ) { ?// 輸出一字節(jié)后直接輸入

? ? ? ? ? ? i--;

? ? ? ? ? ? mWrBuf[ i++ ] = *(PUCHAR)iWriteBuffer | 0x01; ?// I2C目標(biāo)設(shè)備地址,最低位為1則進(jìn)行讀操作

? ? ? ? }

? ? ? ? mWrBuf[ i++ ] = mCH341A_CMD_I2C_STM_US | ( iReadDelay1& 0x0f ); ?// 延時10微秒

? ? ? ? for ( j = 1; j < iReadLength; ) {

? ? ? ? ? ? mLength = mCH341_PACKET_LENGTH - i % mCH341_PACKET_LENGTH; ?// 當(dāng)前包剩余長度,

? ? ? ? ? ? //mLength = 1;

? ? ? ? ? ? if ( mLength <= 1 ) {

? ? ? ? ? ? ? ? if ( mLength ) mWrBuf[ i++ ] = mCH341A_CMD_I2C_STM_END; ?// 當(dāng)前包提前結(jié)束

? ? ? ? ? ? ? ? mLength = mCH341_PACKET_LENGTH;

? ? ? ? ? ? }

? ? ? ? ? ? if ( mLength >= mCH341_PACKET_LENGTH ) mWrBuf[ i++ ] = mCH341A_CMD_I2C_STREAM; ?// 新包的命令碼

? ? ? ? ? ? //mLength = iReadLength - j >= mCH341A_CMD_I2C_STM_MAX ? mCH341A_CMD_I2C_STM_MAX : iReadLength - j; ?// 本次輸入有效數(shù)據(jù)長度

? ? ? ? ? ? mLength = iReadLength - j >= mCH341A_CMD_I2C_STM_MAX ? mCH341A_CMD_I2C_STM_MAX : 1; ?// 本次輸入有效數(shù)據(jù)長度

? ? ? ? ? ? mWrBuf[ i++ ] = (UCHAR)( mCH341A_CMD_I2C_STM_IN | mLength ); ?// 輸入數(shù)據(jù),位5-位0為長度

? ? ? ? ? ? j += mLength;

? ? ? ? ? ? if ( mLength >= mCH341A_CMD_I2C_STM_MAX ) { ?// 當(dāng)前包將滿

? ? ? ? ? ? ? ? mWrBuf[ i ] = mCH341A_CMD_I2C_STM_END; ?// 當(dāng)前包提前結(jié)束

? ? ? ? ? ? ? ? i += mCH341_PACKET_LENGTH - i % mCH341_PACKET_LENGTH; ?// 跳過當(dāng)前包剩余部分

? ? ? ? ? ? }

? ? ? ? ? ? mWrBuf[ i++ ] = mCH341A_CMD_I2C_STM_US | ( iReadDelay2& 0x0f ); ?// 延時10微秒

? ? ? ? }

? ? ? ? mLength = mCH341_PACKET_LENGTH - i % mCH341_PACKET_LENGTH; ?// 當(dāng)前包剩余長度,

? ? ? ? if ( mLength <= 1 ) {

? ? ? ? ? ? if ( mLength ) mWrBuf[ i++ ] = mCH341A_CMD_I2C_STM_END; ?// 當(dāng)前包提前結(jié)束

? ? ? ? ? ? mLength = mCH341_PACKET_LENGTH;

? ? ? ? }

? ? ? ? if ( mLength >= mCH341_PACKET_LENGTH ) mWrBuf[ i++ ] = mCH341A_CMD_I2C_STREAM; ?// 新包的命令碼

? ? ? ? mWrBuf[ i++ ] = mCH341A_CMD_I2C_STM_IN; ?// 輸入數(shù)據(jù),只接收一個字節(jié)并發(fā)送無應(yīng)答

? ? }

? ? mLength = mCH341_PACKET_LENGTH - i % mCH341_PACKET_LENGTH; ?// 當(dāng)前包剩余長度,

? ? if ( mLength <= 1 ) {

? ? ? ? if ( mLength ) mWrBuf[ i++ ] = mCH341A_CMD_I2C_STM_END; ?// 當(dāng)前包提前結(jié)束

? ? ? ? mLength = mCH341_PACKET_LENGTH;

? ? }

? ? if ( mLength >= mCH341_PACKET_LENGTH ) mWrBuf[ i++ ] = mCH341A_CMD_I2C_STREAM; ?// 新包的命令碼

? ? mWrBuf[ i++ ] = mCH341A_CMD_I2C_STM_STO; ?// 產(chǎn)生停止位

? ? mWrBuf[ i++ ] = mCH341A_CMD_I2C_STM_END; ?// 當(dāng)前包提前結(jié)束

? ? mLength = 0;

? ? if ( iReadLength ) j = CH341WriteRead( iIndex, i, mWrBuf, mCH341A_CMD_I2C_STM_MAX, ( iReadLength + mCH341A_CMD_I2C_STM_MAX - 1 ) / mCH341A_CMD_I2C_STM_MAX, &mLength, oReadBuffer ); ?// 執(zhí)行數(shù)據(jù)流命令,先輸出再輸入

? ? else j = CH341WriteData( iIndex, mWrBuf, &i ); ?// 寫出數(shù)據(jù)塊

? ? if ( j && mLength != iReadLength ) j = FALSE;

? ? if ( mWrBuf != mBuffer ) LocalFree( mWrBuf ); ?// 如果是分配的內(nèi)存則釋放

? ? return( j );

}



謝謝!
我先嘗試一下!


長包命令格式是怎么樣的?



如電話溝通,這邊整理下格式然后郵件發(fā)送過去。


只有登錄才能回復(fù),可以選擇微信賬號登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频