by Virgil Stamps converted and optimized for the SX by James Newton
; 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 ;***************************************************************************** PortCTris equ %10010110 SDAOnMask equ %11111101 SDAOffMask equ %00000010 RESET START INIT setb STATUS.RP0 ; bank 1 mov M, #$0F mov !RC, #PortCTris ; rc7= RX rc6= TX rc5=SDO rc4=SDI rc3=SCLK rc1=na rc0=na clrb STATUS.RP0 ; bank 0 clr event ret ;***************************************************************************** ; Program start. Simple poll loop. A good place for breakpoint and testing. ;***************************************************************************** START call INIT ; Initialize Processor Registers setb event.ee_busy ; read block mov W, #0 ; which block mov BLK, W POLL nop snb event.ee_busy ; ee busy? call EE_SERVICE ; service eeprom if needed jmp 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 RC ; EEPROM port SDA equ 1 ; EE data SCL equ 0 ; EE clk block equ $0A0 blk_size equ $050 ; 80 decimal ; VARIABLES defined in low RAM Arbitrary as to where you want to put them event equ $03D ; 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 $03E ; address high byte ADDR1 equ $03F ; address low byte BLK equ $040 ; block number (0-50) BLKC equ $041 ; block counter blkptr equ $042 ; block pointer o_data equ $043 ; output data i_data equ $044 ; input data ee_cntr4 equ $045 ; temp counter ee_cntr3 equ $046 ; temp counter ee_cntr2 equ $047 ; temp counter ee_cntr1 equ $048 ; temp counter X_DELAY equ $04B ; delay counter MS DELAY equ $04C ; 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 sb event.ee_busy ; busy? ret ; no call EEPRMSVC ; service eeprom sb event.ee_busy jmp EE_SERVICE mov W, #10 call X_DELAY500 jmp EE_SERVICE ; if yes EEPRMSVC snb event.ee_write ; write to ee? jmp write_block ; if yes jmp read_block ; no, read a block write_block snb event.ee_blk_op ; writing a block now? jmp write_busy ; if yes setb event.ee_blk_op ; no, signal writing a block call set_addr mov W, #block mov blkptr, W ; addr of block buffer mov W, #10 mov ee_cntr4, W ; write 10 groups of 8 bytes each write_busy call low_scl call low_sda mov W, #blk_size/10 mov ee_cntr2, W mov W, blkptr mov FSR, W call w_block decsz ee_cntr4 ; done all groups of 8? jmp poll_ack ; if no clrb event.ee_blk_op ; eeprom block operation done clrb event.ee_write ; eeprom not writing clrb event.ee_busy ; eeprom not busy jmp delay50ms ; return after delay poll_ack mov W, #100 mov ee_cntr3, W ack_loop decsz ee_cntr3 jmp ack_tst jmp err ack_tst call strt mov W, #$0a0 call out_byte call wait snb RC.SDA ; did chip acknowledge? jmp clkit ; if no jmp pulse ; yes, so exit clkit call pulse jmp ack_loop ; poll again err nop ; EEPROM is bad (add your own error recovery) jmp err ; eeprom did not respond in 100 tries w_block call strt ; burst write 8 bytes mov W, #$0a0 call out_byte call ack mov W, ADDR0 ; ms addr call out_byte call ack mov W, ADDR1 ; ls addr call out_byte call ack wrtblk mov W, INDF ; byte to write call out_byte call ack inc FSR inc blkptr mov W, #1 add ADDR1, W ; EEPROM addr low snb C inc ADDR0 ; EEPROM addr high decsz ee_cntr2 jmp wrtblk call stop ret read_block setb event.ee_blk_op ; signal reading a block call set_addr call low_scl call high_sda call high_scl ; idle bus mov W, #block mov FSR, W ; addr of block buffer mov W, #blk_size mov ee_cntr2, W ; bytes to copy call strt mov W, #$0a0 ; write preface call out_byte call ack mov W, ADDR0 ; ms address call out_byte call ack mov W, ADDR1 ; ls address call out_byte call ack call strt mov W, #$0a1 call out_byte ; read preface more_seq call ack call in_byte ; fetch the byte mov W, i_data mov INDF, W ; copied to current block inc FSR ; point to next address in block mov W, #1 add ADDR1, W snb C inc ADDR0 decsz ee_cntr2 ; read all bytes? jmp more_seq call stop clrb event.ee_blk_op ; block read is done clrb event.ee_busy ; ee not busy ret out_byte mov o_data, W ; output 8 bits to eeprom mov W, #8 mov ee_cntr1, W o_loop rl o_data ; msb to carry call low_sda snb C ; is it a 1? call high_sda call pulse decsz ee_cntr1 ; done? jmp o_loop ; no call high_sda ret in_byte mov W, #8 ; input 8 bits from eeprom mov ee_cntr1, W call high_sda i_loop call high_scl ; data valid clrb C snb RC.SDA setb C rl i_data call low_scl call wait decsz ee_cntr1 jmp i_loop ret ack call high_sda ; acknowledge operation snb RC.SDA ; bit low? jmp force0 ; if no jmp pulse ; slave acknowledges force0 call low_sda ; master acknowledges call pulse jmp high_sda ; return as input strt call high_sda call high_scl call low_sda ; strt condition jmp low_scl stop call low_sda call high_scl call high_sda ; stop condition jmp low_scl low_sda call wait setb STATUS.RP0 ; bank 1 mov M, #$0F mov !RC, #PortCTris | SDAOnMask ; rc1=SDA rc0=SCL clrb STATUS.RP0 ; bank 0 clrb RC.SDA jmp wait high_sda call wait setb STATUS.RP0 ; bank 1 mov M, #$0F mov !RC, #PortCTris & SDAOffMask ; rc1=SDA rc0=SCL clrb STATUS.RP0 ; bank 0 setb RC.SDA jmp wait low_scl clrb EE.SCL ; clock line goes low ret high_scl setb EE.SCL ; clock line goes high ret wait nop ; delay for the chip nop nop nop ret pulse call high_scl ; one clock pulse call wait jmp low_scl ; subroutine to compute block address: addr = n * 80 set_addr clr ADDR0 ; assume 1st block clr ADDR1 mov W, BLK mov BLKC, W mov W, BLK sb Z ; zero? jmp next_addr2 ; if n jmp set_done ; if yes next_addr2 clrb C ; set ADDR0 and ADDR1 modulo 80 mov W, #blk_size ; sizeof block add ADDR1, W snb C ; overflow? inc ADDR0 ; if yes decsz BLKC jmp next_addr2 ; if no set_done ret ; a delay routine delay50ms mov W, #100 X_DELAY500 mov X_DELAY, W ; +1 1 cycle X_DELAY500_LOOP call DELAY500 ; step1 wait 500uSec decsz X_DELAY ; step2 1 cycle jmp X_DELAY500_LOOP ; step3 2 cycles ret ; +2 2 cycles DELAY500 mov W, #165 ; +1 1 cycle mov DELAY, W ; +2 1 cycle DELAY500_LOOP decsz DELAY ; step 1 1 cycle jmp DELAY500_LOOP ; step 2 2 cycles ret ; +3 2 cycles END ; End of program
file: /Techref/scenix/lib/mem/24c32.htm, 8KB, , updated: 2004/6/10 13:40, local time: 2024/11/17 10:24,
18.119.124.202:LOG IN
|
©2024 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://linistepper.com/techref/scenix/lib/mem/24c32.htm"> SX Microcontroller 24C32 EEPROM Memory Method</A> |
Did you find what you needed? |