这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » ARM2214,I2C,24LC64 请教:ARM2214怎样用硬件I2C读取2

共2条 1/1 1 跳转至

ARM2214,I2C,24LC64 请教:ARM2214怎样用硬件I2C读取24LC64。因为多个从地址!

院士
2006-09-17 18:14:16     打赏
ARM2214,I2C,24LC64 请教:ARM2214怎样用硬件I2C读取24LC64。因为多个从地址!



关键词: ARM2214     24LC64     请教     怎样     硬件         

院士
2006-12-22 22:43:00     打赏
2楼
24LC64多了个从地址,好象用硬件I2C不支持好象只支持24LC16呢? 1: 如果是标准的I2C器件,应该可以支持。您说的从地址是指内部地址还是I2C规定的地址?如果是I2C规定的地址,您在访问前应当知道访问那个地址,自己设置从机地址即可。如果是内部地址,有写数据方式写地址即可。 2: 谢谢,是内部地址呀,可我看数据手册或者资料上面都是以下格式呀  从地址(器件地址)+子地址(内部地址)+数据
可是我需要的是          从地址(器件地址)+子地址H(内部地址)+子地址L
(内部地址)+数据。 3: 不其中一个子地址当作数据发送即可。其实对于I2c规范来说,所有子地址都是按照数据方式发送的。函数仅仅是包装了一下 4: 一点疑问按数据把从地址送出,在写过程可以,但读过程呢? 5: 对呀,我现在正在想办法读呀?读好象不成功啊? 6: 用仿真器调一下这个象周功说的,当数据发,但得在程序里改一下,我就是这么改的。 7: 先写地址再读(操作两次)。 8: to zlgARM你的建议我试了,不通。
  写程序完了,会有一个结束字符,在启动读程序,不行 9: 谢谢继续关注,我试过,读出了一字节,其他的读不出? 10: 关注中…… 11: 顶 12: 给二个例子给你们一个例子吧.
第一个例子不是用I2C中断来做的.
void delayMS(uint32 i)
{    uint32 j,add;
    for(j=0;j<i;j++)
        for(add=0;add<500;add++) ;
}

/*************************************************
&ordm;&macr;&Ecirc;&yacute;&Atilde;&ucirc;&sup3;&AElig;&pound;&ordm;        startE2PROM
&frac14;ò&Ograve;&ordf;&Atilde;è&Ecirc;&ouml;&pound;&ordm;        E2PROM&iquest;&ordf;&Ecirc;&frac14;
&Ecirc;&auml;&Egrave;&euml;&pound;&ordm;                    void
&Ecirc;&auml;&sup3;&ouml;&pound;&ordm;                    void
&ETH;&THORN;&cedil;&Auml;&Egrave;&Otilde;&Ouml;&frac34;&pound;&ordm;
*************************************************/
void startE2PROM(void)
{
    IOCLR=E2PROMSCL;
    delayMS(1);
    IOSET=E2PROMSDA;
    delayMS(1);
    IOSET=E2PROMSCL;
    delayMS(1);
    IOCLR=E2PROMSDA;
    delayMS(1);
    IOCLR=E2PROMSCL;
    delayMS(1);
    IOSET=E2PROMSDA;
    delayMS(1);    
}

/*************************************************
&ordm;&macr;&Ecirc;&yacute;&Atilde;&ucirc;&sup3;&AElig;&pound;&ordm;        endE2PROM
&frac14;ò&Ograve;&ordf;&Atilde;è&Ecirc;&ouml;&pound;&ordm;        E2PROM&Ouml;&Otilde;&Ouml;&sup1;
&Ecirc;&auml;&Egrave;&euml;&pound;&ordm;                    void
&Ecirc;&auml;&sup3;&ouml;&pound;&ordm;                    void
&ETH;&THORN;&cedil;&Auml;&Egrave;&Otilde;&Ouml;&frac34;&pound;&ordm;
*************************************************/
void endE2PROM(void)
{
    IOCLR=E2PROMSCL;
    delayMS(1);
    IOCLR=E2PROMSDA;
    delayMS(1);
    IOSET=E2PROMSCL;
    delayMS(1);
    IOSET=E2PROMSDA;
    delayMS(1);
    IOCLR=E2PROMSCL;
    delayMS(1);
}

/*************************************************
&ordm;&macr;&Ecirc;&yacute;&Atilde;&ucirc;&sup3;&AElig;&pound;&ordm;        ackE2PROM
&frac14;ò&Ograve;&ordf;&Atilde;è&Ecirc;&ouml;&pound;&ordm;        E2PROM&Ouml;&Otilde;&Ouml;&sup1;
&Ecirc;&auml;&Egrave;&euml;&pound;&ordm;                    void
&Ecirc;&auml;&sup3;&ouml;&pound;&ordm;                    void
&ETH;&THORN;&cedil;&Auml;&Egrave;&Otilde;&Ouml;&frac34;&pound;&ordm;
*************************************************/
void ackE2PROM(void)
{
    IOCLR=E2PROMSDA;
    delayMS(1);
    IOSET=E2PROMSCL;
    delayMS(1);
    IOCLR=E2PROMSCL;
    delayMS(1);
    IOSET=E2PROMSDA;        
    delayMS(1);
}

/*************************************************
&ordm;&macr;&Ecirc;&yacute;&Atilde;&ucirc;&sup3;&AElig;&pound;&ordm;        noackE2PROM
&frac14;ò&Ograve;&ordf;&Atilde;è&Ecirc;&ouml;&pound;&ordm;        E2PROM&Ouml;&Otilde;&Ouml;&sup1;
&Ecirc;&auml;&Egrave;&euml;&pound;&ordm;                    void
&Ecirc;&auml;&sup3;&ouml;&pound;&ordm;                    void
&ETH;&THORN;&cedil;&Auml;&Egrave;&Otilde;&Ouml;&frac34;&pound;&ordm;
*************************************************/
void noackE2PROM(void)
{
    IOSET=E2PROMSDA;
    delayMS(1);
    IOSET=E2PROMSCL;
    delayMS(1);
    IOCLR=E2PROMSCL;
    delayMS(1);
    IOSET=E2PROMSDA;
    delayMS(1);

}

/*************************************************
&ordm;&macr;&Ecirc;&yacute;&Atilde;&ucirc;&sup3;&AElig;&pound;&ordm;        send_byte_to_E2PROM
&frac14;ò&Ograve;&ordf;&Atilde;è&Ecirc;&ouml;&pound;&ordm;        &Euml;&Iacute;1byte &micro;&frac12;E2PROM
&Ecirc;&auml;&Egrave;&euml;&pound;&ordm;                    (uchar)val:&Euml;ù&Ograve;&ordf;&ETH;&acute;&Egrave;&euml;&micro;&Auml;&Ouml;&micro;
&Ecirc;&auml;&sup3;&ouml;&pound;&ordm;                    void
&ETH;&THORN;&cedil;&Auml;&Egrave;&Otilde;&Ouml;&frac34;&pound;&ordm;
*************************************************/
void send_byte_to_E2PROM(uint8 val)
{
    uint8 i =0;

    for (i = 0;i < 8;i++)
    {
        IOCLR=E2PROMSCL;
        delayMS(1);
        
        if ((val & 0x80) == 0x80)
        {
            IOSET=E2PROMSDA;            
        }
        else
        {
            IOCLR=E2PROMSDA;
            
        }
        delayMS(1);
        val = val << 1;

        IOSET=E2PROMSCL;
        delayMS(1);
    }

    IOCLR=E2PROMSCL;
    delayMS(1);
    noackE2PROM();
}

/*************************************************
&ordm;&macr;&Ecirc;&yacute;&Atilde;&ucirc;&sup3;&AElig;&pound;&ordm;        get_byte_from_E2PROM
&frac14;ò&Ograve;&ordf;&Atilde;è&Ecirc;&ouml;&pound;&ordm;        &acute;&Oacute;E2PROM&para;&Aacute;&Ograve;&raquo;byte
&Ecirc;&auml;&Egrave;&euml;&pound;&ordm;                    void
&Ecirc;&auml;&sup3;&ouml;&pound;&ordm;                    (uchar)val :&Euml;ù&para;&Aacute;&sup3;&ouml;&micro;&Auml;&Ouml;&micro;
&ETH;&THORN;&cedil;&Auml;&Egrave;&Otilde;&Ouml;&frac34;&pound;&ordm;
*************************************************/
uint8 get_byte_from_E2PROM(void)
{
    uint8 val = 0;
    uint8 i = 0;
    
    IOCLR=E2PROMSCL;
    delayMS(1);
    IODIR &= 0xfffffff7;//!E2PROMSDA;//&Eacute;è&Ouml;&Atilde;&Ecirc;&auml;&Egrave;&euml;
    delayMS(1);
    
    for (i = 0;i < 8;i++)
    {
        val = val << 1;

        IOSET=E2PROMSCL;
        
        delayMS(1);
        if ( (IOPIN&E2PROMSDA) == E2PROMSDA)
        {
            val = val | 0x01;
        }
        else
        {
            val = val & 0xfe;
        }
        delayMS(1);
        IOCLR=E2PROMSCL;
        delayMS(1);
        
    }
    IODIR |= E2PROMSDA;//&Eacute;è&Ouml;&Atilde;&Ecirc;&auml;&sup3;&ouml;
    
    return val;
}

/*************************************************
&ordm;&macr;&Ecirc;&yacute;&Atilde;&ucirc;&sup3;&AElig;&pound;&ordm;        resetE2PROM
&frac14;ò&Ograve;&ordf;&Atilde;è&Ecirc;&ouml;&pound;&ordm;        &sup3;&otilde;&acute;&Icirc;&Eacute;&Iuml;&micro;&ccedil;&cedil;&acute;&Icirc;&raquo;E2PROM
&Ecirc;&auml;&Egrave;&euml;&pound;&ordm;                    void
&Ecirc;&auml;&sup3;&ouml;&pound;&ordm;                    void
&ETH;&THORN;&cedil;&Auml;&Egrave;&Otilde;&Ouml;&frac34;&pound;&ordm;
*************************************************/
void resetE2PROM(void)
{
    IOCLR=E2PROMSCL;
    delayMS(1);
    IOSET=E2PROMSDA;
    delayMS(1);
    startE2PROM();
    endE2PROM();
}

/*************************************************
&ordm;&macr;&Ecirc;&yacute;&Atilde;&ucirc;&sup3;&AElig;&pound;&ordm;        readE2PROM
&frac14;ò&Ograve;&ordf;&Atilde;è&Ecirc;&ouml;&pound;&ordm;        &para;&Aacute;E2PROM
&Ecirc;&auml;&Egrave;&euml;&pound;&ordm;                    (uint) addr:&Euml;ù&Ograve;&ordf;&para;&Aacute;&micro;&Auml;&micro;&Oslash;&Ouml;·
                    (uchar) len : &Euml;ù&Ograve;&ordf;&para;&Aacute;&micro;&Auml;&sup3;¤&para;&Egrave;
                    (uchar)highlow : &Euml;ù&Ograve;&ordf;&para;&Aacute;&micro;&Auml;&Ecirc;&Ccedil;&cedil;&szlig;&Ccedil;&oslash;&raquo;&sup1;&Ecirc;&Ccedil;&micro;&Iacute;&Ccedil;&oslash;
&Ecirc;&auml;&sup3;&ouml;&pound;&ordm;                    void
&ETH;&THORN;&cedil;&Auml;&Egrave;&Otilde;&Ouml;&frac34;&pound;&ordm;
*************************************************/
void readDataI2C(uint16 addr,uint8 len,uint8 *DATA)
{
    uint8 i = 0;
    uint16 temp_addr;
    
    temp_addr=addr;
    startE2PROM();


    send_byte_to_E2PROM(EEWRITE);
    send_byte_to_E2PROM(addr>>8);
    addr=temp_addr;
    send_byte_to_E2PROM(addr);
    
    startE2PROM();

    send_byte_to_E2PROM(EEREAD);

    *DATA = get_byte_from_E2PROM();
    DATA++;
    
    for (i = 1;i < len;i++)
    {
        ackE2PROM();
        *DATA = get_byte_from_E2PROM();
        DATA++;
    }

    endE2PROM();
}



/*************************************************
&ordm;&macr;&Ecirc;&yacute;&Atilde;&ucirc;&sup3;&AElig;&pound;&ordm;        writeE2PROM
&frac14;ò&Ograve;&ordf;&Atilde;è&Ecirc;&ouml;&pound;&ordm;        &ETH;&acute;E2PROM
&Ecirc;&auml;&Egrave;&euml;&pound;&ordm;                    (uint) addr:&Euml;ù&Ograve;&ordf;&ETH;&acute;&micro;&Auml;&micro;&Oslash;&Ouml;·
                    (uchar) len : &Euml;ù&Ograve;&ordf;&ETH;&acute;&micro;&Auml;&sup3;¤&para;&Egrave;
                    (uchar)highlow : &Euml;ù&Ograve;&ordf;&ETH;&acute;&micro;&Auml;&Ecirc;&Ccedil;&cedil;&szlig;&Ccedil;&oslash;&raquo;&sup1;&Ecirc;&Ccedil;&micro;&Iacute;&Ccedil;&oslash;
&Ecirc;&auml;&sup3;&ouml;&pound;&ordm;                    void
&ETH;&THORN;&cedil;&Auml;&Egrave;&Otilde;&Ouml;&frac34;&pound;&ordm;
*************************************************/
void writeDataI2C(uint16 addr,uint8 len,uint8 *DATA)
{
    uint8 i = 0;
    uint16 temp_addr;
    
    temp_addr=addr;
    
    startE2PROM();


    send_byte_to_E2PROM(EEWRITE);
    send_byte_to_E2PROM(addr>>8);
    addr=temp_addr;
    send_byte_to_E2PROM(addr);

    for (i = 0;i <len;i++)
    {
        send_byte_to_E2PROM(*DATA);
        DATA++;
    }    

    endE2PROM();
    delayMS(100);
}

下面这个例子是用I2C中断来做的
void  __irq  IRQ_I2C(void)
{  unsigned char  sta;
   CLOSEINT();
   sta = I2STAT;                    // 读出I2C状态字
   switch(sta)
   {  case  0x08:                   // 己发送起始条件
            if(1==I2C_suba_en) I2DAT = I2C_sla&0xFE;    // 指定子地址读时,先写入地址
              else I2DAT = I2C_sla;                     // 否则直接发送从机地址
            I2CONCLR = 0x28;        // SI=0
            break;
            
      case  0x10:
            I2DAT = I2C_sla;        // 重启动总线后,发送从地址
            I2CONCLR = 0x28;        // SI=0
            break;
   
      case  0x18:                   // 已发送SLA+W,并已接收应答
            if(0==I2C_suba_en)      // 无子地址,则直接发送数据
            {  if(I2C_num>0)
               {  I2DAT = *I2C_buf++;
                  I2CONCLR = 0x28;
                  I2C_num--;
               }
               else
               {  I2CONSET = 0x10;  // 无数据发送,结束总线
                  I2CONCLR = 0x28;
                  I2C_end = 1;      // 设置总线操作结束标志
               }
               break;
            }
            if(1==I2C_suba_en)      // 发送子地址
            {  I2DAT = I2C_suba>>8;
               I2CONCLR = 0x28;
               I2C_suba_en = 3;     //041009
            }
            if(2==I2C_suba_en)
            {  I2DAT = I2C_suba>>8;
               I2CONCLR = 0x28;
               I2C_suba_en = 4;     // 子地址己处理
            }
            break;
            
      case  0x28:                   // 已发送I2C数据,并接收到应答
            if(3==I2C_suba_en)      // 发送子地址
            {  I2DAT = I2C_suba;
               I2CONCLR = 0x28;
               I2C_suba_en = 1;     //041009
               break;
            }
            if(4==I2C_suba_en)
            {  I2DAT = I2C_suba;
               I2CONCLR = 0x28;
               I2C_suba_en = 0;     // 子地址己处理
               break;
            }                       //041009
            
            
            if(0==I2C_suba_en)      // 无子地址,则直接发送数据
            {  if(I2C_num>0)
               {  I2DAT = *I2C_buf++;
                  I2CONCLR = 0x28;
                  I2C_num--;
               }
               else
               {  I2CONSET = 0x10;  // 无数据发送,结束总线
                  I2CONCLR = 0x28;
                  I2C_end = 1;
               }
               break;
            }
            if(1==I2C_suba_en)      // 若是指定地址读,则重新启动总线
            {  I2CONSET = 0x20;
               I2CONCLR = 0x18;
               I2C_suba_en = 0;     // 子地址己处理
            }
            break;
   
   
      case  0x20:
      case  0x30:
      case  0x38:
            I2CONCLR = 0x28;        // 总线进入不可寻址从模式
            I2C_end = 0xFF;         // 总线出错,设置标志
            break;
   
   
      case  0x40:                   // 己发送SLA+R,并已接收到应答
            if(1==I2C_num)          // 最后一字节,接收数据后发送非应答信号
            {  I2CONCLR = 0x2C;     // AA=0,接收到数据后产生非应答
            }
            else                    // 接收数据并发送应答信号
            {  I2CONSET = 0x04;     // AA=1,接收到数据后产生应答
               I2CONCLR = 0x28;
            }
            break;
            
      case  0x50:
            *I2C_buf++ = I2DAT;     // 读取数据
            I2C_num--;
            if(1==I2C_num)
            {  I2CONCLR = 0x2C;     // AA=0,接收到数据后产生非应答
            }
            else
            {  I2CONSET = 0x04;     // AA=1,接收到数据后产生应答
               I2CONCLR = 0x28;
            }
            break;
      
      case  0x58:
            *I2C_buf++ = I2DAT;     // 读取最后一字节数据
            I2CONSET = 0x10;        // 结束总线
            I2CONCLR = 0x28;
            I2C_end = 1;
            break;
      
      case  0x48:
            I2CONCLR = 0x28;        // 总线进入不可寻址从模式
            I2C_end = 0xFF;
            break;
   }
   VICVectAddr = 0x00;              // 中断处理结束
   OPENINT();
}
13: 谢谢,先下了看看! 14: 给周开发板上配套的例子做一个接口程序,就行了,同时读写at24c64和pf8563(时钟),没有任何总是呀

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]