原创 I2C总线应用(ISL12028篇)

2008-11-7 22:04 3961 4 6 分类: MCU/ 嵌入式

https://static.assets-stash.eet-china.com/album/old-resources/2008/11/7/398834db-aa32-4f10-bb3f-70b8d32200fd.rarpdfpdfhttps://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总线的原理,本文结束后,本人将对其进行详细的代码编写


    


     


      


       


     


 


       


   


   


 

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

用户223038 2009-5-20 09:17

博主有改应用程序么?我也在做一个类似的东西,不知怎么编写应用程序把端点1的数据采集上来,求你帮忙,谢谢

用户1394949 2009-1-8 15:02

我把最近的项目做完,就学学这个东西,哈哈,楼主的资料我先保存了
相关推荐阅读
用户178741 2009-04-16 22:02
平顶降落以及上升时间在估算滤波器上限及下限频率方面的应用
A.平顶降落在估算滤波器下限频率上的应用:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&...
用户178741 2009-04-08 14:55
模块综合中(与CPLD部分相连的器件调试)
           ----------应用于MAX197数据采样与BDCM<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com...
用户178741 2009-03-17 22:18
FPGA开发关键问题
1FPGA设计的关键问题 随着FPGA(Field Programmable Gate Array)容量、功能以及可靠性的提高,其在现代数字通信系统中的应用日渐广泛。采用FPGA设计数字电路已经成为数...
用户178741 2009-03-10 21:40
AD9851DDS的EZ-USB控制
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />     上面是电路图,晶振是20M...
用户178741 2009-03-05 12:13
RE200B应用电路设计
https://static.assets-stash.eet-china.com/album/old-resources/2009/3/5/8cf180a0-1e24-4a85-92f6-5201b...
用户178741 2009-02-25 10:47
USB_CPLD控制系统实验
https://static.assets-stash.eet-china.com/album/old-resources/2009/2/25/14ebdb66-d1b4-456f-aac6-80c1...
EE直播间
更多
我要评论
2
4
关闭 站长推荐上一条 /3 下一条