SOS!我在使用CH340G(外置晶振)時(shí),初始化時(shí)芯片的輸出電平會(huì)有相應(yīng)變化(而控制系統(tǒng)是不希望這樣的),后來(lái)廠家升級(jí)了驅(qū)動(dòng)程序,這個(gè)問(wèn)題解決了。可是當(dāng)我采用CH340C(無(wú)外置晶振)時(shí),這個(gè)問(wèn)題又出現(xiàn)了,該如何解決呢?請(qǐng)廠家提供解決方案。謝謝了!有高手也望不吝指教!拜托了!順祝節(jié)日快樂(lè)!
您好,請(qǐng)問(wèn)具體所指信號(hào)變化是否為DTR和RTS變化。如果是該2個(gè)信號(hào)在USB插入時(shí)變化,則是因?yàn)轵?qū)動(dòng)版本未更新至最新版本所致,請(qǐng)從如下鏈接中下載驅(qū)動(dòng):http://www.findthetime.net/downloads/CH341SER_EXE.html?
謝謝TECH39的回復(fù)!確實(shí)是DTR和RTS信號(hào)的變化,CH340C插入U(xiǎn)SB時(shí)DTR和RTS沒(méi)有變化,當(dāng)驅(qū)動(dòng)加載后這兩個(gè)信號(hào)就動(dòng)作了,而這時(shí)操作DTR和RTS的命令并沒(méi)有下達(dá)。當(dāng)芯片為CH340G時(shí),通過(guò)升級(jí)CH341SER.EXE可以解決。而當(dāng)芯片為CH340C時(shí),這個(gè)方法不起作用了。鏈接下載的驅(qū)動(dòng)日期為2019/1/30,版本為3.5.2019.1。也就是說(shuō):這個(gè)版本不能解決問(wèn)題。癥結(jié)在哪里呀?還求TECH39繼續(xù)指導(dǎo)為盼!
您好,可以添加我微信單獨(dú)確認(rèn)下問(wèn)題仍然存在的原因。已私信您聯(lián)系方式。
您好!如何添加呀?您的微信號(hào)是啥?盼告。謝謝!
我的微信號(hào):lichenyin2017,EMAIL:個(gè)人信息保護(hù),已隱藏
您好,已添加微信。您可以將如上包含個(gè)人信息回帖刪除,以免收到廣告信息等。
官網(wǎng)CH341A驅(qū)動(dòng)程序無(wú)法適配 ubuntu 5.11.0-37-generic 系統(tǒng),驅(qū)動(dòng)版本過(guò)舊,無(wú)法編譯,需要如何修改驅(qū)動(dòng)程序源代碼!
您好,請(qǐng)單獨(dú)mail給我,我將資料包發(fā)送過(guò)去,有問(wèn)題及時(shí)溝通。我的郵箱地址:zhangj@wch.cn
1、利用CH341對(duì)I2C從站進(jìn)行寫(xiě)操作,代碼如下,結(jié)果成功完成。
? ? ? ? ? ? CH341OpenDevice(0);
? ? ? ? ? ? CH341StreamI2C(0, 18, tx_buf, 0, rx_buf);????// 寫(xiě)入16字節(jié)的數(shù)據(jù)到指定存儲(chǔ)器
? ? ? ? ? ? CH341CloseDevice(0);
2、對(duì)從站進(jìn)行讀操作,代碼如下:
? ? ? ? ? ? CH341OpenDevice(0);
? ? ? ? ? ? IIC_IssueStart(0);????????????????????????? ?// start
? ? ? ? ? ? IIC_OutByteCheckAck(0, 0x80);????// 從站地址=0x40
? ? ? ? ? ? IIC_OutByteCheckAck(0, 0x04);????// 讀取命令
? ? ? ? ? ? IIC_IssueStart(0);????????????????????????? ?// start
? ? ? ? ? ? IIC_OutByteCheckAck(0, 0x81);????// 0x40<<1 + 1
? ? ? ? ? ? IIC_InBlockByAck(0, 15, rx_buf);? ?// 前15個(gè)字節(jié)由主機(jī)ACK
? ? ? ? ? ? IIC_InByteNoAck(0, temp);? ? ? ? ? ?// 最后一個(gè)字節(jié)由主機(jī)NACK
? ? ? ? ? ? rx_buf[15] = temp;
? ? ? ? ? ? IIC_IssueStop(0);
? ? ? ? ? ? CH341CloseDevice(0);
????????????從站是一個(gè)MCU,通過(guò)監(jiān)視可以正常接收到IIC_OutByteCheckAck發(fā)送的數(shù)據(jù),但返回給主機(jī)的數(shù)據(jù)只發(fā)送了2個(gè)字節(jié)(應(yīng)該發(fā)送16個(gè)字節(jié)的),而通過(guò)CH341這邊接收到的數(shù)據(jù)又全部是0xFF。
? ? ? ? ? ? 以上程序是調(diào)用CH341DLL.DLL在VC#環(huán)境下編制的,以前采用其它廠家的USB/I2C轉(zhuǎn)換器都完全調(diào)試通過(guò)了的,因此I2C從站設(shè)備是不會(huì)有問(wèn)題的,現(xiàn)在就是針對(duì)IIC_InBlockByAck和IIC_InByteNoAck這兩個(gè)功能塊有所懷疑,請(qǐng)幫助分析一下,謝謝!
您好,如上提到的功能函數(shù)IIC_InBlockByAck、IIC_InByteNoAck等具體是什么實(shí)現(xiàn),可以把這部分的代碼發(fā)給我們確認(rèn)下。排查I2C的讀寫(xiě)問(wèn)題主要有如下幾個(gè)點(diǎn):
1、CH341的讀I2C,默認(rèn)API在寫(xiě)完設(shè)備+寄存器地址后沒(méi)有delay,要求設(shè)備準(zhǔn)備數(shù)據(jù)足夠快;(若來(lái)不及,可以先通過(guò)CH341SetStream設(shè)置為100Khz的I2C);
2、CH341默認(rèn)是忽略I2C設(shè)備的ACK狀態(tài)的,即設(shè)備是ACK或NACK,不影響API返回結(jié)果;
提到的返回給主機(jī)的數(shù)據(jù)只發(fā)送2個(gè)字節(jié)(應(yīng)該16字節(jié)):關(guān)于這段話,主機(jī)讀取的字節(jié)是主機(jī)決定,不是設(shè)備決定,讀取16字節(jié)CH341StreamI2C中的讀長(zhǎng)度設(shè)置為16即可。
1、已被驗(yàn)證可正確執(zhí)行的3個(gè)子程序:
? ? ? ? public bool IIC_IssueStart(UInt32 iIndex)
? ? ? ? {
? ? ? ? ? ? byte[] mBuffer = new byte[3];
? ? ? ? ? ? UInt32 mLength;
? ? ? ? ? ? mBuffer[0] = mCH341A_CMD_I2C_STREAM;
? ? ? ? ? ? mBuffer[1] = mCH341A_CMD_I2C_STM_STA;
? ? ? ? ? ? mBuffer[2] = mCH341A_CMD_I2C_STM_END;
? ? ? ? ? ? mLength = 3;
? ? ? ? ? ? return (CH341WriteData(iIndex, mBuffer, ref mLength));
? ? ? ? }
? ? ? ? public bool IIC_IssueStop(UInt32 iIndex)
? ? ? ? {
? ? ? ? ? ? byte[] mBuffer = new byte[3];
? ? ? ? ? ? UInt32 mLength;
? ? ? ? ? ? mBuffer[0] = mCH341A_CMD_I2C_STREAM;
? ? ? ? ? ? mBuffer[1] = mCH341A_CMD_I2C_STM_STO;
? ? ? ? ? ? mBuffer[2] = mCH341A_CMD_I2C_STM_END;
? ? ? ? ? ? mLength = 3;
? ? ? ? ? ? return (CH341WriteData(iIndex, mBuffer, ref mLength));
? ? ? ? }
? ? ? ? public bool IIC_OutByteCheckAck(UInt32 iIndex, byte iOutByte)
? ? ? ? {
? ? ? ? ? ? byte[] mBuffer = new byte[10];
? ? ? ? ? ? UInt32 mLength, mInLen;
? ? ? ? ? ? mBuffer[0] = mCH341A_CMD_I2C_STREAM;
? ? ? ? ? ? mBuffer[1] = mCH341A_CMD_I2C_STM_OUT;
? ? ? ? ? ? mBuffer[2] = iOutByte;
? ? ? ? ? ? mBuffer[3] = mCH341A_CMD_I2C_STM_END;
? ? ? ? ? ? mLength = 4;
? ? ? ? ? ? mInLen = 0;
? ? ? ? ? ? if (CH341WriteRead(iIndex, mLength, mBuffer, 32, 1, ref mInLen, mBuffer) == true)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if ((mInLen > 0) && ((mBuffer[mInLen-1] & 0x80) == 0))
? ? ? ? ? ? ? ? ? ? return (true);
? ? ? ? ? ? }
? ? ? ? ? ? return (false);
? ? ? ? }
??
2、執(zhí)行結(jié)果不正確的2個(gè)子程序:?
? ? ? ? public bool IIC_InBlockByAck(UInt32 iIndex, UInt32 iInLength, byte[] oInBuffer)
? ? ? ? {
? ? ? ? ? ? byte[] mBuffer = new byte[40];
? ? ? ? ? ? UInt32 mLength, mInLen;
? ? ? ? ? ? if ((iInLength == 0) || (iInLength > 32))
? ? ? ? ? ? ? ? return (false);
? ? ? ? ? ? mBuffer[0] = mCH341A_CMD_I2C_STREAM;
? ? ? ? ? ? mBuffer[1] = (byte)(mCH341A_CMD_I2C_STM_IN |iInLength);
? ? ? ? ? ? mBuffer[2] = mCH341A_CMD_I2C_STM_END;
? ? ? ? ? ? mLength = 3;
? ? ? ? ? ? mInLen = 0;
? ? ? ? ? ? if(CH341WriteRead(iIndex, mLength, mBuffer, 32, 1, ref mInLen, mBuffer)==true)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if (mInLen == iInLength)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? for (int i = 0; i < iInLength; i++)
? ? ? ? ? ? ? ? ? ? ? ? oInBuffer[i] = mBuffer[i];
? ? ? ? ? ? ? ? ? ? return (true);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? return(false);
? ? ? ? }
? ? ? ? public bool IIC_InByteNoAck(UInt32 iIndex, ref byte oInByte)
? ? ? ? {
? ? ? ? ? ? byte[] mBuffer = new byte[4];
? ? ? ? ? ? byte[] nBuffer = new byte[40];
? ? ? ? ? ? UInt32 mLength, mInLen;
? ? ? ? ? ? mBuffer[0] = mCH341A_CMD_I2C_STREAM;
? ? ? ? ? ? mBuffer[1] = mCH341A_CMD_I2C_STM_IN;
? ? ? ? ? ? mBuffer[2] = mCH341A_CMD_I2C_STM_END;
? ? ? ? ? ? mLength = 3;
? ? ? ? ? ? mInLen = 0;
? ? ? ? ? ? if(CH341WriteRead(iIndex,mLength,mBuffer,32,1,ref mInLen,nBuffer)==true)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if(mInLen > 0 )
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? oInByte = nBuffer[mInLen-1];
? ? ? ? ? ? ? ? ? ? return(true);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? return(false);
? ? ? ? }
從機(jī)只發(fā)送了2個(gè)字節(jié)是這樣的:從機(jī)MCU是通過(guò)中斷來(lái)發(fā)送數(shù)據(jù)的,每中斷一次增加一次發(fā)送計(jì)數(shù)器,目前這個(gè)指令(0x04)執(zhí)行后已經(jīng)把要發(fā)送的數(shù)據(jù)放到了發(fā)送緩沖區(qū)(0x3F,0x9D,0x70,0xA4,.....)共16個(gè)字節(jié),但響應(yīng)完指令后發(fā)送計(jì)數(shù)器=2,上位機(jī)接收到的數(shù)據(jù)為:0x1F,0xFF,0xFF,0xFF,.....共16個(gè)字節(jié)。
當(dāng)發(fā)送緩沖區(qū)數(shù)據(jù)=0x40,....共16個(gè)字節(jié)時(shí),已發(fā)送的字節(jié)還是=2,但上位機(jī)收的數(shù)據(jù)為:0x20,0xFF,0xFF,...16個(gè)字節(jié),感覺(jué)像數(shù)據(jù)錯(cuò)位或時(shí)鐘過(guò)快。
?? ? ? ? ? IIC_IssueStart(0);????????????????????????? ?// start
? ? ? ? ? ? IIC_OutByteCheckAck(0, 0x80);????// 從站地址=0x40
? ? ? ? ? ? IIC_OutByteCheckAck(0, 0x04);????// 讀取命令
(CH341的讀I2C,因?yàn)閷?xiě)完設(shè)備+寄存器地址后沒(méi)有delay,要求設(shè)備準(zhǔn)備數(shù)據(jù)足夠快;
? ? ? ? ? ?那我在這里加入一條延時(shí)語(yǔ)句,是否有用?)
? ? ? ? ? ? IIC_IssueStart(0);????????????????????????? ?// start
? ? ? ? ? ? IIC_OutByteCheckAck(0, 0x81);????// 0x40<<1 + 1
? ? ? ? ? ? IIC_InBlockByAck(0, 15, rx_buf);? ?// 前15個(gè)字節(jié)由主機(jī)ACK
? ? ? ? ? ? IIC_InByteNoAck(0, temp);? ? ? ? ? ?// 最后一個(gè)字節(jié)由主機(jī)NACK
? ? ? ? ? ? rx_buf[15] = temp;
? ? ? ? ? ? IIC_IssueStop(0);
您好,因?yàn)镮2C的讀操作需要Repeat Start,進(jìn)行讀操作的時(shí)候需要先Write設(shè)備地址(有寄存器地址),如果是采用單獨(dú)的?IIC_OutByteCheckAck函數(shù)再讀,則會(huì)沒(méi)有Repeat Start信號(hào)。您可以發(fā)郵件給我,我整理下Code發(fā)您。此外,有邏輯分析儀的話可以同步抓下I2C時(shí)序,定位問(wèn)題會(huì)更便捷些。