打印

16F877A的EEPROM读写问题

[复制链接]
3653|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
longinus|  楼主 | 2008-11-10 13:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近尝试着使用EEPROM进行读写,但是不管怎么修改,发现写入EEPROM正常,但是读取的时候不正常。

我的程序思路是依次将 69H 96H 5AH这三个数依次写入EEPROM内的20H,21H,22H,每次都将写入的数发送出来,写完发送0F5H;然后再依次读出来,每读完一个地址都发送读出的数据,读完后发送0F6H。

但是读出来的结果始终是5A 5A 5A,而不是69 96 5A,改了好几天都没效果,请各位大侠指点下。

我试过读数的时候每次将EEADR的值发送出来,发现每次都是00H,不知是什么原因,而我程序里面设置了它累加的


#include <P16F877A.INC>
 list p=16F877A,r=HEX
;clock is 4MHz
;Set Configuration Word: crystal oscillator XT, WDT off, 
;     power-up timer on, code protect off, LV Program on.
    __CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _LVP_OFF & _CPD_ON

DATAA         equ  73h
DATAB         equ  74h
DATAC         equ  75h
CNT           equ  76h

;***************************************************       
       ORG     0000H
       NOP
       GOTO    MAIN
;**************************************************   
MAIN
       CALL    INITIAL                
LOOP   
       CALL    EEPW1
       CALL    EEPR1
       GOTO    $      

;****************************************************
INITIAL 
        BSF         STATUS,RP0         ;选体1
        MOVLW       19H                ;9600波特率
        MOVWF       SPBRG
        MOVLW       80H                ;使能RC6 RC7
        MOVWF       TRISC
        MOVLW       0X04               ;选择异步高速方式传输8位数据
        MOVWF       TXSTA
     
        BCF         STATUS,RP0 
        MOVLW       B'10010000'         ;允许同步串行口工作,连续接收
        MOVWF       RCSTA 
        CLRF        PORTC               ;清PORT

        MOVLW       69H
        MOVWF       DATAA
        MOVLW       96H
        MOVWF       DATAB
        MOVLW       5AH
        MOVWF       DATAC

        RETURN
;***************************************************
EEPW1                       ;存储状态到1号位置
       
       MOVLW  D'03'
       MOVWF  CNT
       MOVLW  DATAA
       MOVWF  FSR
       
       BSF    STATUS,RP1
       BCF    STATUS,RP0   ;选择BANK2
       MOVLW  20H          ;将目标地址1写入EEADR
       MOVWF  EEADR
LOOP1  BSF    STATUS,RP1
       BSF    STATUS,RP0   ;选定BANK3
       CLRF   EECON1
       BTFSC  EECON1,WR    ;检测WR是否为1,是1则跳转
       GOTO   $-1  
       BCF    STATUS,RP0
       MOVF   INDF,W
       MOVWF  EEDATA
       BSF    STATUS,RP0   ;选择BANK3
       BCF    EECON1,EEPGD ;指定数据存储器为写操作对象
       BSF    EECON1,WREN  ;放开写操作使能位
       BCF    INTCON,GIE   ;禁止所有中断

       MOVLW  0x55         ;此段为固定的验证程序
       MOVWF  EECON2
       MOVLW  0xAA
       MOVWF  EECON2
       BSF    EECON1,WR    ;开始写入

       BCF    EECON1,WREN   ;写保护
       BTFSC  EECON1,WRERR
       GOTO   LOOP1
       INCF   FSR,F
       BCF    STATUS,RP0
       INCF   EEADR,F

       BANKSEL EEDATA
       MOVF    EEDATA,W
       BANKSEL TXREG
       MOVWF   TXREG
       CALL    TX
       DECFSZ  CNT,F
       GOTO    LOOP1
       BSF     INTCON,GIE   ;开放中断
       BANKSEL TXREG
       MOVLW   0F5H
       MOVWF   TXREG
       CALL    TX
       RETURN
;*********************************************
EEPR1                      ;读取1号位置状态
       MOVLW  D'03'
       MOVWF  CNT
       MOVLW  DATAA
       MOVWF  FSR      

       BSF    STATUS,RP1    
       BCF    STATUS,RP0   ;选择BANK2
       MOVLW  20H
       MOVWF  EEADR     
LOOPR1 
       BSF    STATUS,RP1
       BSF    STATUS,RP0
       BCF    EECON1,EEPGD ;指定数据存储器为读操作对象
       BSF    EECON1,RD    ;启动一次读操作
       BCF    STATUS,RP0   ;选择BANK2
       MOVF   EEDATA,W     ;将EEDATA中的数据转移到W
       MOVWF  INDF
       BANKSEL TXREG
       MOVWF   TXREG
       CALL   TX
       BANKSEL EEADR
       INCF   FSR,F
       INCF   EEADR,F      
       DECFSZ CNT,F
       GOTO   LOOPR1
       BCF    STATUS,RP1   ;选择BANK0     
       MOVLW  0F6H
       MOVWF  TXREG
       CALL   TX
       RETURN
;***************************************************
TX    
      BSF STATUS,RP0 
      BSF TXSTA,TXEN ;发送允许
      BCF STATUS,RP0 
      BTFSS PIR1,TXIF 
      GOTO $-1
      RETURN


  end
沙发
longinus|  楼主 | 2008-11-10 14:00 | 只看该作者

结果

这是我用串口调试助手收到的结果

使用特权

评论回复
板凳
庄庄| | 2008-11-19 13:21 | 只看该作者

有可能是通信波特率的问题

建议你检查通信程序,晶振是内部,还是外部,一般读写不会出错

使用特权

评论回复
地板
headwolf| | 2008-11-19 17:29 | 只看该作者

EE区写代码错了。

 BSF    EECON1,WR    ;开始写入

 BCF    EECON1,WREN   ;写保护
代码有问题。WREN不是什么写保护位,是写使能位,都还没写完就清掉.

使用特权

评论回复
5
bobo1957| | 2008-11-28 15:32 | 只看该作者

必须按照芯片时序来做

microchip官网专门有EEprom的文档,看看基本就没有问题了。时序必须是datasheet上面的、控制寄存器位要认真看看什么意思

使用特权

评论回复
6
bobo1957| | 2008-12-17 23:56 | 只看该作者

你怎么知道写入对了读出没有对呢

使用特权

评论回复
7
洪七公| | 2008-12-20 21:30 | 只看该作者

16F877A的EEPROM读写宏定义

;HotPower 2005.3.25
;读取EEPROM函数READEEPROM()
;-------读取EEPROM函数READEEPROM()-------------
;读取eeprom函数Readeeprom()-------------
#define ReadeepromByte(ADDR,DATA) Procedure_ReadeepromByte ADDR,DATA
Procedure_ReadeepromByte MACRO ADDR,DATA
        local   start
  MainCbanksel = 0
        ifndef  Function_Readeeprom
          #define Function_Readeeprom Function_Readeeprom_Call_Address
          GOTO    start
Function_Readeeprom_Call_Address
          CBANKSEL EECON1 
          BCF      EECON1,EEPGD;选中EEPROM
          BSF      EECON1,RD;读EEPROM
          return
        endif
start
  MainCbanksel = 0
        ByteVal(EEADR,ADDR);
        ACALL    Function_Readeeprom
        ByteVar(DATA,EEDATA);
  MainCbanksel = 0
        ENDM

#define ReadeepromWord(ADDR,DATA) Procedure_ReadeepromWord ADDR,DATA
Procedure_ReadeepromWord MACRO ADDR,DATA
        local   start
  MainCbanksel = 0
        ifndef  Function_Readeeprom
          #define Function_Readeeprom Function_Readeeprom_Call_Address
          GOTO    start
Function_Readeeprom_Call_Address
          CBANKSEL EECON1 
          BCF      EECON1,EEPGD;选中EEPROM
          BSF      EECON1,RD;读EEPROM
          return
        endif
start
  MainCbanksel = 0
        ByteVal(EEADR,ADDR);
        ACALL    Function_Readeeprom
        ByteVar(DATA,EEDATA);
        IncByte(EEADR);
        ACALL    Function_Readeeprom
        ByteVar(DATA+1,EEDATA);
  MainCbanksel = 0
        ENDM
;-------写入EEPROM函数READEEPROM()-------------
#define WriteeepromByte(ADDR,DATA) Procedure_WriteeepromByte ADDR,DATA
Procedure_WriteeepromByte MACRO ADDR,DATA
        local start
  MainCbanksel = 0
        IFNDEF  Function_Writeeeprom
          #define Function_Writeeeprom Function_Writeeeprom_Call_Addr
          GOTO    start
Function_Writeeeprom_Call_Addr
        CBANKSEL EECON1
        BCF     EECON1,EEPGD;选中EEPROM
        MACRO_ROMWRITE_COMMAND
          RETURN
        ENDIF
start
  MainCbanksel = 0
        ByteVal(EEADR,ADDR);
        ByteVar(EEDATA,DATA);
        ACALL   Function_Writeeeprom
  MainCbanksel = 0
        ENDM 

#define WriteeepromWord(ADDR,DATA) Procedure_WriteeepromWord ADDR,DATA
Procedure_WriteeepromWord MACRO ADDR,DATA
        local start
  MainCbanksel = 0
        IFNDEF  Function_Writeeeprom
          #define Function_Writeeeprom Function_Writeeeprom_Call_Addr
          GOTO    start
Function_Writeeeprom_Call_Addr
        CBANKSEL EECON1
        BCF     EECON1,EEPGD;选中EEPROM
        MACRO_ROMWRITE_COMMAND
           RETURN
        ENDIF
start
  MainCbanksel = 0
        ByteVal(EEADR,ADDR);
        ByteVar(EEDATA,DATA);
        ACALL   Function_Writeeeprom
        IncByte(EEADR);
        ByteVar(EEDATA,DATA+1);
        ACALL   Function_Writeeeprom
  MainCbanksel = 0
        ENDM 

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

12

帖子

0

粉丝