winnie 发表于 2009-5-5 17:37:51

PIC单片机通讯E2PROM

本帖最后由 winnie 于 2009-5-5 17:39 编辑

;=======================================      
PIC16C74B单片机与AT24C64通讯
;该程序实现的功能是:
;将I2C_A,I2C_B.....I2C_K内容写入EEPROM中
;同时在EEPROM中读出数据从新写入各个寄存器
;=======================================
      LISTP=16C74B
      #include<p16c74.inc>
      ERRORLEVEL-302
I2C_A    EQU      0X20   
I2C_B    EQU      0X21
I2C_C    EQU      0X22
I2C_D    EQU      0X23
I2C_E    EQU      0X24
I2C_F    EQU      0X25
I2C_G    EQU      0X26   
REG1   EQU      0X2B
REG2   EQU      0X2C
COUNT    EQU      0X71            ;I2C
BCOUNT   EQU      0X72            ;I2C
TXBUF    EQU      0X73            ;I2C
RXBUF    EQU      0X74            ;I2C
BUSCON   EQU      0X75            ;I2C
BUSSTA   EQU      0X76            ;I2C
I2CBUF   EQU      0X77            ;I2C
SLAVEADDR      EQU    0XA0      ;I2C
DATAADDRH      EQU    0X01      ;I2C
DATAADDRL      EQU    0X00      ;I2C
;---------------------------------------   
;BUSCON
;---------------------------------------   
SLAVE_RW      EQU       7
LAST_BYTE_RX    EQU       6
SLAVE_ACTIVE    EQU       5
TIME_OUT      EQU       4
;---------------------------------------   
;BUSSTA
;---------------------------------------
BUS_BUSY          EQU       7
TX_PROGRESS       EQU       6
RX_PROGRESS       EQU       5
TX_SUCCESS      EQU       4
RX_SUCCESS      EQU       3
FATAL_ERROR       EQU       2    ;SLAVE EEPROM
ABORT             EQU      1
ACK_ERROR         EQU       0
;---------------------------------------
R_NOT_WEQU       0         
TRUE   EQU       1
FALSE    EQU       0
SDA      EQU   0X04            ;I2C
SCL      EQU   0X03            ;I2C
;=======================================
      ORG   0X00
      GOTO    START
      ORG   0X20
START   BCF   STATUS,RP1
      BCF   STATUS,RP0
      CLRF    RA
      CLRF    RB
      CLRF    RC
      CLRF    RD
      CLRF    RE      
      BSF   STATUS,RP0
      CLRF    TRISA
      CLRF    TRISB                     
      CLRF    TRISC
      CLRF    TRISD
      CLRF    TRISE
      MOVLW   0X02
      MOVWF   I2C_A
      MOVLW   0X04
      MOVWF   I2C_B
      MOVLW   0X03
      MOVWF   I2C_C
      MOVLW   0X03
      MOVWF   I2C_D
      MOVLW   0X05
      MOVWF   I2C_E
      MOVLW   0X06
      MOVWF   I2C_F
      MOVLW   0X04
      MOVWF   I2C_G
;=======================================      
START1
      CALL   I2CBUS_INIT
      CALL   REGTOI2CBUF
      CALL   I2CWRITE
      CALL   CLRI2CBUF
      CALL   D10
      CALL   I2CREAD      
      CALL   I2CBUFTOREG
      GOTO   START1
;=======================================   
;CLRI2CBUF
;---------------------------------------
CLRI2CBUF
      BCF      STATUS,RP0
      MOVLW      I2CBUF
      MOVWF      FSR
      MOVLW      0X08
      MOVWF      COUNT
CLRLOOP CLRF       INDF
      INCF       FSR,F
      DECFSZ   COUNT,F
      GOTO       CLRLOOP
      RETURN
;---------------------------------------   
;将各个REGSTER数据写入 I2CBUF 缓冲区
;---------------------------------------
REGTOI2CBUF
      BCF      STATUS,RP0
      MOVLW      I2CBUF
      MOVWF      FSR
      MOVF       I2C_A,W
      MOVWF      INDF
      INCF       FSR,F
      MOVF       I2C_B,W
      MOVWF      INDF
      INCF       FSR,F
      MOVF       I2C_C,W
      MOVWF      INDF
      INCF       FSR,F
      MOVF       I2C_D,W
      MOVWF      INDF
      INCF       FSR,F
      MOVF       I2C_E,W
      MOVWF      INDF
      INCF       FSR,F
      MOVF       I2C_F,W
      MOVWF      INDF
      INCF       FSR,F
      MOVF       I2C_G,W
      MOVWF      INDF
      RETURN
;---------------------------------------
;将 I2CBUF 缓冲区数据写入各个REGSTER
;---------------------------------------      
I2CBUFTOREG
      BCF      STATUS,RP0
      MOVLW      I2CBUF
      MOVWF      FSR
      MOVF       INDF,W
      MOVWF      I2C_A
      INCF       FSR,F
      MOVF       INDF,W
      MOVWF      I2C_B
      INCF       FSR,F
      MOVF       INDF,W
      MOVWF      I2C_C
      INCF       FSR,F
      MOVF       INDF,W
      MOVWF      I2C_D
      INCF       FSR,F
      MOVF       INDF,W
      MOVWF      I2C_E
      INCF       FSR,F
      MOVF       INDF,W
      MOVWF      I2C_F
      INCF       FSR,F
      MOVF       INDF,W
      MOVWF      I2C_G
      RETURN
;=======================================   
;将I2CBUF缓冲区内的数据写入EEPROM
;=======================================
I2CWRITE
      CALL       I2CSTART
      BTFSS      BUSSTA,BUS_BUSY
      GOTO       TX_FAIL
      BCF      BUSCON,SLAVE_RW
      CALL       TX_SLAVE_ADDR
      BTFSS      BUSSTA,TX_SUCCESS    ;SUCESSFULL?
      GOTO       TX_FAIL
      CALL       TX_DATA_ADDR
      BTFSS      BUSSTA,TX_SUCCESS
      GOTO       TX_FAIL
      MOVLW      I2CBUF
      MOVWF      FSR
      MOVLW      07
      MOVWF      COUNT
T_BYTE_LOOP
      MOVF       INDF,W
      MOVWF      TXBUF
      CALL       I2CTXB
      BTFSS      BUSSTA,TX_SUCCESS
      GOTO       TX_FAIL
      INCF       FSR,F
      DECFSZ   COUNT,F
      GOTO       T_BYTE_LOOP
      GOTO       TX_PASS
TX_FAIL CALL       I2CSTOP
      BCF      BUSSTA,TX_PROGRESS
      BCF      BUSSTA,TX_SUCCESS
      RETLW      FALSE
TX_PASS
      CALL       I2CSTOP
      BCF      BUSSTA,TX_PROGRESS
      RETLW      TRUE
;---------------------------------------            
;从 EEPROM 中读出数据到 I2CBUF 寄存器
;---------------------------------------
I2CREAD BCF      STATUS,RP0
      BCF      BUSSTA,RX_SUCCESS
      CALL       I2CSTART
      BTFSS      BUSSTA,BUS_BUSY
      GOTO       RX_FAIL
      BCF      BUSCON,SLAVE_RW
      CALL       TX_SLAVE_ADDR
      BTFSS      BUSSTA,TX_SUCCESS   
      GOTO       RX_FAIL
      CALL       TX_DATA_ADDR
      BTFSS      BUSSTA,TX_SUCCESS
      GOTO       RX_FAIL
      CALL       I2CSTART
      BSF      BUSCON,SLAVE_RW
      CALL       TX_SLAVE_ADDR
      BTFSS      BUSSTA,TX_SUCCESS
      GOTO       RX_FAIL
      BCF      BUSSTA,LAST_BYTE_RX
      MOVLW      I2CBUF
      MOVWF      FSR
      MOVLW      07
      MOVWF      COUNT
R_BYTE_LOOP
      MOVLW      0X01
      XORWF      COUNT,W
      BTFSC      STATUS,Z
      BSF      BUSSTA,LAST_BYTE_RX
      CALL       I2CRXB
      BTFSS      BUSSTA,RX_SUCCESS
      GOTO       RX_FAIL
      MOVF       RXBUF,W   
      MOVWF      INDF
      INCF       FSR,F
      DECFSZCOUNT,F
      GOTO       R_BYTE_LOOP
      GOTO       RX_PASS
RX_FAIL CALL       I2CSTOP
      BCF      BUSSTA,RX_PROGRESS
      BCF      BUSSTA,RX_SUCCESS
      RETLW      FALSE
RX_PASS CALL       I2CSTOP
         BCF      STATUS,RP0
      BCF      BUSSTA,TX_PROGRESS
      BCF      BUSSTA,RX_PROGRESS
      BSF      BUSSTA,RX_SUCCESS
      RETLW      TRUE
;=======================================      
; I2C 初始化
;=======================================
I2CBUS_INIT
      BCF      STATUS,RP0
      MOVF       RC,W
      ANDLW      0X18
      MOVWF      RC
      CLRF       BUSSTA
      CLRF       BUSCON
      RETURN         
;=======================================   
; 传送设备地址
;入口:BUSCON
;出口:BUSSTA
;=======================================
TX_SLAVE_ADDR
      BCF      STATUS,RP0
      BCF      BUSSTA,ACK_ERROR
      MOVLW      SLAVEADDR
      MOVWF      TXBUF
      BTFSC      BUSCON,SLAVE_RW
      BSF       TXBUF,R_NOT_W
      CALL       I2CTXB         
      BTFSC      BUSSTA,TX_SUCCESS
      GOTO       TXADDR_SUCCESS
      CLRWDT
      BTFSS      BUSSTA,ACK_ERROR
      CALL       I2CSTOP
      GOTO       TXADDR_END
TXADDR_SUCCESS
      CLRWDT
TXADDR_END
      RETURN
;=======================================   
;TX_DATA_ADDR   发送写/读的地址
;=======================================
TX_DATA_ADDR
      BCF      STATUS,RP0
      MOVLW      DATAADDRH
      MOVWF      TXBUF
      CALL       I2CTXB
      BCF      STATUS,RP0
      BTFSS      BUSSTA,TX_SUCCESS
      GOTO       TX_DATA_ADDR_ERROR
      MOVLW      DATAADDRL
      MOVWF      TXBUF
      CALL       I2CTXB
      BCF      STATUS,RP0
      BTFSS      BUSSTA,TX_SUCCESS
      GOTO       TX_DATA_ADDR_ERROR
      GOTO       TX_DATA_END
TX_DATA_ADDR_ERROR
      BCF      BUSSTA,TX_PROGRESS
      BCF      BUSSTA,TX_SUCCESS
      BSF      BUSSTA,ACK_ERROR
TX_DATA_END
      RETURN
;=======================================   
;向 EEPROM 输出一个8位数据,并检测EEPROM的ACK信号
;入口:TXBUF寄存器
;       BUSSTA 寄存器
;出口:EEPROM 存储器
;       BUSSTA 寄存器
;======================================   
I2CTXBBCF      STATUS,RP0
      BSF      BUSSTA,TX_PROGRESS
      BCF      BUSSTA,TX_SUCCESS
      MOVLW      0X08
      MOVWF      BCOUNT
TXLOOPCLRWDT               
      BSF      STATUS,RP0   
      BCF      TRISC,SCL
      NOP   
      BCF      TRISC,SDA   
      BCF      STATUS,RP0   
      RLF      TXBUF,F      
      BSF      STATUS,RP0
      BTFSC      STATUS,C
      BSF      TRISC,SDA
      NOP
      BSF      TRISC,SCL
      NOP
      NOP
      BCF      STATUS,RP0
      DECFSZ   BCOUNT,F
      GOTO       TXLOOP
;---------------------------------------
;检测是EEPROM否有ACK信号产生,产生为正常
;检测方法:
;   1. 将RC口的SCL.SDA分别设置为输出和输入状态
;   2. 延时2个指令周期,将SCL设置为高电平
;   3. 延时2个指令周期,检测RC口SDA的状态
;   4. 如果为高电平,设置错误状态,返回
;   5. 如果为低电平,延时2个指令周期后,将RC口SCL设置为低电平,继续执行
;---------------------------------------
      BSF      STATUS,RP0
      BCF      TRISC,SCL
      BSF      TRISC,SDA
      NOP
      NOP
      BSF      TRISC,SCL
      NOP
      BCF      STATUS,RP0
      BTFSC      RC,SDA
      GOTO       TX_ERR
      BSF      STATUS,RP0
      BCF      TRISC,SCL
      BCF      STATUS,RP0
      BCF      BUSSTA,TX_PROGRESS
      BSF      BUSSTA,TX_SUCCESS
      BCF      BUSSTA,ACK_ERROR
      GOTO       TX_END
TX_ERRBCF      BUSSTA,TX_PROGRESS
      BCF      BUSSTA,TX_SUCCESS
      BSF      BUSSTA,ACK_ERROR
TX_ENDRETURN
;=======================================
;从EEPROM中读出 8 位的数据,并发送发送ACK信号
;入口:EEPROM存储器
;       BUSCON寄存器
;出口:RXBUF   寄存器
;       BUSSTA寄存器
;=======================================
I2CRXBBCF      STATUS,RP0
      BSF      BUSSTA,RX_PROGRESS
      BCF      BUSSTA,RX_SUCCESS
      MOVLW      0X08
      MOVWF      BCOUNT
RXLOOPCLRWDT
      BSF      STATUS,RP0
      BCF      TRISC,SCL          ;定义TRISC<SCL>为输出
      BSF      TRISC,SDA          ;定义TRISC<SDA>为输入      
      NOP            
      NOP
      BSF      TRISC,SCL          ;TRISC<SCL>输出高电平
      NOP
      BCF      STATUS,RP0
      BCF      STATUS,C
      BTFSC      RC,SDA             ;原指令为BTFSC TRISC,SDA
      BSF      STATUS,C
      RLF      RXBUF,F
      DECFSZ   BCOUNT,F
      GOTO       RXLOOP
;---------------------------------------
;发送ACK信号到EEPROM
;判断接收的是否为最后一个字节
;LAST_BYTE_RX为1,是    SDA发送一个高电平,结束
;LAST_BYTE_RX为0,不是SDA发送一个低电平ACK,继续接收
;---------------------------------------
      BSF      STATUS,RP0
      BCF      TRISC,SCL      
      BCF      TRISC,SDA      
      BTFSC      BUSCON,LAST_BYTE_RX      ;检测是否是最后一个字节
      BSF      TRISC,SDA                ;是最后一个字节
      NOP                           ;发送ACK信号
      BSF      TRISC,SCL
      NOP
      NOP
      NOP
      NOP
      BCF      TRISC,SCL
      BCF      STATUS,RP0
      BCF      BUSSTA,RX_PROGRESS   
      BSF      BUSSTA,RX_SUCCESS
      RETURN
;=======================================
;I2C 开始信号
;输入:无
;输出:BUFSSTA<BUS_BUSY>
;=======================================
I2CSTART
      BSF   STATUS,RP0
      BSF   TRISC,SDA    ;1US
      NOP                     ;1US
      BSF   TRISC,SCL       ;1US
      NOP
      NOP
      BCF   TRISC,SDA
      NOP
      NOP
      BCF   STATUS,RP0
      BSF   BUSSTA,BUS_BUSY
      RETURN
;=======================================
;I2C 结束信号
;输入:无
;输出:BUSSTA<BUS_BUSY>
;=======================================
I2CSTOP
      BSF   STATUS,RP0
      BCF   TRISC,SCL
      BCF   TRISC,SDA
      BSF   TRISC,SCL
      NOP
      NOP
      BSF   TRISC,SDA
      NOP
      BCF   STATUS,RP0
      BCF   BUSSTA,BUS_BUSY            
      RETURN
;=======================================
; D10 @
;clock in 4Mhz
;delay 10ms
;=======================================   
D10    MOVLW    0X0D      
    MOVWF    REG1
LOOP2    MOVLW    0XFF      
    MOVWF    REG2
LOOP1    DECFSZ    REG2,f
    GOTO    LOOP1
    DECFSZ    REG1,f
    GOTO    LOOP2
    RETURN
;=======================================
I2CERRCLRWDT
      NOP
      NOP
      NOP
      RETURN
      END
页: [1]
查看完整版本: PIC单片机通讯E2PROM