|
本帖最后由 winnie 于 2009-5-5 17:39 编辑
;=======================================
PIC16C74B单片机与AT24C64通讯
;该程序实现的功能是:
;将I2C_A,I2C_B.....I2C_K内容写入EEPROM中
;同时在EEPROM中读出数据从新写入各个寄存器
;=======================================
LIST P=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_W EQU 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
DECFSZ COUNT,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 寄存器
;======================================
I2CTXB BCF STATUS,RP0
BSF BUSSTA,TX_PROGRESS
BCF BUSSTA,TX_SUCCESS
MOVLW 0X08
MOVWF BCOUNT
TXLOOP CLRWDT
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_ERR BCF BUSSTA,TX_PROGRESS
BCF BUSSTA,TX_SUCCESS
BSF BUSSTA,ACK_ERROR
TX_END RETURN
;=======================================
;从EEPROM中读出 8 位的数据,并发送发送ACK信号
;入口: EEPROM 存储器
; BUSCON 寄存器
;出口: RXBUF 寄存器
; BUSSTA 寄存器
;=======================================
I2CRXB BCF STATUS,RP0
BSF BUSSTA,RX_PROGRESS
BCF BUSSTA,RX_SUCCESS
MOVLW 0X08
MOVWF BCOUNT
RXLOOP CLRWDT
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
;=======================================
I2CERR CLRWDT
NOP
NOP
NOP
RETURN
END |
|