CH341 BlockRead卡死

如題,我在使用CH341進(jìn)行I2C通訊,使用PmBus協(xié)議,但是在讀取較多數(shù)據(jù)時(shí)經(jīng)??ㄋ?,4個(gè)6個(gè)字節(jié)短一點(diǎn)的都可以,多了的話如20個(gè)25個(gè)都不行了。其他情況如讀寫字節(jié)或字均正常,請問有什么解決辦法嗎?

您好,可以把完整測試代碼發(fā)下,我們協(xié)助您看下是否為代碼調(diào)用問題導(dǎo)致。此外,您反饋的卡死是API發(fā)生阻塞嗎?如是,此時(shí)設(shè)備管理器中設(shè)備狀態(tài)是否正常?


????你好,下面是我的C#代碼

public?SmbusStatus?BlockRead(byte?cmd,?ref?byte[]?data,?byte?dataLen,?bool?bPec)
{
	byte[]?txBuffer?=?new?byte[10];
	byte[]?rxBuffer?=?new?byte[512];
	byte?txLength?=?0;
	byte?rxLength?=?bPec???(byte)(dataLen?+?2):?(byte)(dataLen?+?1);

	try
	{
		//?Write?SlaveAddress?and?Cmd,?ReadAddress?will?be?sent?automatically?to?fetch?data
		txBuffer[txLength++]?=?NodeId;
		txBuffer[txLength++]?=?cmd;
		Marshal.Copy(txBuffer,?0,?ptrTx,?txLength);
		if?(!CH341StreamI2C_Delay(DevIndex,?txLength,?ptrTx,?rxLength,?ptrRx,?0,?0,?60,?0))//?動態(tài)延時(shí)
		{
			return?SmbusStatus.I2cError;
		}
		else?if(rxLength?>?2)//?CNT?+?DATA?+?PEC
		{
			Marshal.Copy(ptrRx,?rxBuffer,?0,?rxLength);

			//?validate?CRC
			if?(bPec)
			{
				byte[]?crcBuffer?=?new?byte[256];
				crcBuffer[0]?=?NodeId;
				crcBuffer[1]?=?cmd;
				crcBuffer[2]?=?(byte)(NodeId?+?1);
				crcBuffer[3]?=?rxBuffer[0];//data?cnt
				for?(uint?i?=?0;?i?<?rxBuffer[0];?i++)
				{
					crcBuffer[4?+?i]?=?rxBuffer[i+1];
				}

				if?(rxBuffer[rxLength-1]?!=?(byte)CRC(CRC_8,?crcBuffer,?0,?(byte)(4?+?dataLen)))
				{
					return?SmbusStatus.PecError;
				}
			}

			//?return?received?byte,?except?cnt?and?rec
			for?(uint?i?=?0;?i?<?dataLen;?i++)
			{
				data[i]?=?rxBuffer[1?+?i];
			}

			return?SmbusStatus.Successful;
		}
		else
		{
			return?SmbusStatus.I2cError;
		}
	}
	catch
	{
		return?SmbusStatus.I2cError;
	}
}

????我在使用您之前提供的博客中的CH341StreamI2C_Delay代碼后返回FALSE,多讀取幾次之后API卡死,需要重新插拔CH341設(shè)備才能退出GUI。

????在我第一次調(diào)用讀取函數(shù)時(shí)可以用邏輯分析儀看到收發(fā)的數(shù)據(jù),仿真查看嵌入式設(shè)備的回復(fù)正常,但CH341回讀回來的數(shù)據(jù)似乎是錯(cuò)的

????以下是正?;貜?fù)數(shù)據(jù):

1698392915655654.png

1698392915872838.png

1698392915696848.png




抱歉,上面的數(shù)據(jù)解析似乎是RIGOL的邏輯分析功能解析數(shù)據(jù)時(shí)錯(cuò)位了,請幫我看下API卡死的問題就好,謝謝。


1698393968380616.png

1698393969153387.png



您好,可以把完整的代碼工程發(fā)到我們技術(shù)郵箱,我們工程師同步試下。郵箱地址:tech@wch.cn。


好的,感謝,我在這兒同步貼下我的CH341StreamI2C_Delay代碼,這通訊搞得確實(shí)頭疼,只剩下這一個(gè)問題沒解決了。

#define?CH341_TX_LEN_MAX????32??//每包數(shù)據(jù)最多發(fā)送的數(shù)據(jù)長度,最大32


inline?UCHAR?CH341_DELAY_US(PUCHAR?mBuf,?UCHAR?uDelay)
{
????UCHAR?i?=?0;

????while?(uDelay?>?mCH341A_CMD_I2C_STM_DLY)
????{
????????mBuf[i++]?=?mCH341A_CMD_I2C_STM_US?|?mCH341A_CMD_I2C_STM_DLY;?//?延時(shí)15微秒
????????uDelay?-=?mCH341A_CMD_I2C_STM_DLY;
????}

????if?(uDelay?>?0)
????????mBuf[i++]?=?mCH341A_CMD_I2C_STM_US?|?(uDelay?&?0x0f);?//?填入剩余的延遲

????return?i;
}

inline?UCHAR?CH341_DELAY_MS(PUCHAR?mBuf,?UCHAR?uDelay)
{
????UCHAR?i?=?0;

????while?(uDelay?>?mCH341A_CMD_I2C_STM_DLY)
????{
????????mBuf[i++]?=?mCH341A_CMD_I2C_STM_MS?|?mCH341A_CMD_I2C_STM_DLY;?//?延時(shí)15毫秒
????????uDelay?-=?mCH341A_CMD_I2C_STM_DLY;
????}

????if?(uDelay?>?0)
????????mBuf[i++]?=?mCH341A_CMD_I2C_STM_MS?|?(uDelay?&?0x0f);?//?填入剩余的延遲

????return?i;
}

BOOL?WINAPI?CH341StreamI2C_Delay(
????ULONG?iIndex,??????????//?指定CH341設(shè)備序號
????ULONG?iWriteLength,????//?準(zhǔn)備寫出的數(shù)據(jù)字節(jié)數(shù)
????PVOID?iWriteBuffer,????//?指向一個(gè)緩沖區(qū),放置準(zhǔn)備寫出的數(shù)據(jù),首字節(jié)通常是I2C設(shè)備地址及讀寫方向位
????ULONG?iReadLength,?????//?準(zhǔn)備讀取的數(shù)據(jù)字節(jié)數(shù)
????PVOID?oReadBuffer,?????//?指向一個(gè)緩沖區(qū),返回后是讀入的數(shù)據(jù)
????UCHAR?iWriteDataDelay,?//?連續(xù)寫數(shù)據(jù)之間的延時(shí),單位US,數(shù)值范圍:0~15
????UCHAR?iAddrDelay1,?????//?寫地址到讀地址之間的延時(shí),單位US,數(shù)值范圍:0~15
????UCHAR?iAddrDelay2,?????//?讀地址和讀數(shù)據(jù)的延時(shí),單位US,數(shù)值范圍:0~15
????UCHAR?iReadDataDelay)??//?連續(xù)讀數(shù)據(jù)之間的延時(shí),單位US,數(shù)值范圍:0~15
{
????UCHAR?mBuffer[mDEFAULT_COMMAND_LEN?+?mDEFAULT_COMMAND_LEN?/?8];
????UCHAR?mBufferTemp[mDEFAULT_COMMAND_LEN?+?mDEFAULT_COMMAND_LEN?/?8];
????ULONG?i,?j,?mLength;
????PUCHAR?mWrBufTemp,mWrBuf;

????//?內(nèi)存分配
????mLength?=?max(iWriteLength,?iReadLength);
????if?(mLength?>?mMAX_BUFFER_LENGTH)
????????return?(FALSE);
????if?(mLength?<=?mDEFAULT_BUFFER_LEN)//?不超過默認(rèn)緩沖區(qū)長度
????{
????????mWrBuf?=?(PUCHAR)mBuffer;
????????mWrBufTemp?=?(PUCHAR)mBufferTemp;
????}
????else?//?超過則需要另外分配內(nèi)存
????{
????????mWrBuf?=?(PUCHAR)LocalAlloc(LMEM_FIXED,?mMAX_COMMAND_LENGTH?+?mMAX_COMMAND_LENGTH?/?8);?//?分配內(nèi)存
????????mWrBufTemp?=?(PUCHAR)LocalAlloc(LMEM_FIXED,?mMAX_COMMAND_LENGTH?+?mMAX_COMMAND_LENGTH?/?8);?//?分配內(nèi)存
????????if?((mWrBuf?==?NULL)?||?(mWrBufTemp?==?NULL))
????????????return?(FALSE);?//?分配內(nèi)存失敗
????}

????//?填充發(fā)送數(shù)據(jù)
????i?=?0;
????//mWrBufTemp[i++]?=?mCH341A_CMD_I2C_STREAM;??//?命令碼,從次字節(jié)開始為I2C命令流
????mWrBufTemp[i++]?=?mCH341A_CMD_I2C_STM_STA;?//?產(chǎn)生起始位

????//?填入發(fā)送數(shù)據(jù)
????j?=?0;
????while?(j?<?iWriteLength)
????{
????????//?填入一個(gè)字節(jié)的數(shù)據(jù)
????????mWrBufTemp[i++]?=?(UCHAR)(mCH341A_CMD_I2C_STM_OUT?|?0x01);?//?輸出數(shù)據(jù),位5-位0為長度
????????mWrBufTemp[i++]?=?*((PUCHAR)iWriteBuffer?+?j++);?//?復(fù)制地址

????????i?+=?CH341_DELAY_US(&mWrBufTemp[i],?iWriteDataDelay);
????}

????if?(iReadLength?>?0)
????{
????????//?填入讀地址與寫地址之間的延遲
????????i?+=?CH341_DELAY_US(&mWrBufTemp[i],?iAddrDelay1);

????????//?填入讀地址
????????mWrBufTemp[i++]?=?mCH341A_CMD_I2C_STM_STA;?//?產(chǎn)生起始位
????????mWrBufTemp[i++]?=?(UCHAR)(mCH341A_CMD_I2C_STM_OUT?|?0x01);?//?輸出數(shù)據(jù),位5-位0為長度
????????mWrBufTemp[i++]?=?*(PUCHAR)iWriteBuffer?|?0x01;?//?I2C目標(biāo)設(shè)備地址,最低位為1則進(jìn)行讀操作

????????//?填入讀地址與讀數(shù)據(jù)之間的延遲
????????i?+=?CH341_DELAY_US(&mWrBufTemp[i],?iAddrDelay2);

????????//?填入讀數(shù)據(jù)
????????for?(j?=?0;?j?<?(iReadLength?-?1);?j++)
????????{
????????????mWrBufTemp[i++]?=?(UCHAR)(mCH341A_CMD_I2C_STM_IN?|?1);????????????????????????????//?輸入數(shù)據(jù),位5-位0為長度
????????????i?+=?CH341_DELAY_US(&mWrBufTemp[i],?iReadDataDelay);
????????}
????????
????????//?填入最后一個(gè)字節(jié)并發(fā)送無應(yīng)答
????????mWrBufTemp[i++]?=?(UCHAR)mCH341A_CMD_I2C_STM_IN;????????????????????????????//?輸入數(shù)據(jù),位5-位0為長度
????????i?+=?CH341_DELAY_US(&mWrBufTemp[i],?iReadDataDelay);
????}

????//?填入結(jié)束命令
????mWrBufTemp[i++]?=?mCH341A_CMD_I2C_STM_STO;????//?產(chǎn)生停止位
????mWrBufTemp[i++]?=?mCH341A_CMD_I2C_STM_END;????//?當(dāng)前包提前結(jié)束

????//?復(fù)制臨時(shí)數(shù)組到發(fā)送數(shù)組,并按照指定長度分割
????mLength?=?i;//?待分配字節(jié)數(shù)
????i?=?0;//?mWrBufTemp序列號
????j?=?0;//?mWrBuf序列號
????while?(mLength?>?(CH341_TX_LEN_MAX?-?1))
????{
????????mWrBuf[j++]?=?mCH341A_CMD_I2C_STREAM;??//?命令碼,從次字節(jié)開始為I2C命令流
????????memcpy(&mWrBuf[j],?&mWrBufTemp[i],?(CH341_TX_LEN_MAX?-?1));???//?填充所有數(shù)據(jù)
????????j?+=?(CH341_TX_LEN_MAX?-?1);
????????i?+=?(CH341_TX_LEN_MAX?-?1);
????????mLength?-=?(CH341_TX_LEN_MAX?-?1);
????}

????//?復(fù)制最后的不足指定長度的數(shù)據(jù)
????mWrBuf[j++]?=?mCH341A_CMD_I2C_STREAM;??//?命令碼,從次字節(jié)開始為I2C命令流
????memcpy(&mWrBuf[j],?&mWrBufTemp[i],?mLength);???//?填充所有數(shù)據(jù)
????j?+=?mLength;
????mLength?=?0;

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

????//?檢測是否讀回所需數(shù)據(jù)
????if?(i?&&?mLength?!=?iReadLength)
????????i?=?FALSE;

????//?釋放分配的內(nèi)存
????if?(mWrBuf?!=?mBuffer)
????{
????????LocalFree(mWrBuf);
????????LocalFree(mWrBufTemp);
????}

????return?(i);
}

? 這兩天測試下來發(fā)現(xiàn)確實(shí)是CH341WriteRead這個(gè)API有BUG,每次點(diǎn)擊讀數(shù)據(jù)時(shí),前32個(gè)數(shù)據(jù)發(fā)送和讀取均正常,從第二個(gè)數(shù)據(jù)流開始時(shí)鐘信號發(fā)送的越來越晚,到第三次重新讀數(shù)據(jù)第二個(gè)數(shù)據(jù)流干脆就沒有時(shí)鐘信號產(chǎn)生了。

? 我試過更換CH341DLL.LIB庫版本也沒有用,所以想請教下有沒有什么解決辦法?或者能提供CH341WriteRead的源碼以便我自行修改嗎?

? 真的很急,謝謝!

? 聯(lián)系方式:個(gè)人信息保護(hù),已隱藏


補(bǔ)貼

增加了讀數(shù)據(jù)復(fù)位操作以防卡死

//?檢測是否讀回所需數(shù)據(jù)
if?(i?&&?mLength?!=?iReadLength)
{
	CH341ResetRead(iIndex);//復(fù)位讀操作以防下次讀數(shù)據(jù)卡死
	i?=?FALSE;
}

未加CH341ResetRead復(fù)位讀操作前第一個(gè)信號流能讀到數(shù)據(jù),第二個(gè)信號流讀不到。

加上之后在復(fù)位之后CH341才正常產(chǎn)生了時(shí)鐘信號,后續(xù)第二個(gè)信號流的數(shù)據(jù)用示波器抓到了


您好,工程師已添加您微信,后續(xù)有問題可隨時(shí)溝通。


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

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