winnie 发表于 2009-5-5 17:28:25

PIC16C74单片机SPI方式读写串行EEPROM程序

; PORTC PIN DESCRIPTION
; SCK bit 3, SDI bit 4, SDO bit 5, CS bit 7
; Fosc = 10.0 MHz, thus each instr. cycle = 400ns

;***************Ram Register Definitions*******************************


   rxdata equ 25h
   addr   equ 26h
   loopsequ 27h

;***************Bit Definitions****************************************
;#define   CS    PORTC,7         ; SPI chip select bit definition

;**********************************************************************


;***************25Cxxx command definitions
;#define      WREN6               ;write enable latch
;#define      WRDI4               ;reset the write enable latch
;#define      RDSR5               ;read status register
;#define      WRSR1               ;write status register
;#define      READ3               ;read data from memory
;#define      WRITE 2               ;write data to memory

; Bit defines within status register
;#define      WIP   0               ;write in progress
;#define      WEL   1               ;write enable latch
;#define      BP0   2               ;block protection bit
;#define      BP1   3               ;block protection bit
;**********************************************************************

;      include "p16c74.inc"   ; 16C74 include file
;      __CONFIG   _WDT_OFF & _CP_OFF & _HS_OSC & _PWRTE_ON

;**********************************************************************
    page

         org   0000            ; Reset Vector
         clrfPCLATH             ; ensure PCLATH bit 3 is cleared
         clrfINTCON             ; ensure all interrupts are disabled
         gotostart            ; jump to the beginning of the program

         org   004            ; interrupt vector, do nothing
isr:      gotoisr                ; do nothing, location just
                                  ; identified in code


;***************BEGIN MAIN PROGRAM*************************************
;
start:    bcf   STATUS,5         ; need to set bank 0
         clrfPORTC            ; initialize port c
         bsf   CS               ; make sure cs is set
         bsf   STATUS,5         ; need to set bank 1
         movlw 0x10               ; all bits are outputs except SDI
         movwf TRISC            ; for SPI setup
         bcf   STATUS,RP0         ; need to set bank 0
         movlw 0x31               ; SPI master, clk/16, ckp=1
         movwf SSPCON             ; SSPEN enabled
         movlw 0x10               ; *** put beginning address in addr**
         movwf addr               ; for later use

loop
;The first thing we will do is the WREN
         callwren               ; call the write enable routine
;Next write status reg. to clear the block protect bits
         callwrsr               ; call the write status routine
;Next do a busy test
         callbusy_test          ; test WIP bit in status register
;Then do the WREN before writing to the array
         callwren               ; call the write enable command

;Next write 0xA5 (or any other value) to 0x10
         bcf   CS               ; set chip select line low
         movlw WRITE            ; WRITE control byte
         calloutput             ; call the output subroutine
         movlw b'00000000'      ; high addr byte is all 0's
         calloutput             ; call the output subroutine
         movfaddr,w             ; low addr byte
         calloutput             ; call the output subroutine
         movlw b'10100101'      ; load 0xA5 as data to be sent out
         calloutput             ; call the output subroutine
         bcf   SSPCON,CKP         ; set clock idle low, mode 0,1
         bsf   CS               ; set chip select, begin write cycle
         bsf   SSPCON,CKP         ; set clock idle high, mode 1,1

         callbusy_test
         callrdsr               ; call the read status subroutine

;Now, read location 0x10h and store in rxdata. With Picmaster a
;user can break, read that memory location to see if the read worked
         bcf   CS               ; set chip select line low
         movlw READ               ; READ control byte
         calloutput             ; call the output subroutine
         movlw b'00000000'      ; high addr byte is all 0's
         calloutput             ; call the output subroutine
         movfaddr,w             ; get ready to send next byte
         calloutput             ; call the output subroutine
         movlw b'01011010'      ; move don't care byte of 0x5A into
         calloutput             ; call the output subroutine
         bsf   CS               ; bring chip select high end
                                  ; terminate read command

;While program is continuously looping, the user may halt (if using an
;emulator), and look at the data in rxdata. If it is 0xA5, the
;read/write worked.
         callwait               ; little delay between SPI sequence
         gotoloop               ; do it all over again
                                  ; loop can be used to evaluate SPI
                                  ; signals on oscilloscope


;********************* BEGIN SUBROUTINES*******************************
;*** DELAY ROUTINE - 400uS ***
;
wait   movlw .200               ; timing adjustment variable
         movwf loops            ; move variable into loops
top      nop                      ; sit and wait
         nop                      ; no operation
         decfsz loops,f         ; loop complete?
         goto   top               ; no, go again
         return                   ; yes, return from sub


;****** This is the OUTPUT transmit/receive subroutine. ***************
output   movwf SSPBUF             ; place data in buffer to send
loop1    bsf   STATUS,RP0         ; specify bank 1
         btfss SSPSTAT,BF         ; has data been received (xmit done)?
         gotoloop1            ; not done yet, keep trying
         bcf   STATUS,RP0         ; specify bank 0
         movfSSPBUF,W         ; empty receive buffer
         movwf rxdata             ; put received byte into rxdata
         return                   ; return from subroutine

;*******Write Enable Subroutine****************************************
wren   bcf   CS               ; set chip select line low
         movlw WREN               ; WREN control byte
         calloutput             ; Call the output subroutine
         bcf   SSPCON,CKP         ; set clock idle low, mode 0,1
         bsf   CS               ; set chip select, begin write
         bsf   SSPCON,CKP         ; set clock idle high, mode 1,1
         return                   ; return from subroutine

;*******Read Status Register Subroutine********************************
rdsr   movlw RDSR               ; RDSR control byte
         calloutput             ; Call the output subroutine
         movlw b'00000101'      ; this byte is a don't care byte
         calloutput             ; status reg data will be in rxdata
         bsf   CS               ; set chip select
         return                   ; return from subroutine

;*******Write Status Register Subroutine*******************************
wrsr   bcf    CS                ; set chip select line low
         movlwWRSR            ; WRSR control byte
         call   output            ; Call the output subroutine
         movlwb'00001000'       ; set BP1 bit in status register
         call   output            ; this will clear block protect bits
         bcf    SSPCON,CKP      ; set clock idle low, mode 0,1
         bsf    CS                ; set chip select
         bsf    SSPCON,CKP      ; set clock idle high, mode 1,1
         return                   ; return from subroutine

;*******Busy Test - WIP bit in Status Register*************************
busy_test
         bcf    CS                ; set chip select line low
         movlwRDSR            ; RDSR control byte
         call   output            ; Call the output subroutine
         movlwb'00000000'       ; send dummy byte
         call   output            ; to initiate clock sequence for read
         bsf    CS                ; else, set chip select high
         btfscrxdata,WIP      ; test WIP bit read from status register
         goto   busy_test         ; repeat busy test
         return                   ; return from subroutine

         end
页: [1]
查看完整版本: PIC16C74单片机SPI方式读写串行EEPROM程序