⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c_exam.c

📁 USB2I2C USB2SPI USB2ISP资料开发包
💻 C
📖 第 1 页 / 共 2 页
字号:
// V1.2

#include	<windows.h>
#include	"USBIOX.H"

/* 本程序涉及到
 1、2线接口TWI的一些自定义时序,处理I2C总线的应答位,以及了解2线接口的内部时序分析
 2、提供例子程序,操作2线接口I2C器件X76F640、PCF8574、PCA9554
*/

/* USB2I2C驱动及DLL的API层次,按从低向高分为
 1、USBIO_WriteData只写数据, USBIO_ReadData只读数据, USBIO_WriteRead先写数据再读数据
 2、USBIO_StreamI2C先写I2C,可选地再读I2C (内部调用USBIO_WriteData和USBIO_WriteRead)
 3、USBIO_ReadEEPROM读EEPROM数据, USBIO_WriteEEPROM写EEPROM数据 (内部调用USBIO_StreamI2C)
 本例子中的子程序将调用USBIO_WriteData、USBIO_WriteRead、USBIO_StreamI2C等DLL中的API */

/* 实测速度
   USBIO_StreamI2C     约56K字节
   USBIO_ReadEEPROM    约56K字节
   USBIO_WriteEEPROM   约5K字节(如果是RAM而非闪存那么与USBIO_ReadEEPROM速度相同)
*/

/* ********************************************************************************************** */
/* 兼容I2C总线的通用操作时序 */

BOOL	WINAPI	I2C_IssueStart(
	ULONG			iIndex )  // 指定USB2I2C设备序号
{
	UCHAR	mBuffer[ mUSBIO_PACKET_LENGTH ];
	ULONG	mLength;
	mBuffer[ 0 ] = mUSBIOSS_CMD_I2C_STREAM;  // 命令码
	mBuffer[ 1 ] = mUSBIOSS_CMD_I2C_STM_STA;  // 产生起始位
	mBuffer[ 2 ] = mUSBIOSS_CMD_I2C_STM_END;  // 当前包提前结束
	mLength = 3;
	return( USBIO_WriteData( iIndex, mBuffer, &mLength ) );  // 写出数据块
}

BOOL	WINAPI	I2C_IssueStop(
	ULONG			iIndex )  // 指定USB2I2C设备序号
{
	UCHAR	mBuffer[ mUSBIO_PACKET_LENGTH ];
	ULONG	mLength;
	mBuffer[ 0 ] = mUSBIOSS_CMD_I2C_STREAM;  // 命令码
	mBuffer[ 1 ] = mUSBIOSS_CMD_I2C_STM_STO;  // 产生停止位
	mBuffer[ 2 ] = mUSBIOSS_CMD_I2C_STM_END;  // 当前包提前结束
	mLength = 3;
	return( USBIO_WriteData( iIndex, mBuffer, &mLength ) );  // 写出数据块
}

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

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

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

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

/* ********************************************************************************************** */
/* 操作加密存储器X76F640 */

BOOL	WINAPI	X76F640_AckPolling(  // 查询X76F640应答 (包括:输出起始位,输出一字节命令数据,检查应答是否有效)
	ULONG			iIndex )  // 指定USB2I2C设备序号
{
	UCHAR	mBuffer[ mUSBIO_PACKET_LENGTH ];
	ULONG	mLength, mInLen;
	mBuffer[ 0 ] = mUSBIOSS_CMD_I2C_STREAM;  // 命令码
	mBuffer[ 1 ] = mUSBIOSS_CMD_I2C_STM_STA;  // 产生起始位
	mBuffer[ 2 ] = mUSBIOSS_CMD_I2C_STM_OUT;  // 输出数据,位5-位0为长度,0长度则只发送一个字节并返回应答
	mBuffer[ 3 ] = 0xF0;  // 应答查询操作的命令码
	mBuffer[ 4 ] = mUSBIOSS_CMD_I2C_STM_END;  // 当前包提前结束
	mLength = 5;
	mInLen = 0;
	if ( USBIO_WriteRead( iIndex, mLength, mBuffer, mUSBIOSS_CMD_I2C_STM_MAX, 1, &mInLen, mBuffer ) ) {  // 执行数据流命令,先输出再输入
		if ( mInLen && ( mBuffer[ mInLen - 1 ] & 0x80 ) == 0 ) return( TRUE );  // 返回的数据的位7代表ACK应答位,ACK=0有效
	}
	return( FALSE );
}

BOOL	WINAPI	X76F640_CheckPasswd(  // 发出操作命令并检查指定的密码 (包括:输出起始位,输出9字节数据(1命令+8密码),查询应答,输出2字节地址)
	ULONG			iIndex,  // 指定USB2I2C设备序号
	ULONG			iCommand,  // 操作命令码
	PVOID			iPasswdBuf,  // 指向一个缓冲区,提供8字节的密码数据
	ULONG			iAddress )  // 指定操作地址或者密码后的2字节数据
{
	UCHAR	mBuffer[ mUSBIO_PACKET_LENGTH ];
	ULONG	i, mLength;
	i = 0;
	mBuffer[ i++ ] = mUSBIOSS_CMD_I2C_STREAM;  // 命令码
	mBuffer[ i++ ] = mUSBIOSS_CMD_I2C_STM_STA;  // 产生起始位
	mBuffer[ i++ ] = (UCHAR)( mUSBIOSS_CMD_I2C_STM_OUT | 9 );  // 输出数据,位5-位0为长度,9字节
	mBuffer[ i++ ] = (UCHAR)iCommand;  // 操作命令码
	memcpy( &mBuffer[ i ], iPasswdBuf, 8 );  // 8字节密码数据
	i += 8;
	mBuffer[ i++ ] = (UCHAR)( mUSBIOSS_CMD_I2C_STM_MS | 10 );  // 以亳秒为单位延时,位3-位0为延时值,延时10毫秒
	mBuffer[ i++ ] = mUSBIOSS_CMD_I2C_STM_END;  // 当前包提前结束
	mLength = i;
	if ( USBIO_WriteData( iIndex, mBuffer, &mLength ) ) {  // 写出数据块
		if ( X76F640_AckPolling( iIndex ) ) {  // 查询应答有效
			i = 0;
			mBuffer[ i++ ] = mUSBIOSS_CMD_I2C_STREAM;  // 命令码
			mBuffer[ i++ ] = (UCHAR)( mUSBIOSS_CMD_I2C_STM_OUT | 2 );  // 输出数据,位5-位0为长度
			mBuffer[ i++ ] = (UCHAR)( iAddress & 0x00FF );  // 地址低8位
			mBuffer[ i++ ] = (UCHAR)( ( iAddress >> 8 ) & 0x00FF );  // 地址高8位

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -