讀寫24LCxx系列的EEPROM的實例程序
;********************************************************?
;*???????????????????? *
;*??? ? PIC16F877A ?I2C Master 家Α???﹃?Α EEPROM ?絛ㄒ祘Α? *
;*?????????????????????????????????????????????????? *
;* Written by:? Richard Yang??????????????????????????????? *
;*????????????? Sr. Corporate Application Engineer??????????? *
;*????????????? Microchip Technology Inc.??????????????? *
;* Date:??????? Oct. 2nd '2002??????????????????????????? *
;* Revision: 1.00???????????????????????????????????? *
;********************************************************
;*************************************************
; This source code provides a demonstration of the MSSP peripheral
; on the PIC16F87x MCU.?
;
;
;***********????? The subroutines for EEPROM????? *****************
;
; EE_Random_Read? ; EEPROM Random address Read from EEPROM
; EE_SEQU_Read? ; EEPROM Sequential Read form EEPROM
; EE_Ack_Check? ; Polling current status of EEPROM
; EE_Page_Write? ; Page Write function for EEPROM
; EE_Byte_Write? ; Write a byte to EEPROM with address setting
;
;***********????? The subroutines for I2C????? *****************
;
; Init_I2C_Master? ; Initial I2C Module for Master Mode , 7-bit address
; StartI2C? ; Send a START Condition !!
; StopI2C?? ; Send s STOP Condition
; RstartI2C? ; Send a Repeat Start conditional to I2C
; Non_Ack?? ; Send a Non-acknowledge signal to I2C
; An_Ack?? ; Send a acknowledge signal to I2C
; Sebd_Byte? ; Send a byte to I2C bus
; RecI2C??? ; Enable Read a byte form slave device
; I2C_Done? : Wait the I2C completed the currect process
;
;***************************************************
? list p=16f877a
? #i nclude
;
;***************************************
;?????? ﹚竡跑計?RAM???
;
?? CBLOCK 0x20
? I2C_Ctrl?
? I2C_Addr
? I2C_Data
? I2C_Page_Length
? D_Count
? ENDC
? cblock 0x40
? I2C_Page_Buffer:8
? I2C_SEQU_Buffer:8
? endc
;
;***************************************
;?????? ﹚竡い耞?既?竟??
w_temp? EQU 0x72
status_temp EQU 0x73
pclath_temp EQU 0x74
;
;***************************************
;?????? ﹚竡 I2C ???の竲?
;
EEPROM_CMD equ 0xA0? ; Device adress of Slave Point
EE_Read? equ .1
EE_Write equ .0
;
#define? SCL PORTC,3? ; I2C SCL pin
#define? SDA PORTC,4? ; I2C SDA pin
;
;********************************************
; Locates startup code @ the reset vector
;********************************************
Reset_Addr
?? org? 0x00
?? nop
?? goto Main_Init
;
?? org? 0x04
?? goto ISR
;
;*************************************************************
;**** The Start Address of ISR is 0x004
;**** "PUSH" & "POP" ?ㄏノ絛ㄒ : 続ノ?鉤 PIC16F877 ΤSHARE BANK ?PIC
;**************************************************************
ISR?
Push? movwf?? w_temp???????????? ; save off current W register contents
?? movf STATUS,w?????????? ; move status register into W register
?? movwf status_temp??????? ; save off contents of STATUS register
?? movf PCLATH,W
?? movwf pclath_temp
;?
;??????? Put your interrupt code here
;
Pop?? movf pclath_temp,W
?? movwf PCLATH
?? movf??? status_temp,w??? ; retrieve copy of STATUS register
?? movwf STATUS??????????? ; restore pre-isr STATUS register contents
?? swapf?? w_temp,f
?? swapf?? w_temp,w????????? ; restore pre-isr W register contents
;
?? retfie??????????????????? ; return from interrupt
??
?
;----------------------------------------------------------------------
Main_Init??
?? pagesel Init_I2C_Master? ; Set PAGE to PCLATH Register
????? call??? Init_I2C_Master? ; Init the MSSP for I2C Master
;
????? banksel I2C_Ctrl
?? movlw EEPROM_CMD?? ; Load EEPROM command address @ 0xA0
?? movwf I2C_Ctrl
;
;
Main
;
;----------------------------------------------------------------------
;
;* ???代剛祘Α穦?盢?艙計?(0x40-0x47)糶??RMA0x40-0x47??竚?????
;* ?ノPage Write?よΑ盢8??じ艙?戈?糶? EEPROM ??????????????????
;* 秈︽?篈?盎代EEPROM琌??ЧΘ糶??笆??程?盢?糶??????????????????
;* ??戈??Sequential Read?よΑ眖EEPROM弄?ㄓ??I2C_SEQU_Bufferい????
;
Test_Page_RW
?? movlw 0x08
?? movwf I2C_Page_Length
?? movlw I2C_Page_Buffer
_Fill_RAM movwf FSR
?? movwf INDF
?? incf FSR,W
?? decfsz I2C_Page_Length,F
?? goto _Fill_RAM
;???
Test_Page_Write
;?? banksel I2C_Ctrl
?? movlw EEPROM_CMD?? ; Load EEPROM command address @ 0xA0
?? movwf I2C_Ctrl
?? movlw 0x10???? ; Select EEPROM location at 0x00
?? movwf I2C_Addr
?? movlw .8
?? movwf I2C_Page_Length
?? call EE_Page_Write
;
?? call EE_Ack_Check
;
?? banksel I2C_Ctrl
?? movlw EEPROM_CMD?? ; Load EEPROM command address @ 0xA0
?? movwf I2C_Ctrl
?? movlw 0x10
?? movwf I2C_Addr
?? movlw .8
?? movwf I2C_Page_Length
?? call EE_SEQU_Read
;
?? goto $
;
;---------------------------------------------------------
;
;* ???代剛祘Α穦?糶????じ艙?戈?糶? EEPROM い???????????????
;* ?秈︽?篈?盎代琌??ЧΘ糶??笆??程?盢?糶???????????????????????????
;* ??戈??眖EEPROM弄?ㄓ??I2C_Data既?竟い??????????????????????
;???????
Test_1byte_RW
?? banksel I2C_Ctrl
?? movlw EEPROM_CMD?? ; Load EEPROM command address @ 0xA0
?? movwf I2C_Ctrl
?? movlw 0x00??? ; Select EEPROM location at 0x00
?? movwf I2C_Addr
?? movlw 0xAA??? ; Write data 0x5A to location 0x00 of EEPROM
?? movwf I2C_Data
?? call EE_Byte_Write
;
Test2? call EE_Ack_Check? ; Polling Acknowledge for next access
;
?? banksel I2C_Data
?? movlw 0x00??? ; Clear I2C data buffer
?? movwf I2C_Data
;
Test3
?? banksel I2C_Ctrl
?? movlw EEPROM_CMD?? ; Load EEPROM command address @ 0xA0
?? movwf I2C_Ctrl
?? movlw 0x00
?? movwf I2C_Addr
?? call EE_Random_Read
?? ;
?? goto? $
;
;
;******************************************************
;*?????????? Random Read a Byte from EEPROM?????????
;*
;* Input:
;*???? - I2C_Ctrl : Control Byte of EEPROM???
;*????? - I2C_Addr : Location of EEPROM??
;* Output:
;*????? - I2C_Data : Read Data from EEPROM???
;******************************************************
;
; Send Command for RANDOM READ :
; " Start+ 0xA0 + EE_Address + ReStart + 0xA1 + Read_Data + NAck + Stop "
;
EE_Random_Read
??? call StartI2C? ; Set SSPCON2.SEN
;
?? bcf? I2C_Ctrl,0? ; set for write Command
?? movf I2C_Ctrl,W? ; Send Slave Address to I2C Bus
?? call Send_Byte
;
?? movf I2C_Addr,W? ; Send out the Rendom address of EEPROM?
?? call Send_Byte
;
?? call RstartI2C? ; Send a Repeat Start to I2C
;
?? bsf? I2C_Ctrl,0? ; set for Read Command
?? movf I2C_Ctrl,W? ; Send Slave Address to I2C Bus
?? call Send_Byte
;
?? call RecI2C? ; Enable I2C Receive
;
?? BANKSEL SSPBUF
?? movf SSPBUF,W ; Save to I2C_Data First !!
?? movwf I2C_Data
?? call Non_Ack? ; Initial NACK Response !!
?? call StopI2C? ; Initial STOP Condition
?? return
;
;***************************************************************
;*??????????????? Sequential Read from EEPROM?????????
;*
;* Input:
;*???? - I2C_Ctrl : Control Byte of EEPROM???
;*????? - I2C_Addr : Start Location of EEPROM
;*???? - I2C_Page_Length : How many byte need to read??
;* Output:
;*????? - I2C_SEQU_Buffer : Sequential Read Data buffer
;*??
;***************************************************************
;
; Send Command for RANDOM READ :
; " Start+ 0xA0 + EE_Address + ReStart + 0xA1 + Read_Data + NAck + Stop "
;
EE_SEQU_Read
??? call StartI2C? ; Set SSPCON2.SEN
;
?? bcf? I2C_Ctrl,0? ; set for write Command
?? movf I2C_Ctrl,W? ; Send Slave Address to I2C Bus
?? call Send_Byte
;
?? movf I2C_Addr,W? ; Send out the Rendom address of EEPROM?
?? call Send_Byte
;
?? call RstartI2C? ; Send a Repeat Start to I2C
;
?? bsf? I2C_Ctrl,0? ; set for Read Command
?? movf I2C_Ctrl,W? ; Send Slave Address to I2C Bus
?? call Send_Byte
;
?? movlw I2C_SEQU_Buffer
?? movwf FSR
;
_Sequ_Loop call RecI2C?? ; Enable I2C Receive
?? BANKSEL SSPBUF
?? movf SSPBUF,W? ; Save to I2C_Data First !!
?? movwf INDF
?? incf FSR,F
?? decfsz I2C_Page_Length,F
?? goto _Cont_Read
?? goto _End_Read
_Cont_Read call An_Ack
?? goto _Sequ_Loop
;
_End_Read call Non_Ack?? ; Initial NACK Response !!
?? call StopI2C?? ; Initial STOP Condition
?? return
;
;******************************************************
;*????????????? EEPROM Acknowledge Polling
;*???????????
;*???? --? The routine will polling the ACK??
;*?????????? response from EEPROM???????
;*??? --? ACK=0 return????????
;*?? --? ACK=1 send Restart & loop check
;*?
;******************************************************
;
EE_Ack_Check
??? call StartI2C? ; Set SSPCON2.SEN
???
?? bcf? I2C_Ctrl,0? ; Clear for Write Command
?? movf I2C_Ctrl,W? ; Send Slave Address to I2C Bus
?? call Send_Byte
_Ack_Polling
?? BANKSEL SSPCON2
?? btfss SSPCON2,ACKSTAT ; Check ACKSTAT bit , 0 = ACK , 1 = NACK
?? goto ACK_Return? ; Ack = 0 ; EEPROM is Ready
_Ack_Hi??????? ; Ack = 1 ; EEPROM is Busy for Write
?? call Delay_mS? ; Delay 500uS for next Ack polling
?? call RstartI2C? ; Send a Repeat Start to I2C
?? bcf? I2C_Ctrl,0? ; Clear for Write Command
?? movf I2C_Ctrl,W? ; Send Slave Address to I2C Bus
?? call Send_Byte
?? goto _Ack_Polling
?
ACK_Return
?? call StopI2C?? ; Initial STOP Condition
?? return
;
;**********************************************************
;*?????????? Page Write 1 to 8 Bytes to EEPROM????????
;*
;*? Input:
;*???? - I2C_Ctrl : Control Byte of EEPROM??
;*???? - I2C_Addr : Location of EEPROM??
;*?? - I2C_Page_Buffer: RAM location of Data
;*???? - I2C_Page_Length : Data length count
;*??
;**********************************************************
;
; Send Command for PAGE WRITE :
; " Start+ 0xA0 + EE_Address + W_Data 0+ .. + W_Data N + Stop "
;
EE_Page_Write
?? movf I2C_Page_Length,W
?? btfsc STATUS,Z
?? return
;??
??? call StartI2C? ; Set SSPCON2.SEN
;
?? bcf? I2C_Ctrl,0? ; Clear for Write Command
?? movf I2C_Ctrl,W? ; Send Slave Address to I2C Bus
?? call Send_Byte
;
?? movf I2C_Addr,W? ; Send out the Command?
?? call Send_Byte
;
?? movlw I2C_Page_Buffer
?? movwf FSR
_W1?? movf INDF,W
?? call Send_Byte
?? incf FSR,F
?? decfsz I2C_Page_Length,F
?? goto _W1
;
??? call StopI2C?? ; Initial STOP Condition
?? return
;
;
;*******************************************************
;*?????????????? Write a Byte to EEPROM???????????????
;*
;* Input:
;*???? - I2C_Ctrl : Control Byte of EEPROM???
;*????? - I2C_Addr : Location of EEPROM??
;*????? - I2C_Data : Data to EEPROM
;*??
;*******************************************************
;
; Send Command for BYTE WRITE :
; " Start+ 0xA0 + EE_Address + Write_Data + Stop "
;
EE_Byte_Write
??? call StartI2C? ; Set SSPCON2.SEN
;
?? bcf? I2C_Ctrl,0? ; Clear for Write Command
?? movf I2C_Ctrl,W? ; Send Slave Address to I2C Bus
?? call Send_Byte
;
?? movf I2C_Addr,W? ; Send out the Command?
?? call Send_Byte
;
?? movf I2C_Data,W? ; Send out the Data
?? call Send_Byte
;
??? call StopI2C?? ; Initial STOP Condition
?? return
;
;**********************************************************************
;
;?? As following subroutines perform commonly used I2C functions.
;????? You can use these subroutines for your I2C access
;
;**********************************************************************
;
;*** Initial I2Cmodule fot 7-bit I2C Master Mode with 100Kcps @4MHz
;
Init_I2C_Master????
?? BANKSEL TRISC?? ; Initial PortC,bit 3 & 4 as Input
??? bsf? SCL??? ; RC3 = SCL? ,? RC4 = SDA
?? bsf? SDA??
;
??? BANKSEL PORTC
??? bsf? SCL??? ; SCL = Hi
??? bsf? SDA??? ; SDA = Hi
;
?? movlw b'00101000'? ; I2C Master Mode, Clock Rate: FOSC/(4*SSPADD+1)
?? movwf SSPCON?? ;
;
???????? banksel SSPADD
???????? movlw?? .9????????????? ; This gives 100KHz I2C clock @ 4MHz
?? movwf?? SSPADD?? ; (4MHz/4) / (9+1)= 100KHz
;
?????? movlw?? b'10000000'???? ; Disable slew rate control,
???????? movwf?? SSPSTAT?? ; and clear status bits
;
????????? movlw?? b'00000000'???? ; Set SCL,SDA into Ready status
???????? movwf?? SSPCON2?????????
;????
?? return
;
;******?? Send START condition to bus?? *******
;
StartI2C??? ; Initiate the I2C START condition.
???????? banksel SSPCON2
????????? bsf???? SSPCON2,SEN
???????? goto I2C_Done
;
;******?? Send STOP condition to bus?? *******
;
StopI2C????
??????? banksel SSPCON2
???????? bsf???? SSPCON2,PEN
???????? goto I2C_Done
;
;******?? Send RESTART condition to bus?? *******
;?????
RstartI2C???
???????? banksel SSPCON2
???????? bsf???? SSPCON2,RSEN
???????? goto I2C_Done
;
;******?? Send a Non-Acknowledge status to bus (ACK=1)??? *******
;???????
Non_Ack
???????? banksel SSPCON2
???????? bsf???? SSPCON2,ACKDT??? ; Set the ACK bit
???????? bsf???? SSPCON2,ACKEN??? ; Initiate the NACK sequence.
???????? goto I2C_Done
;
;******?? Send an Acknowledge status to bus (ACK=0)???? *******
;????????
An_Ack
????????? banksel SSPCON2
???????? bcf???? SSPCON2,ACKDT??? ; Clear the ACK bit
???????? bsf???? SSPCON2,ACKEN??? ; Initiate the NACK sequence.
???????? goto I2C_Done
;
;******?? Send data to I2C bus from Wreg.???? *******
;
Send_Byte
?? banksel SSPBUF
?? movwf SSPBUF
?? goto I2C_Done
;
;******?? Enable I2C Receive for Master Mode???? *******
;
RecI2C
??????? banksel SSPCON2?????????
???????? bsf???? SSPCON2,RCEN??? ; Set the receive enable bit.
?? goto I2C_Done
;
;******? Check the I2C stage is completed?? ********
;
I2C_Done
???????? banksel PIR1
??? btfss?? PIR1,SSPIF ; Poll for SSPIF
???????? goto??? $-1
???????? bcf???? PIR1,SSPIF
???????? return
;
Delay_mS
?? banksel D_Count
?? movlw .124?? ; Load .5mS Dealy Value
??? movwf D_Count???
_D_mS? nop
?? decfsz D_Count,F??
?? goto _D_mS?
?? return?????????
;
; *********** End Of Program !!!!!
;
?? end
?
評論
查看更多