; ; *************************************************************************** ; *** Bubble Software Parallax to PIC Source Converter. Copyright 1999. *** ; *** http://www.picnpoke.com email: sales@picnpoke.com *** ; *************************************************************************** ; ; EEPROM (related subroutines) ; This is a collection of subroutines for reading, writing, and ; erasing the 93LC56 (or 'C56) serial EEPROM. As a demonstration, it ; writes a scanning pattern to the 256 bytes of the EEPROM, and then ; reads it back to eight LEDs connected to port rb. P = pic16c54 #include <16c54.inc> ; processor assembler definitions _CONFIG _xt_osc & _wdt_off & _protect_off reset start D equ ra.0 ; Pins DI and DO of the EEPROM CLK equ ra.1 ; Clock pin--data valid on rising edge CS equ ra.2 ; Chip select--high = active ROP equ d'192' ; Opcode for read WROP equ d'160' ; Opcode for write EWEN equ d'152' ; Opcode to enable erase and write EWDS equ d'128' ; Opcode to disable erase and write ERAS equ d'224' ; Opcode to erase a byte ERAL equ d'144' ; Opcode to erase all bytes WRAL equ d'136' ; Opcode to write all bytes org 8 temp Res d'1' ; Temporary variable for EE routines EEdata Res d'1' ; Data to EEwrite/wrall, from EEread EEaddr Res d'1' ; Address to EErase, EEwrite, EEread clocks Res d'1' ; Number of clock cycles for SHiftOUT tick1 Res d'1' ; Timer for demo. tick2 Res d'1' ; Timer for demo. org 0 start MOVLW d'0' ; Clear ports MOVWF 5h MOVLW d'0' MOVWF 6h MOVLW d'0' ; Make all ra pins outputs initially. TRIS 5h MOVLW d'0' ; Output for LEDs. TRIS 6h CALL EEnable ; Turn off write/erase protection. MOVLW d'1' ; EEdata = 1. MOVWF EEdata MOVLW d'0' ; Start at address 0. MOVWF EEaddr start_loop CALL EEwrite ; Write pattern to EEPROM CALL Busy ; Wait until done writing. RRF EEdata ; Rotate the pattern right. INCFSZ EEaddr ; FOR EEaddr = 0 to 255... GOTO start_loop CALL EEdisbl ; Turn write/erase protection back on. start_loop2 CALL EEread ; Now read back contents of EEPROM. MOVF EEdata,w ; Display the EEPROM data on LEDs. MOVWF 6h INCF EEaddr ; Set up for next address. CALL delay ; Delay to slow down the scanning. GOTO start_loop2 ; Do forever. ; Shout shifts out the bits of the variable temp to the EEPROM data line. ; All of the other EEPROM routines call Shout. Shout RLF temp ; Rotate bit7 of temp into carry BTFSS status,c ; Move carry bit to input of EEPROM BCF 5h,d'0' BTFSC status,c BSF 5h,d'0' BSF 5h,d'1' ; Clock the bit into EEPROM NOP ; Clock must be high > 500 ns BCF 5h,d'1' DECFSZ clocks ; FOR I = 1 TO clocks... GOTO Shout RETLW 0h ; Read the byte in EEaddr into EEdata. EEread MOVLW ROP ; Move the read opcode into temp MOVWF temp MOVLW d'4' ; Number of bits to shift out (op+1) MOVWF clocks BSF 5h,d'2' ; Select the EEPROM. CALL Shout ; Shift the read opcode out. MOVLW d'8' ; Number of bits to output (8 addr bits). MOVWF clocks MOVF EEaddr,w ; Set up to send the address. MOVWF temp CALL Shout ; Shift out the address. MOVLW d'1' ; Now, change D to input. TRIS 5h MOVLW d'8' ; Number of bits to input (8 data bits). MOVWF clocks EEread_read BSF 5h,d'1' ; Data valid on rising edge of clock. BTFSS 5h,d'0' ; Data bit into carry. BCF status,c BTFSC 5h,d'0' BSF status,c RLF temp ; Rotate carry into temp. BCF 5h,d'1' ; Falling edge of clock. DECFSZ clocks ; FOR I = 1 TO 8... GOTO EEread_read MOVF temp,w ; Move temp into EEdata MOVWF EEdata MOVLW d'0' ; Restore D to output. TRIS 5h BCF 5h,d'2' ; Deselect the EEPROM. RETLW 0h ; Call to unprotect after EEdisbl or power up or any time EEPROM ; has been write protected. EEnable BSF 5h,d'2' ; Select the EEPROM. MOVLW d'12' ; Set up to shift out opcode. MOVWF clocks MOVLW EWEN ; temp = erase/write-enable op code. MOVWF temp CALL Shout ; Shift temp out to the EEPROM. BCF 5h,d'2' ; Done. Deselect EEPROM. RETLW 0h ; Call to protect against accidental write/erasure. Manufacturer advises ; leaving EEPROM in write-protected state most of the time to prevent accidental ; alteration by a runaway program. EEdisbl BSF 5h,d'2' ; Select the EEPROM. MOVLW d'12' ; Set up to shift out opcode. MOVWF clocks MOVLW EWDS ; temp = erase/write-disable op code. MOVWF temp CALL Shout ; Shift temp out to the EEPROM. BCF 5h,d'2' ; Done. Deselect EEPROM. RETLW 0h ; Write the byte in EEdata to EEaddr. EEwrite MOVLW WROP ; Get the write op code. MOVWF temp MOVLW d'4' ; Prepare to shift out 4 msbs. MOVWF clocks BSF 5h,d'2' ; Select the EEPROM. CALL Shout ; Shift temp out to the EEPROM. MOVLW d'8' ; Now prepare for 8 addr bits. MOVWF clocks MOVF EEaddr,w ; Move address into temp. MOVWF temp CALL Shout ; Shift temp out to the EEPROM. MOVLW d'8' ; Prepare for 8 data bits. MOVWF clocks MOVF EEdata,w ; Move data into temp. MOVWF temp CALL Shout ; Shift temp out to the EEPROM. BCF 5h,d'2' ; Done. Deselect EEPROM. RETLW 0h ; Erase the byte in EEaddr. Erasure leaves 0FFh (all 1s) in the byte. EErase MOVLW ERAS ; Get the erase op code. MOVWF temp MOVLW d'4' ; Prepare to shift out 4 msbs. MOVWF clocks BSF 5h,d'2' ; Select the EEPROM. CALL Shout ; Shift temp out to the EEPROM. MOVLW d'8' ; Prepare for 8 addr bits. MOVWF clocks MOVF EEaddr,w ; Move address into temp. MOVWF temp CALL Shout ; Shift address out to the EEPROM. BCF 5h,d'2' ; Done. Deselect EEPROM. RETLW 0h ; Erase the entire EEPROM--all 256 bytes. Call before using EEwrall below. EEwipe BSF 5h,d'2' ; Select the EEPROM. MOVLW ERAL ; Get the erase-all opcode. MOVWF temp MOVLW d'12' ; Prepare to shift out 12 bits. MOVWF clocks CALL Shout ; Send op code + don't-care bits. BCF 5h,d'2' ; Done. Deselect EEPROM. RETLW 0h ; Write the byte in EEdata to every address. Call EEwipe first. EEwrall BSF 5h,d'2' ; Select the EEPROM. MOVLW WRAL ; Get the write-all opcode. MOVWF temp MOVLW d'12' ; Prepare to shift out 12 bits. MOVWF clocks CALL Shout ; Send op code + don't-care bits. MOVLW d'8' ; Prepare to shift out 8 data bits. MOVWF clocks MOVF EEdata,w ; Move data into temp. MOVWF temp CALL Shout ; Shift temp out to EEPROM. BCF 5h,d'2' ; Done. Deselect EEPROM. RETLW 0h ; Check flag to determine whether the EEPROM has finished its self-timed ; erase/write. Caution: This will lock up your program until D goes high. Busy MOVLW d'1' ; Set D to input. TRIS 5h BSF 5h,d'2' ; Select the EEPROM. Busy_wait BTFSS 5h,d'0' ; Wait until D goes high (end of write). GOTO Busy_wait BCF 5h,d'2' ; Done. Deselect EEPROM. MOVLW d'0' ; Restore D to output. TRIS 5h RETLW 0h ; Delay routine for demo. Delay DECFSZ tick1 GOTO Delay DECFSZ tick2 GOTO Delay RETLW 0h