请教CH341!

在贵公司的资料下载里看到一个EXAM.C文件: 中有下面四个子函数: /* ********************************************************************************************** */ /* 例子:兼容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 ); }

/* ********************************************************************************************** */

请问,其中检查ACK的两个函数中ACK是一个字节还是一位? 现在碰到这样的问题: _____ _______ __________________________________ |___| |____| ACK 我在开发时的芯片在受到一个ACKbit后立即要发一个BYTE,这种情况能否直接调用:IIC_InBlockByAck 这样的函数? [Emot]4[/Emot] 请教各位前辈!谢谢啦!

应答信号ack是位。IIC总线上的第9个时钟脉冲对应于应答位,相应数据线上低电平时为“应答” 信号,高电平时为“非应答”信号。 当然可以!


呵呵,跟我们的问题很像啊

这样一个时序, ...|A1|A0|R/W|ACK|D7|D6|D5|... 地址帧 |ACK| 数据帧 用下面的程序可不可以呢?谢谢大侠!

IIC_IssueStart(iIndex); //Master发起始位 IIC_OutByteCheckAck(iIndex,0x**); //Master发地址帧 //slaver发ACK握手信号0(bit) IIC_InBlockByAck(iIndex,1, pt_inbuffer++); //slaver发高四位;Master将数据收入inbuffer[0],master产生ACK, IIC_IssueStop(iIndex); //master发停止位


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