导航: 老古网老古论坛XMOS公共讨论区XMOS开源项目区单片机程序设计嵌入式系统广告区域
→弱弱的问个问题,关于EEPROM[hatereg]

 *第17369篇: 弱弱的问个问题,关于EEPROM

  
楼 主:hatereg 2003年11月13日14:22
 弱弱的问个问题,关于EEPROM
我写了一段读at24c08的程序,控制字和地址写正常,但等不到响应ack
不知是什么原因
请大虾指教
  
2楼:hatereg 2003年11月13日14:41
 请帮帮忙,谢谢了
  
3楼:红心j 2003年11月13日17:08
 看不到程序怎么说。
可能等待ack的操

看不到程序怎么说。
可能等待ack的操作时序不对
  
4楼:hatereg 2003年11月13日17:24
 哦?酱紫,那请大家看看我的程序。
这是个读数据程序
谢谢!

sbit SCL=P1^0;
sbit SDA=P1^1;

        
PUBLIC void start(void)
{
 SDA=1;
 SCL=1;
 TIMING_STABLE();
 SDA=0;
 DELAY_WAIT();
 SCL=0;
 TIMING_STABLE();
}

PUBLIC void stop(void)
{
 SDA=0;
 SCL=1;
 TIMING_STABLE();
 SDA=1;
 TIMING_STABLE();
 SCL=0;
 TIMING_STABLE();
}

PUBLIC void write_da(u8 send_byte)   //写数据
{
 XDATA u8 j=8;
 for(;j>  0;j--)
 {
         send_byte  <  <=1;
  SDA=CY;
  DELAY_WAIT();
  SCL=1;
  TIMING_STABLE();
  SCL=0;
  TIMING_STABLE();
 }
        SDA=1;  
}

PUBLIC void re_ack(void)    //读ACK
{
       XDATA u8 i=128;
       
       do
       {
         CY=SDA;
         i--;
       }while(CY!=0 && i>  0);         
        
        SCL=1;        
        TIMING_STABLE();
 SCL=0;
 TIMING_STABLE();
    
               
PUBLIC u8 read_da(void)       //读数据
{
 XDATA u8 receivebyte=0;
 XDATA u8 i=8;
 while(i--)
 {
  receivebyte=(receivebyte  <  <1)|SDA;
                DELAY_WAIT();
  SCL=1;
  TIMING_STABLE();
  
  SCL=0;
  TIMING_STABLE();
 }
 return(receivebyte);
}

PUBLIC void TIMING_STABLE(void)   //延时
{
 XDATA u8 i=1;
 XDATA u8 j;
 for(;i>  0;i--)
 {
                j=1;
  for(;j>  0;j--)
  {
   _nop_();
  }
 }
}

PUBLIC void DELAY_WAIT(void)  //延时
{        
        XDATA u8 j=1;
       for(;j>  0;j--)
       {
            _nop_();
       }
}
 
 
PUBLIC void read_from(u8 address,u8 *re_address)    //读数据主程序段
{    
              
  start();
 write_da(0xa0);
        re_ack();
        write_da(address);
        
        re_ack();
        start();
 write_da(0xa1);
        
 re_ack();
 *re_address=read_da();
 stop();
        DELAY_WAIT();
}

  
5楼:guest 2003年11月14日09:52
 伪写不需要等应答
伪写不需要等应答
  
6楼:hatereg 2003年11月14日11:49
 要的呀,atmel的官方资料上说要的
  
7楼:hatereg 2003年11月13日19:29
 哪个大虾指导一下,错在哪了?
  
8楼:phoibos 2003年11月14日08:53
 我写了个24C02的,不过是汇编。要的话,说一声。
能用的。02和08在地址上有些差别,你要自己改。
swordofgod@163.com
  
9楼:hatereg 2003年11月14日09:18
 好啊好啊,我要的,我给你发信
  
10楼:phoibos 2003年11月14日09:44
 已经发了。
  
11楼:hatereg 2003年11月14日10:00
 唉,目前为止没有收到
  
12楼:phoibos 2003年11月14日11:38
 贴出来好了。
调用前指明B_E2(收/发),E2ADDS(24C02起始地址),E2LONG(读写多少BYTES),E2START(目标起始地址)
设置B_T0OV和B_TR0是为了防止读死(在TIMER0里加标志)。
>   ;***************************
;READ AND WRITE 24C02(E2ROM)
;INPUT B_E2(WRITE OR READ),E2ADDS(BEGIN ADDRESS),E2LONG(WR OR RD LONG)
;IF READ,OUT=SIZE++,IF WRITE,IN=SIZE++ ;FROM R0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
E2ROM:
 PUSH ACC
 
E2_1:  CLR B_T0OV
  MOV TH0,#2BH
  MOV TL0,#0B4H
  MOV R_T0,#02H
  SETB B_TR0
 LCALL SBEGIN
 JB B_E2,E2W
E2R: MOV A,#0A0H       ;24C02地址
 LCALL SWR
         LCALL SWRACK
         JB B_T0OV,E2RET
 MOV A,E2ADDS
 LCALL SWR
         LCALL SWRACK
         JB B_T0OV,E2RET
 LCALL SBEGIN
 MOV A,#0A1H       ;24C02地址
 LCALL SWR
         LCALL SWRACK
         JB B_T0OV,E2RET
 MOV R0,E2START
E2R1: MOV R6,E2LONG
 CJNE R6,#00H,E2R3
 SJMP E2RET
E2R3: DEC R6
 CJNE R6,#00H,E2R2
        LCALL SRD
         MOV @R0,A
 LCALL SRDNACK
E2RET:  LCALL SEND
        CLR B_TR0
        JNB B_START,E2_2

E2_2:           POP ACC
        RET
E2R2:   LCALL SRD
 MOV @R0,A

 LCALL SRDACK

 INC R0
 SJMP E2R3
E2W: MOV A,#0A0H
 LCALL SWR
         LCALL SWRACK
         JB B_T0OV,E2RET
 MOV A,E2ADDS
 LCALL SWR
         LCALL SWRACK
         JB B_T0OV,E2RET
 MOV R0,E2START
 mov a,@r0
E2W1: LCALL SWR
        LCALL SWRACK
         JB B_T0OV,E2RET
 INC R0
 MOV A,@R0
 DJNZ E2LONG,E2W1
           SJMP E2RET

;*******************
SBEGIN:    SETB SDA
 SETB SCL
 ;nop
 CLR SDA
 CLR SCL
 ;nop
 RET
 ;**************
 ;INCLUDE A,
SWR:       MOV R7,#08H
 ;MOV A,#0A0H
SWR1: RLC A
 MOV SDA,C
 SETB SCL
 ;nop
 CLR SCL
 ;nop
 DJNZ R7,SWR1
 RET
 ;*******************
SRD:       MOV R7,#08H
SRD1: setb sda
 SETB SCL
 MOV C,SDA
 RLC A
 CLR SCL
 DJNZ R7,SRD1
 RET
 ;*****************
SEND:     SETB      CON2
 CLR SDA
 SETB SCL
 ;nop
 SETB SDA
 RET
 ;*****************
SWRACK:    setb sda
 SETB SCL
 ;nop
SWRACK3:   JB SDA,SWRACK1
 CLR SCL
 ;nop
SWRACK2:   RET
SWRACK1:   JB B_T0OV,SWRACK2
 SJMP SWRACK3
 ;*****************
SRDACK:    CLR SDA
 SETB SCL
 ;nop
 CLR SCL
 ;nop
 RET
 ;**************
SRDNACK:  SETB SDA
 SETB SCL
 ;nop
 CLR SCL
 ;nop
 RET

  
13楼:hatereg 2003年11月14日14:02
 不好意思的说,我不是很懂
我不太懂单片机
请问,设置了TH0、TL0和B_TOOV、B_TR0有什么关系?
是不是计数完毕就SET或CLR?
还有SEND子程序是干吗的啊?
呵呵
谢谢赐教啊
  
14楼:phoibos 2003年11月14日14:27
 这样的
在定时器0里指定TH0,TL0就行了。
在写完之后等24C02的回答之前置B_TR0,回答了就清B_TR0;这样,在定时器的中断里经过几次(次数最好大于等于2)若B_TR0都为1,就置B_T0OV。当B_T0OV=1时,认为通信故障,不再访问,同时清B_TR0,B_T0OV。
SBEGIN:访问开始
SWR:写(8BITS)
SRD:读(8BITS)
SWRACK:写后等24C02回答
SRDACK:读后回答24C02
SRDNACK:读后不回答24C02(最后一个操作)
  
15楼:Kuang-chingTsui 2003年11月14日16:58
 给你个汇遍程序片段
其中写EEPROM一段供你参考;其中的数据是我自己程序用的.你可以按照EEPROM的操作写读数据子程序.
关于IIC总线的那些子程序应当是完整的,注释我自己能看懂,不知你是否看得懂.有问题互相交流.
2402的从地址你自己定义

;IIC bus data section define:

bit_cnt     data 08h            ;Bit counter for iic routines
slv_addr    data 0ah            ;Slave address for iic routines


flags       data 28h             ;Location for bit flags
no_ack      bit flags.0         ;Iic no acknowledge flag
bus_fault   bit flags.1         ;Iic bus fault flag
iic_busy    bit flags.2         ;Iic bus is busy flag


eeprom_addr equ 0a6h            ;The address of 24c02

;a write data to eeprom subprograming

wri_rom:
            mov slv_addr,#eeprom_addr
            call master
            mov a,#18h
            call send_byte
            mov slv_addr,#eeprom_addr
            call master
            mov a,#01h
            call send_byte
            mov a,#01h
            call send_byte
            mov a,32h
            call send_byte
            mov a,33h
            call send_byte
            mov a,#02h
            call send_byte
            mov a,#02h
            call send_byte
            mov a,36h
            call send_byte
            mov a,37h
            call send_byte
            call send_stop
            call delay10

            ret


;iic bus operating subprograming

send_stop:  clr sda_pin         ;get sda ready for stop.
            setb scl_pin        ;set clock for stop.
            jnb scl_pin,$
            nop
            nop
            nop                 ;delay 3 cycles
            setb sda_pin        ;send iic stop.
                                ;delay satisfied via software.
            clr iic_busy        ;clear iic busy status.
            ret                 ;bus should now be released.

master:     setb iic_busy       ;indicate that 12c frame is in progress.
            clr no_ack          ;clear error status flags.
            clr bus_fault
            jnb scl_pin,fault   ;check for bus clear.
            jnb sda_pin,fault
            clr sda_pin         ;begin 12c start.
            nop
            nop
            nop                 ;delay_3_cycles.
            clr scl_pin         ;completa 12c start.
            nop
            nop
            nop                 ;delay_3_cycles.
            mov a,slv_addr      ;get slave address.
            call send_byte      ;send slave address.
            ret
fault:      setb bus_fault      ;set fault status.
            ret                 ;and return.

send_byte:  mov bit_cnt,#8      ;set bit count value.
sb_loop:    rlc a               ;send one data bit.
            mov sda_pin,c       ;put data bit on pin.
            setb scl_pin
            jnb scl_pin,$       ;drive scl high.
            nop
            nop
            nop                 ;delay_3_cycles.
            clr scl_pin         ;clear scl.
            nop
            nop
            nop                 ;delay_3_cycles.
            djnz bit_cnt,sb_loop;repeat until all bits sent.
            setb sda_pin        ;release data line for acknowledge.
            setb scl_pin
            jnb scl_pin,$       ;sent clock for acknowledge.
            nop
            nop
            nop
            nop                 ;delay_4_cycles.
            jnb sda_pin,sb_ex   ;cheek for valid acknowledge bit.
            setb no_ack         ;set status for no acknowledge.

sb_ex:      clr scl_pin         ;finish acknowledge bit.
            nop
            nop
            nop                 ;delay_3_cycles.
            ret                 ;return.


recv_byte:  mov bit_cnt,#8      ;set bit count.
rb_loop:    setb scl_pin
            jnb scl_pin,$       ;read one data bit.
            nop
            nop
            nop                 ;delay_3_cycles.
            mov c,sda_pin       ;get data bit from pin.
            rlc a               ;rotate bit into result byte.
            clr scl_pin         ;clear scl pin.
            nop
            nop
            nop                 ;delay_3_cycles.
            djnz bit_cnt,rb_loop;repeat accumulator.
            push acc            ;save accumulator.
            mov a,byte_cnt      ;copies byte count into a.
            cjne a,#1,rb_ack    ;check for last byte of frame.
            setb sda_pin        ;send no acknowledge on last byte.
            sjmp rb_aclk        ;no ack on last byte;jump to rb_aclk.
rb_ack:     clr sda_pin         ;send acknowledge bit.
rb_aclk:    setb scl_pin
            jnb scl_pin,$       ;send acknowledge clock.
            pop acc             ;restore accumulator.
            nop
            nop
            nop                 ;delay_3_cycles.
            clr scl_pin         ;clear scl pin.
            setb sda_pin        ;clear ackonwledge bit.
            nop
            nop
            nop
            nop                 ;delay_4_cycles.
            ret                 ;return from recv_byte.


;Delay subprograming

delay10:    mov r7,#28
delay10_lp: mov r6,#8fh
            djnz r6,$
            djnz r7,delay10_lp
            ret

  
16楼:hatereg 2003年11月14日17:06
 呵呵,谢谢大家啊,很长知识的哦
  
17楼:Kuang-chingTsui 2003年11月14日20:21
 24c08 除芯片地址定义与24c02不同外,读写方式是一样的。
  
18楼:guest 2003年11月15日10:13
 在写完address 后,等到应答。之后
在写完address 后,等到应答。之后在发完启动信号,24c08就会发出位于address的内容,为何还要写0xa1?
  
19楼:Kuang-chingTsui 2003年11月15日12:00
 芯片地址的最低BIT为0则写操作,为1则读操作.手册上很明白喽.............



>>>>>>对该主题发表你的看法

本主题贴数19,分页: [第1页]


[上一篇主题]:请问以.NH结尾的文件如何打开?先谢了。

[下一篇主题]:寻求价格便宜的录音/录像解决方案,欢迎有性趣的DX跟贴交流指导。