Microchip Virgilstamps Ee.asm
; ee.asm
LIST P=16C74A, F=INHX8M
__CONFIG _BODEN_OFF & _CP_OFF & _WDT_OFF & _XT_OSC
include <p16c74a.inc>
;*****************************************************************************
; This application written by Virgil Stamps, 6-12-99
; I had an application that needed configuration files for various modes of operation.
; A 24C32 I2C EEPROM provides 4Kx8 non-volatile storage. A PIC 16C74 is the processor.
; "Creating electronic products for fun and profit." This code is given
; to the public domain. If you need help, email author at stamps@brokersys.com
;*****************************************************************************
RESET_V EQU 0x0000 ; Address of RESET Vector
ISR_V EQU 0x0004 ; Address of Interrupt Vector
ORG RESET_V ; RESET vector location
RESET GOTO START
ORG ISR_V ; Interrupt vector location
nop ; interrupt service would be here
retfie
INIT bsf STATUS,RP0 ; bank 1
movlw b'10010110'
movwf TRISC ; rc7= RX rc6= TX rc5=SDO rc4=SDI rc3=SCLK rc1=na rc0=na
BCF STATUS, RP0 ; bank 0
clrf event
return
;*****************************************************************************
; Program start. Simple poll loop. A good place for breakpoint and testing.
;*****************************************************************************
START CALL INIT ; Initialize Processor Registers
bsf event,ee_busy ; read block
movlw .0 ; which block
movwf BLK
POLL nop
btfsc event,ee_busy ; ee busy?
call EE_SERVICE ; service eeprom if needed
GOTO POLL
; Driver for Microchip 24C32A Serial EEPROM (32K-bit).
; Generic program listing for those seeking information on programming this type EEPROM.
; Approximately 30 ms to read and 80 ms to write a block of 80 bytes.
; The EEPROM is organized as virtual memory accessed by a block number
; and temporarily stored in RAM at BLOCK (0x0A0 - 0x0EF)
; A 32K-bit device has a maximum of 51 blocks. 4,096 bytes / 80 = 51.2 blocks
; A virtual memory location in your application could be defined as BLK (0-50)
; and a offset (0-79).
EE equ PORTC ; EEPROM port
SDA equ 1 ; EE data
SCL equ 0 ; EE clk
block equ 0x0A0
blk_size equ 0x050 ; 80 decimal
; VARIABLES defined in low RAM Arbitrary as to where you want to put them
event equ 0x03D ; event register where:
ee_busy EQU 2 ; service requested 1=busy, 0=idle
ee_write EQU 1 ; 1=write, 0=read
ee_blk_op EQU 0 ; 1=read or write block operation, 0=idle
ADDR0 equ 0x03E ; address high byte
ADDR1 equ 0x03F ; address low byte
BLK equ 0x040 ; block number (0-50)
BLKC equ 0x041 ; block counter
blkptr equ 0x042 ; block pointer
o_data equ 0x043 ; output data
i_data equ 0x044 ; input data
ee_cntr4 equ 0x045 ; temp counter
ee_cntr3 equ 0x046 ; temp counter
ee_cntr2 equ 0x047 ; temp counter
ee_cntr1 equ 0x048 ; temp counter
X_DELAY equ 0x04B ; delay counter MS
DELAY equ 0x04C ; delay counter LS
;*****************************************************************************
; This application burst mode writes 10 groups of 8-bytes each.
; The read function block reads 80-bytes in a loop.
; To write the 80 bytes at block, set BLK= block number in EEPROM, set event,ee_busy,
; set event,ee_write, call EE_SERVICE.
; To read 80 bytes to block from EEPROM, set BLK= block number in EEPROM,
; set event,ee_busy, clear event,ee_write, call EE_SERVICE.
; on return: event,ee_busy is zero, event,ee_block is zero.
;*****************************************************************************
EE_SERVICE btfss event,ee_busy ; busy?
return ; no
call EEPRMSVC ; service eeprom
btfss event,ee_busy
goto EE_SERVICE
movlw .10
call X_DELAY500
goto EE_SERVICE ; if yes
EEPRMSVC btfsc event,ee_write ; write to ee?
goto write_block ; if yes
goto read_block ; no, read a block
write_block btfsc event,ee_blk_op ; writing a block now?
goto write_busy ; if yes
bsf event,ee_blk_op ; no, signal writing a block
call set_addr
movlw block
movwf blkptr ; addr of block buffer
movlw .10
movwf ee_cntr4 ; write 10 groups of 8 bytes each
write_busy call low_scl
call low_sda
movlw blk_size/.10
movwf ee_cntr2
movf blkptr,w
movwf FSR
call w_block
decfsz ee_cntr4 ; done all groups of 8?
goto poll_ack ; if no
bcf event,ee_blk_op ; eeprom block operation done
bcf event,ee_write ; eeprom not writing
bcf event,ee_busy ; eeprom not busy
goto delay50ms ; return after delay
poll_ack movlw .100
movwf ee_cntr3
ack_loop decfsz ee_cntr3
goto ack_tst
goto err
ack_tst call strt
movlw 0x0a0
call out_byte
call wait
btfsc PORTC,SDA ; did chip acknowledge?
goto clkit ; if no
goto pulse ; yes, so exit
clkit call pulse
goto ack_loop ; poll again
err nop ; EEPROM is bad (add your own error recovery)
goto err ; eeprom did not respond in 100 tries
w_block call strt ; burst write 8 bytes
movlw 0x0a0
call out_byte
call ack
movf ADDR0,w ; ms addr
call out_byte
call ack
movf ADDR1,w ; ls addr
call out_byte
call ack
wrtblk movf INDF,w ; byte to write
call out_byte
call ack
incf FSR
incf blkptr
movlw .1
addwf ADDR1 ; EEPROM addr low
btfsc STATUS,C
incf ADDR0 ; EEPROM addr high
decfsz ee_cntr2
goto wrtblk
call stop
return
read_block bsf event,ee_blk_op ; signal reading a block
call set_addr
call low_scl
call high_sda
call high_scl ; idle bus
movlw block
movwf FSR ; addr of block buffer
movlw blk_size
movwf ee_cntr2 ; bytes to copy
call strt
movlw 0x0a0 ; write preface
call out_byte
call ack
movf ADDR0,w ; ms address
call out_byte
call ack
movf ADDR1,w ; ls address
call out_byte
call ack
call strt
movlw 0x0a1
call out_byte ; read preface
more_seq call ack
call in_byte ; fetch the byte
movf i_data,w
movwf INDF ; copied to current block
incf FSR ; point to next address in block
movlw .1
addwf ADDR1
btfsc STATUS,C
incf ADDR0
decfsz ee_cntr2 ; read all bytes?
goto more_seq
call stop
bcf event,ee_blk_op ; block read is done
bcf event,ee_busy ; ee not busy
return
out_byte movwf o_data ; output 8 bits to eeprom
movlw .8
movwf ee_cntr1
o_loop rlf o_data ; msb to carry
call low_sda
btfsc STATUS,C ; is it a 1?
call high_sda
call pulse
decfsz ee_cntr1 ; done?
goto o_loop ; no
call high_sda
return
in_byte movlw .8 ; input 8 bits from eeprom
movwf ee_cntr1
call high_sda
i_loop call high_scl ; data valid
bcf STATUS,C
btfsc PORTC,SDA
bsf STATUS,C
rlf i_data
call low_scl
call wait
decfsz ee_cntr1
goto i_loop
return
ack call high_sda ; acknowledge operation
btfsc PORTC,SDA ; bit low?
goto force0 ; if no
goto pulse ; slave acknowledges
force0 call low_sda ; master acknowledges
call pulse
goto high_sda ; return as input
strt call high_sda
call high_scl
call low_sda ; strt condition
goto low_scl
stop call low_sda
call high_scl
call high_sda ; stop condition
goto low_scl
low_sda call wait
BSF STATUS, RP0 ; bank 1
bcf TRISC,SDA ; output
bcf STATUS, RP0 ; bank 0
bcf PORTC,SDA
goto wait
high_sda call wait
BSF STATUS, RP0 ; bank 1
bsf TRISC,SDA ; input
bcf STATUS, RP0 ; bank 0
bsf PORTC,SDA
goto wait
low_scl bcf EE,SCL ; clock line goes low
return
high_scl bsf EE,SCL ; clock line goes high
return
wait nop ; delay for the chip
nop
nop
nop
return
pulse call high_scl ; one clock pulse
call wait
goto low_scl
; subroutine to compute block address: addr = n * 80
set_addr clrf ADDR0 ; assume 1st block
clrf ADDR1
movf BLK,w
movwf BLKC
movf BLK,w
btfss STATUS,Z ; zero?
goto next_addr2 ; if n
goto set_done ; if yes
next_addr2 bcf STATUS,C ; set ADDR0 and ADDR1 modulo 80
movlw blk_size ; sizeof block
addwf ADDR1,f
btfsc STATUS,C ; overflow?
incf ADDR0 ; if yes
decfsz BLKC
goto next_addr2 ; if no
set_done return
; a delay routine
delay50ms movlw .100
X_DELAY500 MOVWF X_DELAY ; +1 1 cycle
X_DELAY500_LOOP CALL DELAY500 ; step1 wait 500uSec
DECFSZ X_DELAY, F ; step2 1 cycle
GOTO X_DELAY500_LOOP ; step3 2 cycles
RETURN ; +2 2 cycles
DELAY500 MOVLW D'165' ; +1 1 cycle
MOVWF DELAY ; +2 1 cycle
DELAY500_LOOP DECFSZ DELAY, F ; step 1 1 cycle
GOTO DELAY500_LOOP ; step 2 2 cycles
RETURN ; +3 2 cycles
END ; End of program
file: /Techref/microchip/virgilstamps/ee.asm, 10KB, , updated: 1999/6/12 12:51, local time: 2025/5/3 19:18,
|
| ©2025 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://www.linistepper.com/Techref/microchip/virgilstamps/ee.asm"> microchip virgilstamps ee</A> |
Did you find what you needed?
|