[求助]CH341A I2C 讀寫Micro Controlle

CH341A I2C 讀取Micro Controlle發現回傳數據時無ACK有效位,圖形如下圖:

2011121414495598.jpg

Up!


再頂,貴司技術支持人員呢?


请问你使用的是CH341StreamI2C吗? CH341StreamI2C不支持应答。 请使用下面的函数替换 /* ********************************************************************************************** */ /* 例子:兼容IIC总线的通用操作时序 */

BOOL WINAPI IIC_IssueStart( ULONG iIndex ) // 指定CH341设备序号 { UCHAR mBuffer[ mCH341_PACKET_LENGTH ]; ULONG 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, &mLength ) ); // 写出数据块 }

BOOL WINAPI IIC_IssueStop( ULONG iIndex ) // 指定CH341设备序号 { UCHAR mBuffer[ mCH341_PACKET_LENGTH ]; ULONG 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, &mLength ) ); // 写出数据块 }

BOOL WINAPI IIC_OutBlockSkipAck( // 输出数据块,不检查应答 ULONG iIndex, // 指定CH341设备序号 ULONG iOutLength, // 准备写出的数据字节数,单次必须小于29字节 PVOID iOutBuffer ) // 指向一个缓冲区,放置准备写出的数据 { UCHAR mBuffer[ mCH341_PACKET_LENGTH ]; ULONG mLength; if ( iOutLength == 0 || iOutLength > ( mCH341_PACKET_LENGTH - 1 - 1 - 1 ) ) return( FALSE ); mBuffer[ 0 ] = mCH341A_CMD_I2C_STREAM; // 命令码 mBuffer[ 1 ] = (UCHAR)( mCH341A_CMD_I2C_STM_OUT | iOutLength ); // 输出数据,位5-位0为长度 memcpy( &mBuffer[2], iOutBuffer, iOutLength ); // 数据 mBuffer[ 1 + 1 + iOutLength ] = mCH341A_CMD_I2C_STM_END; // 当前包提前结束 mLength = 1 + 1 + iOutLength + 1; return( CH341WriteData( iIndex, mBuffer, &mLength ) ); // 写出数据块 }

BOOL WINAPI IIC_OutByteCheckAck( // 输出一字节数据并检查应答是否有效 ULONG iIndex, // 指定CH341设备序号 UCHAR iOutByte ) // 准备写出的数据 { UCHAR mBuffer[ mCH341_PACKET_LENGTH ]; ULONG mLength, mInLen; mBuffer[ 0 ] = mCH341A_CMD_I2C_STREAM; // 命令码 mBuffer[ 1 ] = mCH341A_CMD_I2C_STM_OUT; // 输出数据,位5-位0为长度,0长度则只发送一个字节并返回应答 mBuffer[ 2 ] = iOutByte; // 数据 mBuffer[ 3 ] = mCH341A_CMD_I2C_STM_END; // 当前包提前结束 mLength = 4; mInLen = 0; if ( CH341WriteRead( iIndex, mLength, mBuffer, mCH341A_CMD_I2C_STM_MAX, 1, &mInLen, mBuffer ) ) { // 执行数据流命令,先输出再输入 if ( mInLen && ( mBuffer[ mInLen - 1 ] & 0x80 ) == 0 ) return( TRUE ); // 返回的数据的位7代表ACK应答位,ACK=0有效 } return( FALSE ); }

BOOL WINAPI IIC_InBlockByAck( // 输入数据块,每输入一个字节都产生有效应答 ULONG iIndex, // 指定CH341设备序号 ULONG iInLength, // 准备读取的数据字节数,单次必须小于32字节 PVOID oInBuffer ) // 指向一个缓冲区,返回后是读入的数据 { UCHAR mBuffer[ mCH341_PACKET_LENGTH ]; ULONG mLength, mInLen; if ( iInLength == 0 || iInLength > mCH341A_CMD_I2C_STM_MAX ) return( FALSE ); mBuffer[ 0 ] = mCH341A_CMD_I2C_STREAM; // 命令码 mBuffer[ 1 ] = (UCHAR)( mCH341A_CMD_I2C_STM_IN | iInLength ); // 输入数据,位5-位0为长度 mBuffer[ 2 ] = mCH341A_CMD_I2C_STM_END; // 当前包提前结束 mLength = 3; mInLen = 0; if ( CH341WriteRead( iIndex, mLength, mBuffer, mCH341A_CMD_I2C_STM_MAX, 1, &mInLen, mBuffer ) ) { // 执行数据流命令,先输出再输入 if ( mInLen == iInLength ) { memcpy( oInBuffer, &mBuffer[0], iInLength ); // 数据 return( TRUE ); } } return( FALSE ); }

BOOL WINAPI IIC_InByteNoAck( // 输入一字节数据,但是不产生应答 ULONG iIndex, // 指定CH341设备序号 PUCHAR oInByte ) // 指向一个字节的缓冲区,返回后是读入的数据 { UCHAR mBuffer[ mCH341_PACKET_LENGTH ]; ULONG mLength, mInLen; mBuffer[ 0 ] = mCH341A_CMD_I2C_STREAM; // 命令码 mBuffer[ 1 ] = mCH341A_CMD_I2C_STM_IN; // 输入数据,位5-位0为长度,0长度则只接收一个字节并发送无应答 mBuffer[ 2 ] = mCH341A_CMD_I2C_STM_END; // 当前包提前结束 mLength = 3; mInLen = 0; if ( CH341WriteRead( iIndex, mLength, mBuffer, mCH341A_CMD_I2C_STM_MAX, 1, &mInLen, mBuffer ) ) { // 执行数据流命令,先输出再输入 if ( mInLen ) { *oInByte = mBuffer[ mInLen - 1 ]; // 数据 return( TRUE ); } } return( FALSE ); }


感謝回復,確實是在用CH341StreamI2C,用您提供的方法再試試看。


只有登录才能回复,可以选择微信账号登录