6302|16

73

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

AT24C256不返回ACK [复制链接]

我用的AT24C256 EEPROM,经常在写入第二个字节的地址后,它就不返回ACK,导致读取数据失败。大部分时间返回正常,有时候不返回ACK,不产生IIC中断。请问这是什么原因?

最新回复

我建议你用模拟的IIC来做,简单的多了  详情 回复 发表于 2009-7-23 11:39
点赞 关注

回复
举报

88

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
是不是时序不对?
我刚搞定AT24C256 EEPROM读写问题, MCU是新华龙的C8051F020
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
你是怎么读写的?我的就是在写入地址后转入读模式的时候,经常会死掉,就是不产生IIC中断了
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

4
 
我的处理器是S3C2440,自己根据例子写个IIC中断处理程序,结果老出问题
 
 
 

回复

67

帖子

0

TA的资源

一粒金砂(初级)

5
 
[code]void IRQ_I2C(void)
{
       
        int i;
       
#if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
           OS_CPU_SR  cpu_sr;
   #endif
    OS_ENTER_CRITICAL();

        i2cint = 0;

    iicSt   = rIICSTAT;
   
    if(iicSt & 0x8){
            I2C_end = 0xFF;
            rIICCON = 0xaf;
            ClearPending(BIT_IIC);
            return;
    }           //When bus arbitration is failed.clear pending bit
    if(iicSt & 0x4){ClearPending(BIT_IIC);}           //When a slave address is matched with IICADD
    if(iicSt & 0x2){ClearPending(BIT_IIC);}           //When a slave address is 0000000b
   
    if(iicSt & 0x1){
            if(I2C_num >0 ){
                    rIICSTAT = iicSt&(~(1<<5));
                    rIICCON  = 0x2f;
                    Delay(1);
                    //OSSemPost(I2cFail);
                    ClearPending(BIT_IIC);
                    return;
            }           //When ACK isn't received and iic data hasn't transmitted over
    }

    switch(_iicMode)
    {
       case POLLACK:
                 
           i2stat = iicSt;        //-- return the status register value
//           OSSemPost(I2cSucc);
                                                                   i2cint = 1;/////////---
                                                                   i2cnum = I2C_num;
           break;
           
       case RDDATA:
                       I2C_num--;
                       if(I2C_num == -1){
                               rIICSTAT = 0x90;                         //Stop MasRx condition
                               //rIICCON  = 0xaf;                         //Resumes IIC operation.
                                                                        rIICCON  = 0x2f;
                               Delay(1);                                        //Wait until stop condtion is in effect.
                                                                        i2cint = 2; ///---
                                                                i2cnum = I2C_num;
                       OSSemPost(I2cSucc);   
                               break;
                       }
                       *pI2C_buf++ = rIICDS;
                       if(I2C_num==0){                                                        //no data to be send
                                rIICCON = 0x2f;                                                //Resumes IIC operation with NOACK.
                                                                       i2cint = 3;///---
                                                              i2cnum = I2C_num;
                       }else{
               rIICCON = 0xaf;                  //Resumes IIC operation with ACK
                                                               i2cint = 4;///---
                                                            i2cnum = I2C_num;
            }       
            break;
        case WRDATA:
                if(I2C_suba_en ==0){                                //-- two word address both transmitted
                            if((I2C_num--)==0){
                                rIICSTAT = 0xd0;            //Stop MasTx condition
                                rIICCON  = 0xaf;            //-- writer 0 to IICCON[4] to clear the int pend,resuming IIC operation (this also assert the ack enable and rx/tx int enable)
                                Delay(1);                   //Wait until stop condtion is in effect.
                                                                                        //The pending bit will not be set after issuing stop condition.
                                I2C_end = TRUE;
                                OSSemPost(I2cSucc);
                                                    i2cint = 5;///---
                                                    i2cnum = I2C_num;
                                break;   
                            }else{
                                    rIICDS = *pI2C_buf++;
                                                            //for(i=0;i<10;i++);
                                    rIICCON = 0xaf;                                 //-- writer 0 to IICCON[4] to clear the int pend,resuming IIC operation (this also assert the ack enable and rx/tx int enable)
                                                            i2cint = 6;///---
                                                            i2cnum = I2C_num;
                                    break;
                            }
            }
                if(I2C_suba_en ==4){                                //-- writer mode:write first word address
                    rIICDS = I2C_subaH;
                                                            //for(i=0;i<10;i++);                                //-- for setup time until rising edge of IICSCL
                    rIICCON = 0xaf;                                 //-- writer 0 to IICCON[4] to clear the int pend,resuming IIC operation (this also assert the ack enable and rx/tx int enable)
                    I2C_suba_en--;                                        //-- I2C_suba_en = 2,indicate that first word address has been transmitted.
                                                            i2cint = 7;///---
                                                            i2cnum = I2C_num;
                    break;
            }
            if(I2C_suba_en ==3){                                //-- write second word address
                    rIICDS = I2C_subaL;
                    //                                        for(i=0;i<10;i++);
                    rIICCON = 0xaf;                                 //-- writer 0 to IICCON[4] to clear the int pend,resuming IIC operation (this also assert the ack enable and rx/tx int enable)
                    I2C_suba_en = 0;                                        //-- second word address transmitted,I2C_suba_en ==0
                                                                   i2cint = 8;///---
                                                                   i2cnum = I2C_num;
                    break;
            }
       case SETRDADDR:
            if(I2C_suba_en ==2){                                        //--to read data,first ,write word address to EEPROM
                    rIICDS = I2C_subaH;
                                                            //for(i=0;i<10;i++);                                //-- for setup time until rising edge of IICSCL
                    Delay(1);
                    rIICCON = 0xaf;                                 //-- writer 0 to IICCON[4] to clear the int pend,resuming IIC operation (this also assert the ack enable and rx/tx int enable)
                    I2C_suba_en--;                                        //-- I2C_suba_en = 2,indicate that first word address has been transmitted.
                                                                   i2cint = 9;///---
                                                                   i2cnum = I2C_num;
                    break;
            }
            if(I2C_suba_en ==1){                                //-- ??????????word???????·   
                    rIICDS = I2C_subaL;
                                                            //for(i=0;i<10;i++);                                //-- for setup time until rising edge of IICSCL
                    rIICCON = 0xaf;                                 //-- writer 0 to IICCON[4] to clear the int pend,resuming IIC operation (this also assert the ack enable and rx/tx int enable)
                    I2C_suba_en = 0;                                //-- I2C_suba_en = 2,indicate that first word address has been transmitted.
                                                                   i2cint = 10;///---
                                                                   i2cnum = I2C_num;
                    break;
            }
            if(I2C_suba_en ==0){                                //-- read mode:two 8-bit word addressess write completed
                                rIICDS      = I2C_sla+1;
                                rIICSTAT    = 0xb0;                   //MasRx,Start
                                rIICCON                = 0xaf;                   //Resumes IIC operation.
                                I2C_suba_en        = -1;                          
                                                            i2cint = 11;///---
                                                            i2cnum = I2C_num;
                    break;
                        }
                        if(I2C_suba_en == -1){                                //-- read mode:two 8-bit word addressess write completed
                                _iicMode    = RDDATA;                                //-- set iic operation mode flag to read
                                rIICCON                = 0xaf;                   //Resumes IIC operation with ACK.                  
                                                                   i2cint = 12;///---
                                                                   i2cnum = I2C_num;
                    break;
                        }
        default:
                rIICCON  = 0x2f;
                                                                i2cint = 14;///---
                                                                i2cnum = I2C_num;
            break;      
    }
                //================================
                        ClearPending(BIT_IIC);
                //================================
   OS_EXIT_CRITICAL();
}
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

6
 
能否把你的电路,和程序写出来啊,这么说太浅显了,还有,听楼主的介绍,是用的单片机内部I2C总线吧?是不是哪些设置不正确呢?
 
 
 

回复

87

帖子

0

TA的资源

一粒金砂(初级)

7
 
void IRQ_I2C(void)
{
       
        int i;
       
#if OS_CRITICAL_METHOD == 3                                
           OS_CPU_SR  cpu_sr;
   #endif
    OS_ENTER_CRITICAL();

        i2cint = 0;

    iicSt   = rIICSTAT;
   
    if(iicSt & 0x8){
            I2C_end = 0xFF;
            rIICCON = 0xaf;
            ClearPending(BIT_IIC);
            return;
    }           //When bus arbitration is failed.clear pending bit
    if(iicSt & 0x4){ClearPending(BIT_IIC);}           //When a slave address is matched with IICADD
    if(iicSt & 0x2){ClearPending(BIT_IIC);}           //When a slave address is 0000000b
   
    if(iicSt & 0x1){//-- 没有收到返回
            if(I2C_num >0 ){
                    rIICSTAT = iicSt&(~(1<<5));
                    rIICCON  = 0x2f;
                    Delay(1);
                    //OSSemPost(I2cFail);
                    ClearPending(BIT_IIC);
                    return;
            }           //When ACK isn't received and iic data hasn't transmitted over
    }

    switch(_iicMode)
    {
       case POLLACK:
                 
           i2stat = iicSt;        //-- return the status register value
//           OSSemPost(I2cSucc);
                                                                   i2cint = 1;/////////---
                                                                   i2cnum = I2C_num;
           break;
           
       case RDDATA:// 读操作
                       I2C_num--;
                       if(I2C_num == -1){
                               rIICSTAT = 0x90;                         //Stop MasRx condition
                               //rIICCON  = 0xaf;                        
                                                               rIICCON  = 0x2f;
                               Delay(1);                        
                                                                i2cint = 2;
                                                                i2cnum = I2C_num;
                       OSSemPost(I2cSucc);   
                               break;
                       }
                       *pI2C_buf++ = rIICDS;
                       if(I2C_num==0){                                                       
                                rIICCON = 0x2f;                //Resumes IIC operation with NOACK.
                                                               i2cint = 3;///---
                                                              i2cnum = I2C_num;
                       }else{
               rIICCON = 0xaf;                          //Resumes IIC operation with ACK
                                                               i2cint = 4;///---
                                                            i2cnum = I2C_num;
            }       
            break;
        case WRDATA://写操作
                if(I2C_suba_en ==0){                        //-- 两个字节的地址都写入了
                            if((I2C_num--)==0){
                                rIICSTAT = 0xd0;            //Stop MasTx condition
                                rIICCON  = 0xaf;            //-- resume iic
                                Delay(1);                   //Wait until stop condtion is in effect.
                                                                                       
                                I2C_end = TRUE;
                                OSSemPost(I2cSucc);
                                                    i2cint = 5;///---
                                                    i2cnum = I2C_num;
                                break;   
                            }else{
                                    rIICDS = *pI2C_buf++;
                                                            //for(i=0;i<10;i++);
                                    rIICCON = 0xaf;                                 //-- resume iic
                                                            i2cint = 6;///---
                                                            i2cnum = I2C_num;
                                    break;
                            }
            }
                if(I2C_suba_en ==4){                        //-- 先写入第一个字节的地址
                    rIICDS = I2C_subaH;
                                                            //for(i=0;i<10;i++);                                //-- for setup time

until rising edge of IICSCL
                    rIICCON = 0xaf;                                 //-- resume iic
                    I2C_suba_en--;                        //-- 已写入第一个字节地址
                                                            i2cint = 7;///---
                                                            i2cnum = I2C_num;
                    break;
            }
            if(I2C_suba_en ==3){                                //-- 再写第二字节地址
                    rIICDS = I2C_subaL;
                    //                                        for(i=0;i<10;i++);
                    rIICCON = 0xaf;                                 //-- resume iic
                    I2C_suba_en = 0;                        //-- 两个字节地址都写完了,让I2C_suba_en ==0
                                                                   i2cint = 8;///---
                                                                   i2cnum = I2C_num;
                    break;
            }
       case SETRDADDR:// 读数据前,设置地址
            if(I2C_suba_en ==2){                        //--读数据前,先写入地址,现在写入高地址
                    rIICDS = I2C_subaH;
                                                            //for(i=0;i<10;i++);
                    Delay(1);
                    rIICCON = 0xaf;                                 //-- resume iic
                    I2C_suba_en--;                               
                                                                   i2cint = 9;
                                                                   i2cnum = I2C_num;
                    break;
            }
            if(I2C_suba_en ==1){                                //-- 写入低地址   
                    rIICDS = I2C_subaL;
                                                            //for(i=0;i<10;i++);                               
                    rIICCON = 0xaf;                                 //-- resume iic
                    I2C_suba_en = 0;                               
                                                                   i2cint = 10;
                                                                   i2cnum = I2C_num;
                    break;
            }
            if(I2C_suba_en ==0){                                //-- 两个字节地址都写入了
                                rIICDS      = I2C_sla+1;
                                rIICSTAT    = 0xb0;                   //发送重新起始条件,转到读模式
                                rIICCON                = 0xaf;          //Resumes IIC operation.
                                I2C_suba_en        = -1;                          
                                                            i2cint = 11;///---
                                                            i2cnum = I2C_num;
                    break;
                        }
                        if(I2C_suba_en == -1){                        //-- EEPROM对读起始条件的ACK
                                _iicMode    = RDDATA;                //-- set iic operation mode flag to read
                                rIICCON                = 0xaf;         //Resumes IIC operation with ACK.                  
                                                                   i2cint = 12;///---
                                                                   i2cnum = I2C_num;
                    break;
                        }
        default:
                rIICCON  = 0x2f;
                                                                i2cint = 14;///---
                                                                i2cnum = I2C_num;
            break;      
    }
                //================================
                        ClearPending(BIT_IIC);
                //================================
   OS_EXIT_CRITICAL();
}
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

8
 
这是读函数:
[code]
uint8 IRcvStr(uint8 subaL,uint8 subaH,uint8 *s,uint8 no)
{
          uint8 err;
           _iicMode        = SETRDADDR;                        //-- first,use write mode to write word address

    I2C_sla                = AT24C256;                                   //AT24C256 0Xa0

           I2C_subaH         = subaH;

           I2C_subaL         = subaL;

           pI2C_buf         = s;

           I2C_num         = no;

           I2C_suba_en = 2;

           I2C_end         = 0;
   
    rIICDS   = I2C_sla;                 //0xa0,//-- first,write slave address
                                            rIICCON = 0xaf;
                                            ClearPending(BIT_IIC);
   
    rIICSTAT = 0xf0;                    //MasTx,Start

        OSSemPend(I2cSucc,600,&err);
                                                Delay(5);
        if(err == OS_NO_ERR) return 1;
        else return 0;
   
}
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

9
 
我是这样测试的:没隔5s,就读EEPROM 1320个字节,一般在读个十几次后,EEPROM就不回ACK了。
 
 
 

回复

67

帖子

0

TA的资源

一粒金砂(初级)

10
 
2440的I2C用的硬件控制的?速度设多少?
 
 
 

回复

92

帖子

0

TA的资源

一粒金砂(初级)

11
 
是不是读的太快了,每读一页延时一下看看
 
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

12
 
要不就别要ACK了,只要能读出来,了事。。。

我在操作2401的时候就这么干的

 
 
 

回复

56

帖子

0

TA的资源

一粒金砂(初级)

13
 
引用 9 楼 shuiyan 的回复:
2440的I2C用的硬件控制的?速度设多少?

S3C2440有IIC的时钟控制器,只能设置两个值,我选择了其中一个值,应该没问题
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

14
 
还没弄好吗?
 
 
 

回复

59

帖子

0

TA的资源

一粒金砂(初级)

15
 
EEPROM 要求的时序有没有严格实行?   问题的关键哦

 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

16
 
暂时不搞了,将就着用
 
 
 

回复

62

帖子

0

TA的资源

一粒金砂(初级)

17
 
我建议你用模拟的IIC来做,简单的多了
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表