手电大家谈-手电筒爱好者之家

 找回密码
 注册成为会员,享受更多功能。

QQ登录

只需一步,快速开始

只需一步,快速开始

搜索
查看: 7193|回复: 31

[电子电路] 请教各位I2C对24C02写完后无法立即读的问题

[复制链接]
  • TA的每日心情
    开心
    2021-12-29 09:01
  • 签到天数: 1219 天

    [LV.10]以坛为家III

    发表于 2021-2-16 17:24 | 显示全部楼层 |阅读模式

    马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

    您需要 登录 才可以下载或查看,没有账号?注册成为会员,享受更多功能。

    x
    最近在学I2C读写24C02的东西,弄了几天了,搞不定。下面是代码截图,就是对24C02的读写操作,如果是先写后立即读,在Proteus里仿真是读出0xFF,在开发板里是读出0x00,总之读不出。但是,按照先写后立即读操作完,把写的那部分代码注释掉再去跑,Proteus和开发板里都会读出0xAF,请问各位是什么原因。感觉I2C比USART稀奇古怪多了,USART我看几小时就搞定了,I2C几天都搞不定,I2C协议早先我也没接触过什么。
    无标题.png
                              代码图
    1.png
        先写后立即读,读不出
    2.png
    只读,能读出
    回复 dsu_marcocopyright:copyright

    使用道具 举报

  • TA的每日心情
    慵懒
    2021-9-3 07:49
  • 签到天数: 941 天

    [LV.10]以坛为家III

    发表于 2021-2-16 18:22 来自手机 | 显示全部楼层
    本帖最后由 hellohello22 于 2021-2-16 18:24 编辑

    i2c问题不是芯片坏(小概率)就是时序不对 没有例外  我自己写的驱动就一直正常

    点评

    Proteus 仿真也是不正常的。按先写后立即读先跑一遍,是读不出来的,看到网上解释是要给24C02写内存的一点时间,建议等待6ms,但是我都等待2000ms了,仍然读不出。但是然后按只读方式再跑一遍,原来写进去的就能读出  详情 回复 发表于 2021-2-16 18:46
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2021-12-29 09:01
  • 签到天数: 1219 天

    [LV.10]以坛为家III

     楼主| 发表于 2021-2-16 18:46 | 显示全部楼层
    hellohello22 发表于 2021-2-16 18:22
    i2c问题不是芯片坏(小概率)就是时序不对 没有例外  我自己写的驱动就一直正常 ...

    Proteus 仿真也是不正常的。按先写后立即读先跑一遍,是读不出来的,看到网上解释是要给24C02写内存的一点时间,建议等待6ms,但是我都等待2000ms了,仍然读不出。但是然后按只读方式再跑一遍,原来写进去的就能读出来了。仿真和实际的开发板都是这样,应该不是芯片问题。先写后读,按照I2C的解释是两个不同模式的切换,即由写切换到读模式,说是RS(重启)方法切换,但是我不知道啥叫RS方法,我只能理解为先STOP,再START,不知道对不对。看24C02手册读取数据有不同模式,默认是按顺序读,也就是当前操作(无论读写)第N个地址,如果接下来发送读命令,它会去读取第N+1地址的内容,这显然不符合我的要求,不过我是按照手册的“任意地址读”的方式操作的,对于只读,还是能读出来的。
    回复

    使用道具 举报

  • TA的每日心情
    郁闷
    2021-2-12 07:41
  • 签到天数: 58 天

    [LV.5]常住居民I

    发表于 2021-2-16 18:54 | 显示全部楼层

    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2021-9-3 07:49
  • 签到天数: 941 天

    [LV.10]以坛为家III

    发表于 2021-2-16 18:56 来自手机 | 显示全部楼层
    我写完马上读都可以 有示波器看下波形就知道

    点评

    上开发板用示波器看了,先写的过程完整被抓下来了,数据全正确都有,到了STOP,也执行了,但是后续的START之类的波形全没了,也就是没有执行读过程。虽然代码在执行,而且状态也符合,但是实际没有读的波形产生,很  详情 回复 发表于 2021-2-16 20:08
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2021-12-29 09:01
  • 签到天数: 1219 天

    [LV.10]以坛为家III

     楼主| 发表于 2021-2-16 19:03 | 显示全部楼层
    我用的开发平台是ATMEL STUDIO 7,ATMEGA16似乎有些古老了。网上的代码似乎比我的更底层,还要根据接收和发送来设置什么SDA的输入输出方式,也就是I/O模式,但是AV Studio7似乎不鸟这些,也就是按照M16手册说明,语句里只要开了TWI功能,SDA,SCL这两个脚好像就不在是什么I/O口了,任凭你怎么设置PC0,PC1的输入输出方式,全然不鸟,语句也比网上的简单多了,网上也根本找不到相似的原因。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2021-12-29 09:01
  • 签到天数: 1219 天

    [LV.10]以坛为家III

     楼主| 发表于 2021-2-16 20:08 | 显示全部楼层
    hellohello22 发表于 2021-2-16 18:56
    我写完马上读都可以 有示波器看下波形就知道

    上开发板用示波器看了,先写的过程完整被抓下来了,数据全正确都有,到了STOP,也执行了,但是后续的START之类的波形全没了,也就是没有执行读过程。虽然代码在执行,而且状态也符合,但是实际没有读的波形产生,很是奇怪。不知道I2C协议里的读写状态切换的RS信号是啥信号,不知道STOP之后,为什么延迟一段时间用START,实际不会开启。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-1-20 08:48
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2021-2-16 20:34 | 显示全部楼层
    上拉电阻那里,接了电压没?我只看到一个探针

    点评

    那个探针是激励源符号,是一个DC 5V电源,表示接一个5V电压。Proteus大概就是这么用电源的。你仔细看下M16,是没有VCC和GND引脚的,估计默认就是接到5V那去了,根本不让接电源。  详情 回复 发表于 2021-2-16 20:47
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2021-9-3 07:49
  • 签到天数: 941 天

    [LV.10]以坛为家III

    发表于 2021-2-16 20:37 | 显示全部楼层
    本帖最后由 hellohello22 于 2021-2-16 21:58 编辑

    IO模拟,自己写一遍时序就搞定了,读写随便切换,闻所未闻乱七八糟的, 24c02前阵子刚读写过,没有任何问题, i2c是最简单的了

    最近把spi翻了个遍, TF卡挂载FAT32也成功了,随便读写文件和电脑交换, 完全自己写的代码,包括FAT表项,目录项, 簇各种操作,简单高效

    点评

    I/O口模拟的话要写的就太多了,我也是刚学,很多C语言和指令都不熟。M16本身就有TWI硬件相关指令,读写数据是按一个字节8位来操作的,写代码相对一位一位来操作要省事。据说用I/O口模拟要用一堆的delay延时  详情 回复 发表于 2021-2-16 20:58
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2021-12-29 09:01
  • 签到天数: 1219 天

    [LV.10]以坛为家III

     楼主| 发表于 2021-2-16 20:47 | 显示全部楼层
    拓荒牛 发表于 2021-2-16 20:34
    上拉电阻那里,接了电压没?我只看到一个探针

    那个探针是激励源符号,是一个DC 5V电源,表示接一个5V电压。Proteus大概就是这么用电源的。你仔细看下M16,是没有VCC和GND引脚的,估计默认就是接到5V那去了,根本不让接电源。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2021-12-29 09:01
  • 签到天数: 1219 天

    [LV.10]以坛为家III

     楼主| 发表于 2021-2-16 20:58 | 显示全部楼层
    hellohello22 发表于 2021-2-16 20:37
    IO模拟,自己写一遍时序就搞定了,读写随便切换,闻所未闻乱七八糟的, 24c02前阵子刚读写过,没有任何问题 ...

    I/O口模拟的话要写的就太多了,我也是刚学,很多C语言和指令都不熟。M16本身就有TWI硬件相关指令,读写数据是按一个字节8位来操作的,写代码相对一位一位来操作要省事。据说用I/O口模拟要用一堆的delay延时,不好把握,用TWI硬件指令,访问TWI的中断标志就可以知道设备是否有ACK回应,根据不同回应代码就知道是什么类型的回应,相对方便些,也更高效些。I2C协议描述里,有S,P信号,也就是START和STOP信号,不过也是奇怪,发送P信号就是结束了,怎么下一次的START无效了,而且是代码正常执行,实际却没有波形。

    点评

    想学习原理,就得从底层开始,囫囵吞枣学不深,出了问题定位更难,最近我一直坚持自己写底层,收获甚大,所有细节都一清二楚,为了读写tf和串行flash, 把中断+DMA摸熟,砍柴不误磨刀工 别看网上有些看起来  详情 回复 发表于 2021-2-16 21:40
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2021-9-3 07:49
  • 签到天数: 941 天

    [LV.10]以坛为家III

    发表于 2021-2-16 21:40 | 显示全部楼层
    本帖最后由 hellohello22 于 2021-2-16 22:35 编辑
    cyradg 发表于 2021-2-16 20:58
    I/O口模拟的话要写的就太多了,我也是刚学,很多C语言和指令都不熟。M16本身就有TWI硬件相关指 ...

    想学习原理,就得从底层开始,囫囵吞枣学不深,出了问题定位更难,我一直坚持自己写底层,收获甚大,细节一清二楚,为了读写tf和串行flash, 把中断+DMA摸熟,砍柴不误磨刀工




    点评

    我看网上说I/O模拟I2C效率其实不如直接用单片机里面的TWI硬件功能高,TWI功能里一堆状态我都看不太懂,就是TWSTO,TWSTA,TWINT,TWEA,TWEN之类一堆怎么配合的看不懂,SDA,SCL时序配合比较严谨,参数一配错,设备  详情 回复 发表于 2021-2-16 23:40
    回复

    使用道具 举报

  • TA的每日心情
    擦汗
    2015-1-15 14:39
  • 签到天数: 6 天

    [LV.2]偶尔看看I

    发表于 2021-2-16 21:55 | 显示全部楼层
    我都是用汇编写,不喜欢用C,汇编写更有安全感
    回复

    使用道具 举报

  • TA的每日心情
    擦汗
    2015-1-15 14:39
  • 签到天数: 6 天

    [LV.2]偶尔看看I

    发表于 2021-2-16 22:07 | 显示全部楼层
    给楼主一个建议:用示波器看波形,时序要严格,误差不能太大;

    点评

    不会汇编。已经上示波器了,写进去看波形好像没问题,但是读被我修改的面目全非,看示波器,发出起始信号、片选信号以后,后续的内存地址,内存数据都发不出去,也不能STOP,原先都可以的,现在都不行了,  详情 回复 发表于 2021-2-16 23:19
    回复

    使用道具 举报

    该用户从未签到

    发表于 2021-2-16 22:20 | 显示全部楼层
    汇编-MS51:
    rdee:
                    call star_ee
            ;*************************      
                    mov a,dph
            ;**************************2001.7.17
                    rl a
                    orl a,#slaw                     
            ;**************************2001.7.17
                    call w1bt
                    call cack
                    jb f0,rdee_end
                    mov a,dpl
                    call w1bt
                    call cack
                    jb f0,rdee_end
                    call star_ee
            ;*************************      
                    mov a,dph
            ;**************************2001.7.17
                    rl a
                    orl a,#slar                     
            ;**************************2001.7.17
                    call w1bt
                    call cack
                    jb f0,rdee_end
                    call r1bt
                    ;call mack
                    call mnack
                    call stop_ee
            ;***********************2001.7.22      
                    clr ee_f
                    ret
    rdee_end:
                    setb ee_f
                    ;sjmp rdee
                    ret

    star_ee:
                    setb sda
                    setb scl
                    nop
                    nop
                    clr  sda
                    nop
                    nop
                    clr  scl
                    ret
    stop_ee:
                    clr  sda
                    setb scl
                    nop
                    nop
                    setb sda
                    ret
    mack:
                    clr  sda
                    setb scl
                    nop
                    nop
                    clr  scl
                    setb sda
                    ret
    mnack:
                    setb sda
                    setb scl
                    nop
                    nop
                    clr  scl
                    clr  sda
                    ret
    cack:
                    setb sda
                    setb scl
                    nop
                    nop
                    clr f0
                    jnb sda,cend
                    setb f0
            cend:
                    clr scl
                    ret
    w1bt:
                    mov r7,#08d
            wlp:
                    rlc a
                    jc wr1
            wr0:
                    clr sda
                    setb scl
                    nop
                    nop
                    clr scl;********
                    jmp wlp1
            wr1:
                    setb sda
                    setb scl
                    nop
                    nop
                    clr scl
                    clr sda
            wlp1:
                    nop
                    djnz r7,wlp
                    ret
    r1bt:
                    mov r7,#08d
            rlp:
                    setb sda
                    setb scl
                    nop
                    nop
                    jnb sda ,rd0
            rd1:
                    setb c
                    rlc a
                    clr scl
                    jmp rlp1
            rd0:
                    clr c
                    rlc a
                    clr scl
            rlp1:
                    nop
                    djnz r7,rlp
                    ret
    wree:
                    call star_ee
            ;*************************      
                    mov a,dph
            ;**************************2001.7.17
                    rl a
                    orl a,#slaw                     
            ;**************************2001.7.17
                    call w1bt
                    call cack
                    jb f0,wree_end
                    mov a,dpl
                    call w1bt
                    call cack
                    jb f0,wree_end
                    mov a,r4
                    call w1bt
                    call cack
                    jb f0,wree_end
                    call stop_ee                                                            
                    ;call led
                    push dph
                    push dpl
                    push 00h
                    push 01h
                    push a
                    push b
                    call led
                    pop b
                    pop a
                    pop 01h
                    pop 00h
                    pop dpl
                    pop dph
                    clr ee_f
                    ret
    wree_end:
                    setb ee_f      
                    ret
    回复

    使用道具 举报

    该用户从未签到

    发表于 2021-2-16 22:21 | 显示全部楼层
    24C16:
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    Nop_:
                    nop
                    nop
                    nop
                    nop
                    ret

    StarEe:
                    setb sda
                    call Nop_
                    setb scl
                    call Nop_
                    clr sda
                    call Nop_
                    clr scl
                    ret
                   
    StopEe:
                    clr sda
                    call Nop_
                    setb Scl
                    call Nop_
                    setb sda
                    call Nop_
                    clr scl
                    ret

    Ack:
                    Call Nop_
                    setb scl
                    call Nop_
                    mov c,sda
                    call Nop_
                    clr scl
                    ret

    McuAck:
                    clr sda
                    call Ack
                    setb Sda
                    ret
                   
    McuNAck:
                    setb sda
                    setb Scl
                    call NOp_
                    clr Scl
                    clr Sda
                    ret
    WrByte:
                    mov b,#8
            Wr11:
                    rlc a
                    mov sda,c
                    call Ack
                    djnz b,Wr11
                    setb Sda
                    call Ack
                    ret
    RdByte:
                    mov b,#08
            Rd11:
                    call Ack
                    rlc a
                    djnz b,Rd11
                    ret

    MakeAdr:
                    mov a,dph
                    rl a
                    orl a,#0a0h
                    ret
                   
    ;*********************************
    ;a=0 =>24c16;=>24c32...
    ;r1=Long;R0=Adr;Dptr=EeAdr
    ;*********************************
    EeAll:
                    call StarEe
                    mov a,#0
                    jz Ee24c16
                    ;*************
                    ;Ee24c32
                    mov a,#0a0h
                    call WrByte
                    jc EeErr
                    mov a,dph
                    call WrByte
                    jc EeErr
                    sjmp EeDo
            Ee24c16:
                    mov a,#dph
                    call MakeAdr
                    call WrByte
            EeDo:
                    mov a,Dpl
                    call WrByte
                    jc EeErr
                    ret
            EeErr:
                    setb ee24
                    ret
                                                   
    ;)))))))))))))))))))))))))))))))))
    WrEe:
                    call EeAll
                    jc eeerr
                    ;***** Ok
            we1:
                    mov a,r4
                    call WrByte
                    jc EeErr
                    ;********** Delay
                    call StopEe
                    clr c
                    mov ee24,c
                    ret
    RdEe:
                    call EeAll
                    jc EeErr
                    ;********* Ok
                    call StarEe
                    mov a,#0a1H
                    call WrByte
                    jc Eeerr
                    ;********** Ok
                    call RdByte
                    call McuNAck               
                    call StopEe
                    clr c
                    mov ee24,c
                    ret
    回复

    使用道具 举报

    该用户从未签到

    发表于 2021-2-16 22:22 | 显示全部楼层
    C51:
    //定义EE24XX的管脚********************************
    sbit        SCL        =P1^2;        //
    sbit        SDA =P1^3;

    /************************************************
    延时程序
    ************************************************/
    void nop_(void)
    {
            unsigned char i=5;
            while (i--);       
    }
    /***********************************************
    开始位
    ************************************************/
    void Start_ee        (void)
    {
            SDA=HIGH;
            nop_();
            SCL=HIGH;
            nop_();
            SDA=LOW;
            nop_();
            SCL=LOW;
            nop_();
    }

    /********************************
    停止位
    **********************************/
    void Stop_ee        (void)
    {
            SDA=LOW;
            nop_();
            SCL=HIGH;
            nop_();
            SDA=HIGH;
            nop_();
            SCL=LOW;
            nop_();
    }

    /*********************************
    应答位,返回SDA信号
    **********************************/
    bit Ack(void)
    {
            bit cy;
            SCL=HIGH;
            nop_();
            cy=SDA;
            SCL=LOW;
            nop_();
            return(cy);
    }

    /***********************************
    主应答 返回SDA
    ************************************/
    bit McuAck(void)
    {
            bit cy;
            SDA=LOW;
            cy=Ack();
            SDA=HIGH;
            return(cy);
    }

    /************************************
    不应答
    *************************************/
    void McuNAck(void)
    {
            SDA=HIGH;
            SCL=HIGH;
            nop_();
            SCL=LOW;
            SDA=LOW;
    }

    /************************************
    写入一个字节 ,返回成功标志
    *************************************/
    bit Wr_Byte(unsigned char Dat)
    {
            unsigned char i;
            bit cy;
            for (i=0;i<8;i++)
            {
                    if ((Dat & 0x80)==0x80) SDA=HIGH;
                            else        SDA=LOW;
                            cy=Ack();
                            Dat<<=1;
            }
            SDA=HIGH;
            return(Ack());
    }

    /**********************************
    读取一个字节
    ***********************************/
    unsigned char Rd_Byte(void)
    {
                    unsigned char i,j=0;
                    for (i=0;i<8;i++)
                    {
                            j<<=1;
                            if (Ack()) j++;
                    }
                    return j;
    }

    /*******************************************
    EE24类型检测,返回标志位
    ********************************************/
    unsigned char EeAll (unsigned int EeAdr)
    {
            Start_ee();
            #if Ee_Type                                                          //1 EE24c32__
                       if (Wr_Byte(Wr_ee)) return 1;
                    if (Wr_Byte((unsigned char)EeAdr>>8)) return 1;
                    if (Wr_Byte((unsigned char)EeAdr)) return 1;
              #else
                       if (Wr_Byte((unsigned char)(EeAdr>>7 |Wr_ee))) return 1;                       
                    if (Wr_Byte((unsigned char)EeAdr )) return 1;
       #endif
       return 0;
    }

    /****************************************************
    连续写入字节,返回UINT8标志
    *****************************************************/
    unsigned char WriteEe24(unsigned int EeAdr,unsigned char *RamAdr,unsigned char Number)
    {
            bit cy;
            if (EeAll(EeAdr)) return (0);
            while (Number--)
            {
                    cy=Wr_Byte(*RamAdr++);       
            }
            Stop_ee();       
            Delay (10);

            return (1);                       
    }

    /****************************************************
    连续读取,返回UINT8标志
    *****************************************************/
    unsigned char ReadEe24(unsigned int EeAdr,unsigned char *RamAdr,unsigned char Number)
    {
            if (EeAll(EeAdr)) return (0);
            Start_ee();
            if (Wr_Byte(Rd_ee)) return (0);
            while (--Number)
            {
                    *RamAdr++=Rd_Byte();
                    McuAck();
            }
            *RamAdr=Rd_Byte();
            McuNAck();
            Stop_ee();
            return (1);
    }
    /**************************************************
    每过10秒写入EE24
    **************************************************/
    void SaveEe24c512(void)
    {
            unsigned char Buf[2],i;
            static unsigned char Flag=0;

            if ((UseData.Tm % WrSec) ==0)
            {
                    if(Flag==0) //2004-7-9改FLAG
                    {
                            Flag=1;        //写入标志

                            Buf[1]=WorkData.Nu;
                            Buf[0]=WorkData.Nu>>8;

                            i=WriteEe24(HeadAdr+2*Menu.Piont++,Buf,2);
                   
                            if (Menu.Piont >= WrNumber)
                            {       
                                    EndCount();                //溢出
                                    UseData.ToBak=0;
                                    UseData.To=0;
                                    UseData.Tm=0;        //2004-4-18
                                    Menu.Piont=0;
                                    UseData.LedPower=Msg_Up;                //暂停放电
                            }
                    }
            }
            else
            {
                    Flag=0;
            }
    }

    回复

    使用道具 举报

    该用户从未签到

    发表于 2021-2-16 22:24 | 显示全部楼层
    24C512:
                    sda                bit p3.6
                    scl                bit p3.7

                    mov Sp,#50h
    ;*********************************************************
                    type equ 0
       
    ;TYPE =0  用EE24C01-EE24C16
    ;TYPE =1  用EE24C32-EE24C512
    ;*********************************************************
    ;测试程序
    ;*********************************************************
    tEST:
                    mov a,#0eh
                    call INput
                   
                    mov a,#type
                    mov r0,#21h
                    mov r1,#4
                    call Wree
                    call Delay
                    call Delay

                    mov a,#0h
                    call INput

                    mov a,#type
                    mov r0,#21h
                    mov r1,#8
                    call Rdee               
                    nop
                    sjmp TEST
    InPut:
                    mov r7,#8
                    mov r0,#21h
            lok1:
                    mov @r0,a
                    inc r0
                    djnz r7,lok1
                    ret
    Delay:
                    mov R7,#20
            de11:
                    djnz b,$
                    djnz R7,De11
                    ret
                   
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    ;子程序
    ;入口程序条件:
    ;A=0 用EE24C01-EE24C16
    ;A=1 用EE24C32-EE24C512
    ;DPTR =EE24XX的地址
    ;R0=MCU内部RAM的地址
    ;R1=读出(写入)数据的长度BYTE
    ;C=1操作失败
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    Nop_:
                    nop
                    nop
                    nop
                    nop
                    ret

    StarEe:
                    setb sda
                    call Nop_
                    setb scl
                    call Nop_
                    clr sda
                    call Nop_
                    clr scl
                    ret
                   
    StopEe:
                    clr sda
                    call Nop_
                    setb Scl
                    call Nop_
                    setb sda
                    call Nop_
                    clr scl
                    ret

    Ack:
                    Call Nop_
                    setb scl
                    call Nop_
                    mov c,sda
                    call Nop_
                    clr scl
                    ret

    McuAck:
                    clr sda
                    call Ack
                    setb Sda
                    ret
                   
    McuNAck:
                    setb sda
                    setb Scl
                    call NOp_
                    clr Scl
                    clr Sda
                    ret
                   
    WrByte:
                    mov b,#8
            Wr11:
                    rlc a
                    mov sda,c
                    call Ack
                    djnz b,Wr11
                    setb Sda
                    call Ack
                    ret
    RdByte:
                    mov b,#08
            Rd11:
                    call Ack
                    rlc a
                    djnz b,Rd11
                    ret

    MakeAdr:
                    mov a,dph
                    rl a
                    orl a,#0a0h
                    ret
                   
    ;*********************************
    ;a=0 =>24c16;=>24c32...
    ;r1=Long;R0=Adr;Dptr=EeAdr
    ;*********************************
    EeAll:
                    call StarEe
                    jz Ee24c16
                    ;*************
                    ;Ee24c32
                    mov a,#0a0h
                    call WrByte
                    jc EeErr
                    mov a,dph
                    call WrByte
                    jc EeErr
                    sjmp EeDo
            Ee24c16:
                    mov a,#dph
                    call MakeAdr
                    call WrByte
            EeDo:
                    mov a,Dpl
                    call WrByte
                    jc EeErr
                    ret
            EeErr:
                    nop
                    ret
                                                   
    ;)))))))))))))))))))))))))))))))))
    WrEe: ;写子程序
                    call EeAll
                    jc eeerr
                    ;***** Ok
            we1:
                    mov a,@r0
                    call WrByte
                    jc EeErr
                    ;********** Delay
                    inc r0
                    djnz r1,We1
                    call StopEe
                    clr c
                    ret
    RdEe:;读子程序
                    call EeAll
                    jc EeErr
                    ;********* Ok
                    call StarEe
                    mov a,#0a1H
                    call WrByte
                    jc Eeerr
                    ;********** Ok
                    DEC R1
                    mov a,r1
                    jz Red11
            Red1:
                    call RdByte
                    call McuAck
                    mov @r0,a
                    inc r0
                    djnz r1,Red1
            Red11:
                    call RdByte
                    MOV @R0,A
                    call McuNAck               
                    call StopEe
                    clr c
                    ret
    回复

    使用道具 举报

    该用户从未签到

    发表于 2021-2-16 22:33 | 显示全部楼层
    extern void Delay (unsigned int mS);
    //void Wr_Ee24_Byte (unsigned int EeAdr,unsigned char Dat);
    unsigned char ReadEe24(unsigned int EeAdr,unsigned char *RamAdr,unsigned char Number);
    //定义EE24XX的管脚********************************
    sbit        SCL        =P3^7;        // P3.7
    sbit        SDA =P3^6;        //P3.6
    /************************************************
    延时程序
    ************************************************/
    void nop_(void)
    {
            unsigned char i=1;
            while (i--);       
    }
    /***********************************************
    开始位
    ************************************************/
    void Start_ee        (void)
    {
            SDA=HIGH;
            nop_();
            SCL=HIGH;
            nop_();
            SDA=LOW;
            nop_();
            SCL=LOW;
            nop_();
    }

    /********************************
    停止位
    **********************************/
    void Stop_ee        (void)
    {
            SDA=LOW;
            nop_();
            SCL=HIGH;
            nop_();
            SDA=HIGH;
            nop_();
            SCL=LOW;
            nop_();
    }

    /*********************************
    应答位,返回SDA信号
    **********************************/
    bit Ack(void)
    {
            bit cy;
            SCL=HIGH;
            nop_();
            cy=SDA;
            SCL=LOW;
            nop_();
            return(cy);
    }

    /***********************************
    主应答 返回SDA
    ************************************/
    bit McuAck(void)
    {
            bit cy;
            SDA=LOW;
            cy=Ack();
            SDA=HIGH;
            return(cy);
    }

    /************************************
    不应答
    *************************************/
    void McuNAck(void)
    {
            SDA=HIGH;
            SCL=HIGH;
            nop_();
            SCL=LOW;
            SDA=LOW;
    }

    /************************************
    写入一个字节 ,返回成功标志
    *************************************/
    bit Wr_Byte(unsigned char Dat)
    {
            unsigned char i;
            bit cy;
            for (i=0;i<8;i++)
            {
                    if ((Dat & 0x80)==0x80) SDA=HIGH;
                            else        SDA=LOW;
                            cy=Ack();
                            Dat<<=1;
            }
            SDA=HIGH;
            return(Ack());
    }

    /**********************************
    读取一个字节
    ***********************************/
    unsigned char Rd_Byte(void)
    {
                    unsigned char i,j=0;
                    for (i=0;i<8;i++)
                    {
                            j<<=1;
                            if (Ack()) j++;
                    }
                    return j;
    }

    /*******************************************
    EE24类型检测,返回标志位
    ********************************************/
    unsigned char EeAll (unsigned int EeAdr)
    {
            Start_ee();
            #if Ee_Type                                                          //1 EE24c32__
                       if (Wr_Byte(Wr_ee)) return 1;
                    if (Wr_Byte((unsigned char)EeAdr>>8)) return 1;
                    if (Wr_Byte((unsigned char)EeAdr)) return 1;
              #else
                       if (Wr_Byte(((unsigned char)EeAdr>>7) |Wr_ee )) return 1;                       
                    if (Wr_Byte((unsigned char)EeAdr )) return 1;
       #endif
       return 0;
    }

    /****************************************************
    连续写入字节,返回UINT8标志
    *****************************************************/
    unsigned char WriteEe24(unsigned int EeAdr,unsigned char *RamAdr,unsigned char Number){
            unsigned char i;
            ReadEe24(EeAdr,&i,Number);

            if(i==*RamAdr)        return 0;
            if (EeAll(EeAdr)) return 0;
            while (Number--)         {
                    Wr_Byte(*RamAdr++);       
            }
            Stop_ee();       
            Delay (3500);
            return 1;                       
    }

    /****************************************************
    连续读取,返回UINT8标志
    *****************************************************/
    unsigned char ReadEe24(unsigned int EeAdr,unsigned char *RamAdr,unsigned char Number){
            if (EeAll(EeAdr)) return 0;
            Start_ee();
            if (Wr_Byte(Rd_ee)) return 0;
            while (--Number)        {
                    *RamAdr++=Rd_Byte();
                    McuAck();
            }
            *RamAdr=Rd_Byte();
            McuNAck();
            Stop_ee();
            return 1;
    }
    //***********************************************************************************
    //2006-11-28添加 比较写入数据是否相同!
    /*
    void Wr_Ee24_Byte (unsigned int EeAdr,unsigned char Dat){
            if (EeAll(EeAdr)) return;
            Wr_Byte(Dat);       
            Stop_ee();       
            Delay (6000);
    }
    */


    回复

    使用道具 举报

  • TA的每日心情
    开心
    2021-12-29 09:01
  • 签到天数: 1219 天

    [LV.10]以坛为家III

     楼主| 发表于 2021-2-16 23:19 | 显示全部楼层
    dqp05 发表于 2021-2-16 22:07
    给楼主一个建议:用示波器看波形,时序要严格,误差不能太大;

    不会汇编。已经上示波器了,写进去看波形好像没问题,但是读被我修改的面目全非,看示波器,发出起始信号、片选信号以后,后续的内存地址,内存数据都发不出去,也不能STOP,原先都可以的,现在都不行了,好像也没改多少呀,哎,I2C真TMD啰嗦。

    点评

    ATMEL公司已经停产单片机吧?  详情 回复 发表于 2021-2-16 23:42
    回复

    使用道具 举报

    本版积分规则

    小黑屋|手机版|Archiver|论坛自带搜索|下载论坛app|手电大家谈-手电筒爱好者之家 ( 备案序号:鲁ICP备05002565号 )
    以上言论纯属个人观点,与手电大家谈立场无关。
    最佳浏览模式:1920*1080


    GMT+8, 2024-11-20 02:27 , Processed in 0.156213 second(s), 66 queries , Gzip On.

    Powered by Discuz! X3.4

    © 2001-2023 Discuz! Team.

    快速回复 返回顶部 返回列表