技术天地

EM9170工控主板I2C总线使用方法    发布时间:2011-9-2    被阅览数:

        EM9170提供了一路硬件I2C总线,与GPIO6和GPIO7复用。系统启动后,引脚状态默认为GPIO输入状态。当打开I2C后,系统重新设置GPIO引脚为I2C总线模式。在使用时需要注意,I2C的两条信号线上均要加上拉电阻才能正常使用I2C功能。

 

        在CE6.0操作系统中,I2C资源的使用,需要系统驱动程序作为支持。所以使用时,可以反复调用DeviceIoControl来实现。为了方便使用,英创公司基于驱动程序,封装了4个I2C的操作函数便于应用程序调用,在这4个函数内都是调用DeviceIoControl来实现,相关源码在例程文件夹的I2C.CPP文件中。由于I2C操作时,需要传输的参数量较多,所以在I2C的API函数中使用了一个统一的数据结构来作为参数传递载体,该数据结构的定义如下:

typedef struct
{
        BYTE SlaveAddr; // 要操作的I2C器件的设备物理地址
        WORD RegAddr; // 要操作的设备的存贮器起始地址
        BYTE *pDataBuff; // 要写入/读出的数据BUFF
        int iDLen; // 要写入/读出的数据的字节长度
} I2CParameter , *pI2CParameter;

        在进行I2C操作之前,需要设置I2C设备的物理地址、要操作的存贮器起始地址,数据长度及数据。即定义一个I2CParameter类型的变量并设置相应参数,在调用I2CWrite和I2CRead时,将该变量传递给pI2CParameter类型的指针即可。如:

 

I2CParameter I2C1; // 定义一个I2CParameter结构类型的变量
I2C1.SlaveAddr=0xa0; // I2C设备物理地址设置为0xA0
I2C1.RegAddr=0; // 要操作的I2C设备的寄存器起始地址是0
I2C1.pDataBuff = InBuffer; // I2C操作所分配的BUFF
I2C1.iDLen=50; // 要操作的数据长度是50字节

        EM9170的I2C驱动只支持主机工作模式、最高400KHz的工作时钟,可以多个I2C设备并联,由I2C设备的物理地址来进行区分。封装后的I2C操作函数说明如下:

//----------------------------------------------------------------------------
// I2COpen:该函数主要是打开I2C端口并设置好I2C的工作模式。
// 主要任务是:
// 打开I2C,复位I2C控制器,设置I2C工作在Master模式,设置I2C工作时钟为400KHz
//----------------------------------------------------------------------------
HANDLE I2COpen( );

//----------------------------------------------------------------------------
// I2CWrite:通过已打开的I2C设备进行数据写操作
// 输入参数:
// hDevice:已打开设备的HANDLE值
// pI2CPar:操作I2C设备时I2CParameter类型的指针
// 返回:
// 操作成功 TRUE
// 操作失败 FALSE
//----------------------------------------------------------------------------
bool I2CWrite(HANDLE hDevice , pI2CParameter pI2CPar);

/*----------------------------------------------------------------------------
// I2CRead:通过已打开的I2C设备进行数据读操作
// 输入参数:
// hDevice:已打开设备的HANDLE值
// pI2CPar:操作I2C设备时I2CParameter类型的指针
// 返回:
// 操作成功 TRUE
// 操作失败 FALSE
// ------------------------------------------------------------------------------*/
bool I2CRead(HANDLE hDevice , pI2CParameter pI2CPar);

// ------------------------------------------------------------------------------*/
// I2CClose:关闭I2C端口。
// 在不使用I2C时,需要关闭已打开的I2C端口以对话释放相关资源。
// 输入参数:
// 成功打开的I2C设备的HANDLE值
// 返回:
// 操作成功 TRUE
// 操作失败 FALSE
// ------------------------------------------------------------------------------*/
bool I2CClose( HANDLE hDevice );

        下面是基于上述API函数,对FM24L256铁电存贮器进行测试的例程:

 

HANDLE hI2C;
I2CParameter I2C1;
BYTE InBuffer[50],OutBuffer[50];
int i1;
// 初始化I2C设备参数
I2C1.SlaveAddr=0xa0; // I2C设备物理地址设置,每种器件应有对应的物理地址
I2C1.RegAddr=0; // 要操作的I2C设备的寄存器地址
I2C1.iDLen=50; // 要操作读/写的数据长度
I2C1.pDataBuff = InBuffer; // 数据缓冲区,这里为写入缓冲区
for(i1=0;i1<50;i1++) // 产生测试用的随机数据
{
        InBuffer[i1] = rand() & 0xff;
}
hI2C = I2COpen(); // 打开I2C端口
if( hI2C == NULL )
{
        printf('I2C Open ERR!\r\n');
        return 0;
}
if( I2CWrite( hI2C , &I2C1 ) ) // 向已打开的I2C设备进行写操作
{
        printf('I2C Write Ok:len=%d\r\n',I2C1.iDLen);
        I2C1.pDataBuff = OutBuffer; // 重新设定数据缓冲区,这里为读出缓冲区
        if( I2CRead( hI2C , &I2C1 ) ) // 从已开打的I2C设备读取数据
        {
                printf('I2C Read Ok:len=%d\r\n',I2C1.iDLen);
                for(i1=0;i1<50;i1++) // 写入数据和读出数据进行比较
                {
                        if( InBuffer[i1] != OutBuffer[i1] )
                        {
                                break; 
                        }
                }
                if(i1 == 50)
                        printf('All Test Data OK!\r\n');
                else 
                        printf('Test Data Error:%d\r\n',i1);
        }

I2CClose( hI2C ); // 关闭已打开的I2C端口

        英创公司提供I2C.CPP及测试程序源代码,以供参考。如有需要,请与英创公司联系。

Go Top