https://static.assets-stash.eet-china.com/album/old-resources/2008/11/7/398834db-aa32-4f10-bb3f-70b8d32200fd.rarhttps://static.assets-stash.eet-china.com/album/old-resources/2008/11/7/bd4e48c2-b333-4bb6-97b9-12e78aeffc8e.rar I2C总线应用(ISL12028篇)
摘要:EZ USB FX2 是Cyp ress 公司推出的U SB 2.0 控制器, 其片内集成的I2C 总线控制器可以很好地实现与一些串行外设的无缝接口。本文介绍了EZ U SB FX2 芯片内集成的I2C 总线控制器的特性,并详细说明了其应用于日历芯片ISL12028实时时钟芯片寄存器的配置以及时间值的输出;最后给出了日历芯片的操作固件程序。
EZ U SB FX2 (FX2) 是Cyp ress 公司推出的U SB 2.0控制器, 当用于高速数据采集系统时, 其片内集成的I2C 总线控制器可以很好地实现与一些串行外设(如串行存储器、串行A D 转换器等) 的无缝接口。本文介绍了FX2 片内I2C总线控制器实现I2C 协议,I2C总线的读写操作流程,并将I2C总线应用于日历芯片的实际写寄存器和读寄存器的操作中,完成了传感器实验板的实时时钟部分。
1.FX2 片内I2C 总线控制器的特性
FX2 芯片内集成的I2C 总线控制器具有2 种功能: 启动加载数据和通用I2C 总线接口。其中, 启动加载数据就是当芯片上电复位后, 通过检查其I2C 总线上是否连接有串行E2PROM , 以决定采用何种设备固件加载方式; 通用I2C 总线接口可以很方便地连接一些串行外设。其I2C 总线的默认传输速率为100 kbs, 可以被配置成快速方式, 传输速率可达400 kbs。FX2 只作为主设备, 任何总线冲突将产生一个
错误位, 中断数据的传输。另外, 芯片的串行数据线(SDA )和串行时钟线(SCL ) 需分别连接223的上拉电阻。
FX2 中I2C 总线寄存器如表1 所示, I2DA T 为8 bit 数据寄存器, 负责数据的读入或送出; I2CTL 为配置寄存器,负责配置总线; I2CS 为控制状态寄存器, 负责控制传输和报告各种状态。
表1 FX2 中I2C 总线控制器寄存器
地址 名称 b7 b6 b5 b4 b3 b2 b1 b0
E678 I2CS START STOP LASTRD ID1 ID0 BERR ACK DON E
E679 I2DAT D7 D6 D5 D4 D3 D2 D1 D0
E67A I2CTL 0 0 0 0 0 0 STOPE 400 kHz
开始控制位START 当START 位被配置为1, 写入数据到I2DAT, 开启I2C 总线数据传输。此位在接收器的应答信号期间自动清零。
停止控制位STOP 当STOP 位被配置为1, 当前总线数据传输完后, 停止I2C 总线数据传输。此位在总线停止传输数据后自动清零。
错误状态位BERR 当总线上出现错误时, BERR 位被置为1。此位也可自动清零。
应答信号状态位ACK ACK 位为1 时, 表示接收器成功接受数据; 反之, 表示数据传输失败。此位在读传输时被忽略。
状态位DONE 当完成1B 数据传输后, FX2 设置DON E 位, 并产生中断。当读或写I2DAT 寄存器时, 此位自动清零。
由上可知, 只要正确配置或读取I2CS 和I2CTL 中相应的状态位, 并向I2DA T 中写入数据或从其中读出数据,就能完成I2C 总线数据的传输, 即EZ U SB FX2 通过表1中的3 个寄存器实现了I2C 总线协议, 方便、快捷地完成数据的传输。
2.I2C总线读写流程
A.发送数据
a.设置start=1;
b.向I2DAT写外围设备的地址和方向=0(对于写)。
c.等待done=1。如果BEER=1或ACK~=0,则转向步骤
d.用数据字节加载I2DAT。
e.等待DONE=1。如果BEER=1或ACK~=0,则转向步骤g
f.对于每一个字节,重复d.e两个步骤,直到所有字节全部加载完成
g.设置STOP=1。
B.接收数据
a.设置START=1;
b.将外设地址和方向=1(对于读)写入I2DAT中
c.等待DONE=1,如果BEER=1或ACK~=0,则通过设置stop=1结束
d.读I2DAT并放弃数据。这表示9个脉冲的第一瞬时脉冲作为从从属设备来的第1个字节的时钟
f.等待DONE=1,如果beer=1,则通过STOP=1结束
g.从I2DAT读数据。这表示另外的读传输
h.对于每一个字节重复g.h过程
i.在读到最后一个字节之前,设置LASTRD=1.
j.从I2DAT中读数据,LASTRD=1,这就在总线初始化最终字节的读操作
k.等待DONE=1.如果BEER=1,则通过设置STOP=1来结束。
l.设置STOP=1
m.在设置STOP位后,从I2DAT立即读最后的字节。这就重新得到最后一个数据字节,而不用在I2CS总线上初始化一个额外的读处理(9个或更多的SCL脉冲)。
3.ISL12028寄存器
见详细芯片资料
4.详细代码
STATUS REG
RTC REG
CONTROL REG
三种寄存器
void stregwr(char val); //写isl12028 status register定义
void rtcregwr(void); //写isl12028 RTC registers 定义
void ctrregwr(void); //写isl12028 control registers 定义
BYTE readI2C(unsigned char addr); //读I2C总线
char data Day[]={0x00,0x46,0x19,0x07,0x11,0x08,0x05,0x20};
char data Ctr[]={0x18,0x00,0x00,0x00,0x44};
void stregwr(char val)
{
while(I2CS & bSTOPBIT); //等待STOP位为低电平
I2CS = 0x80; //start
I2DAT = 0xDE; //address
while((I2CS &0x01)!=0x01); //waiting for done bit
I2DAT = 0x00; //word address 0
while((I2CS &0x01)!=0x01); //waiting for done bit
I2DAT = 0x3F; //word address 1
while((I2CS &0x01)!=0x01); //waiting for done bit
I2DAT = val; //data to be writed
while((I2CS &0x01)!=0x01); //waiting for done bit
I2CS = 0x40; //stop
}
void rtcregwr(void)
{
unsigned char i;
while(I2CS & bSTOPBIT);
I2CS = 0x80; //STATT
I2DAT = 0xDE; //ADDRESS 11011110
while((I2CS &0x01)!=0x01); //waiting for done bit
I2DAT = 0x00;
while((I2CS &0x01)!=0x01); //waiting for done bit
I2DAT = 0x30;
while((I2CS &0x01)!=0x01);
for(i =0; i <8; i ++)
{
I2DAT = Day;
while((I2CS &0x01)!=0x01); //waiting for done bit
}
I2CS = 0x40;
}
void ctrregwr(void)
{
unsigned char i;
while(I2CS &bSTOPBIT);
I2CS = 0x80;
I2DAT = 0xDE; //11011110
while((I2CS &0x01)!=0x01);
I2DAT = 0x00;
while((I2CS &0x01)!=0x01);
I2DAT = 0x10;
while((I2CS &0x01)!=0x01);
for(i = 0; i < 5; i ++)
{
I2DAT = Ctr;
while((I2CS &0x01)!=0x01);
}
I2CS = 0x40;
}
BYTE readI2C(unsigned char addr)
{
BYTE d;
// unsigned char address;
while(I2CS &bSTOPBIT);
I2CS = 0x80;
I2DAT = 0xDE; //11101111
while((I2CS & 0x01)!= 0x01);
I2DAT = 0x00;
while((I2CS & 0x01)!= 0x01);
I2DAT = addr;
while((I2CS & 0x01)!= 0x01);
I2CS = 0x80;
I2DAT = 0xDF;
while((I2CS & 0x01)!= 0x01);
I2CS = 0x20;
d= I2DAT;
while((I2CS & 0x01)!= 0x01);
I2CS = 0x40;
d= I2DAT;
return(d);
}
void TD_Init( void )
{ // Called once at startup
unsigned char j;
CPUCS = 0x10; // CLKSPD[1:0]=10, for 48MHz operation
IFCONFIG = 0xC0; // set peripheral interface to ports mode
CPUCS |= 0x26; // enable portc strobe feature, and inv CLKOUT
SYNCDELAY; // see TRM section 15.14
EP1OUTCFG = 0xA0; // ep1out is valid BULK OUT 64
SYNCDELAY; // see TRM section 15.14
EP1INCFG = 0xA0; // ep1in is valid BULK IN 64
SYNCDELAY; // see TRM section 15.14
EP1OUTBC = 0x00; // arm ep1out (warning: only 64 bytes deep)
PORTACFG = 0x00; // PORTA as i/o pins...
//the codes recently added
stregwr(0x02); //see isl12028 page 14
stregwr(0x06); //see isl12028 page 14
rtcregwr(); //see isl12028 page 14
for(j=0;j<100;j++); //waiting
ctrregwr(); //see isl12028 page 14
stregwr(0x00); //see isl12028 page 14 reset
Rwuen = TRUE; // Enable remote-wakeup
}
void TD_Poll( void )
{ //for read operation
if( !( EP1INCS & 0x02 ) )
{
EP1INBUF[ 0 ] = readI2C(0x37);
EP1INBUF[ 1 ] = readI2C(0x36);
EP1INBUF[ 2 ] = readI2C(0x35);
EP1INBUF[ 3 ] = readI2C(0x34);
EP1INBUF[ 4 ] = readI2C(0x33);
EP1INBUF[ 5 ] = readI2C(0x32);
EP1INBUF[ 6 ] = readI2C(0x31);
EP1INBUF[ 7 ] = readI2C(0x30);
}
EP1INBC = 8;
SYNCDELAY;
}
5.结果
在usb控制平台里面,把代码下进去后可以清楚地看到时间在变
Read IOCTL passed
0000 20 05 08 11 07 19 46 00
Read IOCTL passed
0000 20 05 08 11 07 19 46 00
Read IOCTL passed
0000 20 05 08 11 07 19 46 01
Read IOCTL passed
0000 20 05 08 11 07 19 46 01
Read IOCTL passed
0000 20 05 08 11 07 19 46 01
Read IOCTL passed
0000 20 05 08 11 07 19 46 02
Read IOCTL passed
0000 20 05 08 11 07 19 46 02
Read IOCTL passed
0000 20 05 08 11 07 19 46 02
Read IOCTL passed
0000 20 05 08 11 07 19 46 03
Read IOCTL passed
0000 20 05 08 11 07 19 46 03
Read IOCTL passed
0000 20 05 08 11 07 19 46 03
Read IOCTL passed
0000 20 05 08 11 07 19 46 03
Read IOCTL passed
0000 20 05 08 11 07 19 46 18
Read IOCTL passed
0000 20 05 08 11 07 19 46 18
Read IOCTL passed
0000 20 05 08 11 07 19 46 18
6.总结以及注意点
A.要详细地理解ISL12028的内部寄存器结构,写它分为两种模式,本文用的是CCR写模式,所以写地址是“11011110”,在CCR写模式里面,又分为volatile write和page write其中SR属于前者,它要求先开始写操作,再写地址“00000000"
和“0x3f”,然后再进行写数据,写完后要对其进行结束操作。RTC和control字节写操作,里面的写地址是自动增加的,所以对于RTC写起始地址为“00000000”和“0x30”,control字节为“00000000”和“0x10”。page write也要求对其进行一个开始和结束过程
B.还有一种I2C总线的写操作,是中断模式的操作,相对而言复杂一些,但更易于理解I2C总线的原理,本文结束后,本人将对其进行详细的代码编写
用户223038 2009-5-20 09:17
用户1394949 2009-1-8 15:02