?? i2c_exam.c
字號:
// V1.2
#include <windows.h>
#include "USBIOX.H"
/* 本程序涉及到
1、2線接口TWI的一些自定義時(shí)序,處理I2C總線的應(yīng)答位,以及了解2線接口的內(nèi)部時(shí)序分析
2、提供例子程序,操作2線接口I2C器件X76F640、PCF8574、PCA9554
*/
/* USB2I2C驅(qū)動及DLL的API層次,按從低向高分為
1、USBIO_WriteData只寫數(shù)據(jù), USBIO_ReadData只讀數(shù)據(jù), USBIO_WriteRead先寫數(shù)據(jù)再讀數(shù)據(jù)
2、USBIO_StreamI2C先寫I2C,可選地再讀I2C (內(nèi)部調(diào)用USBIO_WriteData和USBIO_WriteRead)
3、USBIO_ReadEEPROM讀EEPROM數(shù)據(jù), USBIO_WriteEEPROM寫EEPROM數(shù)據(jù) (內(nèi)部調(diào)用USBIO_StreamI2C)
本例子中的子程序?qū)⒄{(diào)用USBIO_WriteData、USBIO_WriteRead、USBIO_StreamI2C等DLL中的API */
/* 實(shí)測速度
USBIO_StreamI2C 約56K字節(jié)
USBIO_ReadEEPROM 約56K字節(jié)
USBIO_WriteEEPROM 約5K字節(jié)(如果是RAM而非閃存那么與USBIO_ReadEEPROM速度相同)
*/
/* ********************************************************************************************** */
/* 兼容I2C總線的通用操作時(shí)序 */
BOOL WINAPI I2C_IssueStart(
ULONG iIndex ) // 指定USB2I2C設(shè)備序號
{
UCHAR mBuffer[ mUSBIO_PACKET_LENGTH ];
ULONG mLength;
mBuffer[ 0 ] = mUSBIOSS_CMD_I2C_STREAM; // 命令碼
mBuffer[ 1 ] = mUSBIOSS_CMD_I2C_STM_STA; // 產(chǎn)生起始位
mBuffer[ 2 ] = mUSBIOSS_CMD_I2C_STM_END; // 當(dāng)前包提前結(jié)束
mLength = 3;
return( USBIO_WriteData( iIndex, mBuffer, &mLength ) ); // 寫出數(shù)據(jù)塊
}
BOOL WINAPI I2C_IssueStop(
ULONG iIndex ) // 指定USB2I2C設(shè)備序號
{
UCHAR mBuffer[ mUSBIO_PACKET_LENGTH ];
ULONG mLength;
mBuffer[ 0 ] = mUSBIOSS_CMD_I2C_STREAM; // 命令碼
mBuffer[ 1 ] = mUSBIOSS_CMD_I2C_STM_STO; // 產(chǎn)生停止位
mBuffer[ 2 ] = mUSBIOSS_CMD_I2C_STM_END; // 當(dāng)前包提前結(jié)束
mLength = 3;
return( USBIO_WriteData( iIndex, mBuffer, &mLength ) ); // 寫出數(shù)據(jù)塊
}
BOOL WINAPI I2C_OutBlockSkipAck( // 輸出數(shù)據(jù)塊,不檢查應(yīng)答
ULONG iIndex, // 指定USB2I2C設(shè)備序號
ULONG iOutLength, // 準(zhǔn)備寫出的數(shù)據(jù)字節(jié)數(shù),單次必須小于29字節(jié)
PVOID iOutBuffer ) // 指向一個緩沖區(qū),放置準(zhǔn)備寫出的數(shù)據(jù)
{
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 ); // 輸出數(shù)據(jù),位5-位0為長度
memcpy( &mBuffer[2], iOutBuffer, iOutLength ); // 數(shù)據(jù)
mBuffer[ 1 + 1 + iOutLength ] = mUSBIOSS_CMD_I2C_STM_END; // 當(dāng)前包提前結(jié)束
mLength = 1 + 1 + iOutLength + 1;
return( USBIO_WriteData( iIndex, mBuffer, &mLength ) ); // 寫出數(shù)據(jù)塊
}
BOOL WINAPI I2C_OutByteCheckAck( // 輸出一字節(jié)數(shù)據(jù)并檢查應(yīng)答是否有效
ULONG iIndex, // 指定USB2I2C設(shè)備序號
UCHAR iOutByte ) // 準(zhǔn)備寫出的數(shù)據(jù)
{
UCHAR mBuffer[ mUSBIO_PACKET_LENGTH ];
ULONG mLength, mInLen;
mBuffer[ 0 ] = mUSBIOSS_CMD_I2C_STREAM; // 命令碼
mBuffer[ 1 ] = mUSBIOSS_CMD_I2C_STM_OUT; // 輸出數(shù)據(jù),位5-位0為長度,0長度則只發(fā)送一個字節(jié)并返回應(yīng)答
mBuffer[ 2 ] = iOutByte; // 數(shù)據(jù)
mBuffer[ 3 ] = mUSBIOSS_CMD_I2C_STM_END; // 當(dāng)前包提前結(jié)束
mLength = 4;
mInLen = 0;
if ( USBIO_WriteRead( iIndex, mLength, mBuffer, mUSBIOSS_CMD_I2C_STM_MAX, 1, &mInLen, mBuffer ) ) { // 執(zhí)行數(shù)據(jù)流命令,先輸出再輸入
if ( mInLen && ( mBuffer[ mInLen - 1 ] & 0x80 ) == 0 ) return( TRUE ); // 返回的數(shù)據(jù)的位7代表ACK應(yīng)答位,ACK=0有效
}
return( FALSE );
}
BOOL WINAPI I2C_InBlockByAck( // 輸入數(shù)據(jù)塊,每輸入一個字節(jié)都產(chǎn)生有效應(yīng)答
ULONG iIndex, // 指定USB2I2C設(shè)備序號
ULONG iInLength, // 準(zhǔn)備讀取的數(shù)據(jù)字節(jié)數(shù),單次必須小于32字節(jié)
PVOID oInBuffer ) // 指向一個緩沖區(qū),返回后是讀入的數(shù)據(jù)
{
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 ); // 輸入數(shù)據(jù),位5-位0為長度
mBuffer[ 2 ] = mUSBIOSS_CMD_I2C_STM_END; // 當(dāng)前包提前結(jié)束
mLength = 3;
mInLen = 0;
if ( USBIO_WriteRead( iIndex, mLength, mBuffer, mUSBIOSS_CMD_I2C_STM_MAX, 1, &mInLen, mBuffer ) ) { // 執(zhí)行數(shù)據(jù)流命令,先輸出再輸入
if ( mInLen == iInLength ) {
memcpy( oInBuffer, &mBuffer[0], iInLength ); // 數(shù)據(jù)
return( TRUE );
}
}
return( FALSE );
}
BOOL WINAPI I2C_InByteNoAck( // 輸入一字節(jié)數(shù)據(jù),但是不產(chǎn)生應(yīng)答
ULONG iIndex, // 指定USB2I2C設(shè)備序號
PUCHAR oInByte ) // 指向一個字節(jié)的緩沖區(qū),返回后是讀入的數(shù)據(jù)
{
UCHAR mBuffer[ mUSBIO_PACKET_LENGTH ];
ULONG mLength, mInLen;
mBuffer[ 0 ] = mUSBIOSS_CMD_I2C_STREAM; // 命令碼
mBuffer[ 1 ] = mUSBIOSS_CMD_I2C_STM_IN; // 輸入數(shù)據(jù),位5-位0為長度,0長度則只接收一個字節(jié)并發(fā)送無應(yīng)答
mBuffer[ 2 ] = mUSBIOSS_CMD_I2C_STM_END; // 當(dāng)前包提前結(jié)束
mLength = 3;
mInLen = 0;
if ( USBIO_WriteRead( iIndex, mLength, mBuffer, mUSBIOSS_CMD_I2C_STM_MAX, 1, &mInLen, mBuffer ) ) { // 執(zhí)行數(shù)據(jù)流命令,先輸出再輸入
if ( mInLen ) {
*oInByte = mBuffer[ mInLen - 1 ]; // 數(shù)據(jù)
return( TRUE );
}
}
return( FALSE );
}
/* ********************************************************************************************** */
/* 操作加密存儲器X76F640 */
BOOL WINAPI X76F640_AckPolling( // 查詢X76F640應(yīng)答 (包括:輸出起始位,輸出一字節(jié)命令數(shù)據(jù),檢查應(yīng)答是否有效)
ULONG iIndex ) // 指定USB2I2C設(shè)備序號
{
UCHAR mBuffer[ mUSBIO_PACKET_LENGTH ];
ULONG mLength, mInLen;
mBuffer[ 0 ] = mUSBIOSS_CMD_I2C_STREAM; // 命令碼
mBuffer[ 1 ] = mUSBIOSS_CMD_I2C_STM_STA; // 產(chǎn)生起始位
mBuffer[ 2 ] = mUSBIOSS_CMD_I2C_STM_OUT; // 輸出數(shù)據(jù),位5-位0為長度,0長度則只發(fā)送一個字節(jié)并返回應(yīng)答
mBuffer[ 3 ] = 0xF0; // 應(yīng)答查詢操作的命令碼
mBuffer[ 4 ] = mUSBIOSS_CMD_I2C_STM_END; // 當(dāng)前包提前結(jié)束
mLength = 5;
mInLen = 0;
if ( USBIO_WriteRead( iIndex, mLength, mBuffer, mUSBIOSS_CMD_I2C_STM_MAX, 1, &mInLen, mBuffer ) ) { // 執(zhí)行數(shù)據(jù)流命令,先輸出再輸入
if ( mInLen && ( mBuffer[ mInLen - 1 ] & 0x80 ) == 0 ) return( TRUE ); // 返回的數(shù)據(jù)的位7代表ACK應(yīng)答位,ACK=0有效
}
return( FALSE );
}
BOOL WINAPI X76F640_CheckPasswd( // 發(fā)出操作命令并檢查指定的密碼 (包括:輸出起始位,輸出9字節(jié)數(shù)據(jù)(1命令+8密碼),查詢應(yīng)答,輸出2字節(jié)地址)
ULONG iIndex, // 指定USB2I2C設(shè)備序號
ULONG iCommand, // 操作命令碼
PVOID iPasswdBuf, // 指向一個緩沖區(qū),提供8字節(jié)的密碼數(shù)據(jù)
ULONG iAddress ) // 指定操作地址或者密碼后的2字節(jié)數(shù)據(jù)
{
UCHAR mBuffer[ mUSBIO_PACKET_LENGTH ];
ULONG i, mLength;
i = 0;
mBuffer[ i++ ] = mUSBIOSS_CMD_I2C_STREAM; // 命令碼
mBuffer[ i++ ] = mUSBIOSS_CMD_I2C_STM_STA; // 產(chǎn)生起始位
mBuffer[ i++ ] = (UCHAR)( mUSBIOSS_CMD_I2C_STM_OUT | 9 ); // 輸出數(shù)據(jù),位5-位0為長度,9字節(jié)
mBuffer[ i++ ] = (UCHAR)iCommand; // 操作命令碼
memcpy( &mBuffer[ i ], iPasswdBuf, 8 ); // 8字節(jié)密碼數(shù)據(jù)
i += 8;
mBuffer[ i++ ] = (UCHAR)( mUSBIOSS_CMD_I2C_STM_MS | 10 ); // 以亳秒為單位延時(shí),位3-位0為延時(shí)值,延時(shí)10毫秒
mBuffer[ i++ ] = mUSBIOSS_CMD_I2C_STM_END; // 當(dāng)前包提前結(jié)束
mLength = i;
if ( USBIO_WriteData( iIndex, mBuffer, &mLength ) ) { // 寫出數(shù)據(jù)塊
if ( X76F640_AckPolling( iIndex ) ) { // 查詢應(yīng)答有效
i = 0;
mBuffer[ i++ ] = mUSBIOSS_CMD_I2C_STREAM; // 命令碼
mBuffer[ i++ ] = (UCHAR)( mUSBIOSS_CMD_I2C_STM_OUT | 2 ); // 輸出數(shù)據(jù),位5-位0為長度
mBuffer[ i++ ] = (UCHAR)( iAddress & 0x00FF ); // 地址低8位
mBuffer[ i++ ] = (UCHAR)( ( iAddress >> 8 ) & 0x00FF ); // 地址高8位
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -