使用PIC讀寫1-wire EEPROM DS2430的實例
使用PIC讀寫1-wire EEPROM DS2430的實例程序
;--------------------------------------------------------------------
;
; 1-wire device access
;DS2430
;memory function
;write scratchpad
;read scratchpad
;
;read memory :
; resource occupy by ICD2
; PROM 0x1f00 - 0x1fff
; RAM 0x70,0xf0,0x170,0x1e5~0x1f0
;--------------------------------------------------------------------
; master action
; 0xf0 + start addr(8) => scratchpad(8) --> master
; none => scratchpad(9) --> master
; none => scartchpad(a) --> master
;
; none => scratchpad(0x1f)--> master[wrap around]
; reset pulse => stop sending data
;
; 0xf0+reset pulse => EEPROM(0x00-0x1F) --> scratchpad(0x00-0x1F)
; copy scratchpad
; master
; 0x55 + 0xa5 => scratchpad(000-0x1f) --> EEPROM(0x00-0x1F)
; held hi for 10ms
; 0xf0 + reset pulse => copy whole from EEPROM to SCRATCHPAD
; use timer as a delay timer
;
; author : Rex Chen
; date : May,8th
; ver : 1.81
;
list p=16F877A
#i nclude p16f877a.inc
__CONFIG _CPD_OFF & _CP_ALL & _DEBUG_ON & _BODEN_OFF & _LVP_OFF & _PWRTE_OFF & _WDT_OFF & _XT_OSC
#define OneWireDHi bsf PORTC,Bit2
#define OneWireDLo bcf PORTC,Bit2
#define CARRY STATUS,C
#define ZERO STATUS,Z
Bit0 equ H'0000'
Bit1 equ H'0001'
Bit2 equ H'0002'
Bit3 equ H'0003'
Bit4 equ H'0004'
Bit5 equ H'0005'
Bit6 equ H'0006'
Bit7 equ H'0007'
;variable defination
cblock 0x20 ; RAM area 0x20- 0x7f
SYSFLAG
TxB ; Command buffer been send
TxBuffer ; data buffer been send
RxB ; Command buffer been received
TempB ; Temp Byte to roll the data
LoopCounter
Addr ; address to access BQ2430A
PBDir ; port C direction log file
PADir ; port A direction log file
Temp
ErrCode ;
W_SAVE
STATUS_SAVE
TxBuf:8 ; Tx Temp buffer
Offset
endc
;;
cblock 0xa0
SARS1
SARS2
SARS3
endc
cblock 0x100
HateSARS1
HateSARS2
HateSARS3
HateSARS4
endc
cblock 0x190
SARSIsAPig0
SARSIsAPig1
SARSIsAPig2
SARSIsAPig3
SARSIsAPig4
SARSIsAPig5
endc
;---------------- SYSFLAG ----------------------------------
fTxHi equ H'0000'
fTxLo equ H'0001'
fRxMode equ H'0002'
;;
;;
;; there are 4 memory block
;; 1. EEPROM & 2. memory scratchpad
;; 3. application register
;; 4.register scratchpad
;; aliase
;;
;; memory function
;; write memory scratch
;; read memory scratch
;; copy memory scratch to EEPROM
;; read EEPROM to memory scratch
;;
;; application register , application register is OTP, there are 7 bytes RApR equ H'C3' ; 0xc3 + addr + data + .. + reset pulse SkipROM equ H'CC' ;access memory directly movlw H'21' ;------------------------------------------------- WrScratchPAD ;--------- REE2ScratchPAD --- copy whole EE to ScrathPAD ---------------- R2430A ; returns byte in RxB goto gLo bsf PBDir,Bit2 banksel TRISB ;;-------------------------------------------------------- banksel INTCON ;------------------------------------------------ banksel PIE1 ;;--------------------------------------------------------- TxHi: SetL ;--------------------------- banksel PIR1
WScratch equ H'0F' ; 0x0f + Addr + data + data + .+ reset pulse
; // [Master --> ScratchPad ]
RScratch equ H'AA' ; 0xaa + Addr + R + R +.. + reset pulse
; // [ScratchPad --> Master ]
CPScratch equ H'55' ; 0x55 + 0xa5 + hi 10ms // [ScratchPad --> EEPROM ]
REEROM equ H'F0' ; 0xf0 + Addr +R +R + reset pulse
; // [EEPROM(addr) --> ScratchPad]
; 0xf0 + reset pulse // [EEPROM --> ScratchPad]
;; pay attention when you use application register , it's a 64 bit OTP
WApR equ H'99' ; 0x99 + Addr + data + data .. + reset pulse
; [Master --> Application Reg]
RStatus equ H'66' ; 0x66 + 0x00 + status + reset pulse
; application register --> master ( locked)
; register scratchpad --> master ( not lock)
LockAp equ H'5A' ; 0x5A + 0xa5
; [ register scratchpad --> application register]
; 0x5A + reset pulse cancel copy command
; a OTP type do once only
AppLocked equ B'11111100' ; application locked, the value is data in the status
;; ROM function command// implement skip rom only
SerachROM equ H'f0' ;read a bit , read the complement of the bit,write bit
MatchROM equ H'55' ;0x55 + 64 bit rom bit
ReadROM equ H'33' ;[family code & serial number & CRC ==> master ]
org H'00'
nop
goto main
;;ISR **
org H'04'
goto isr
isr
movwf W_SAVE ;; W_SAVE=W
swapf STATUS,W ;;
movwf STATUS_SAVE ;; STATUS_SAVE=STATUS[3:0]& STATUS[7:4]
btfss PIR1,TMR1IF ;; TMR1IF
goto exit_int_source_check
;; timer 1 service
nop
nop
nop
nop
exit_int_source_check ;; restore STATUS & W before exit from
swapf STATUS_SAVE,W ;; W=STATUS_SAVE=STATUS[3:0]& STATUS[7:4]
movwf STATUS
swapf W_SAVE,F ;; restore W
swapf W_SAVE,W
retfie
;; ISR &&&
main
call init
call init_int_en
movwf FSR
movlw H'3c'
movwf INDF ;
;-----------------------------------------------
;--------- read test --------------------------
;-----------------------------------------------
; movlw H'00'
; banksel Addr
; movwf Addr
; call RdDS2430
; movlw H'01'
; banksel Addr
; movwf Addr
; call RdDS2430
;
; movlw H'02'
; banksel Addr
; movwf Addr
; call RdDS2430
;------------------------------------------------
; banksel Offset
; clrf Offset
; pagesel VendorTable
; call VendorTable
; movwf Temp
;
;
movlw H'00'
banksel Addr
movwf Addr
movlw H'34'
banksel TxBuffer
movwf TxBuffer
call WrDS2430
movlw H'01'
banksel Addr
movwf Addr
movlw H'35'
banksel TxBuffer
movwf TxBuffer
call WrDS2430
movlw H'02'
banksel Addr
movwf Addr
movlw H'36'
banksel TxBuffer
movwf TxBuffer
call WrDS2430
[!--empirenews.page--]
;-------- read address 0 --------------------------
movlw H'00'
movwf Addr
call RdDS2430
goto $
;----------------------------------------------
; template to init before write
; to DS2430
;-----------------------------------------------
; movlw H'00'
; movwf Addr
; movlw H'3C'
; movwf TxBuffer
;---------------------------------------------
; write DS2430 one byte
; input
; Addr = starting address to write
; TxB = data to save
; output =
; ErrCode = 0 -> write ok
; = 1 -> write fail
;-----------------------------------------------
WrDS2430
call WrScratchPAD
call CP2EE
return
;------------------------------------------------
; template to init before read
; to DS2430
;-------------------------------------------------
; movlw H'00'
; movwf Addr
; read DS2430 one byte
; input
; Addr = starting address to read
; output
; RxB = data to read
;--------------------------------------------------
RdDS2430
call REE2ScratchPAD
call HostRdScratchPAD
return
;;--------- host read scratch pad ----------------------------
;; save desired data into RxB
;;
;;--------------------------------------------------------------
HostRdScratchPAD
call DS2430AInitState
banksel TxB
movlw SkipROM
movwf TxB
call TxBYTE ; SkipROM
movlw RScratch ; read scratch PAD Command
movwf TxB
call TxBYTE
movf Addr,W ; starting address to read
movwf TxB
call TxBYTE
call R2430A ; read desired scratch pad into RxB
call RstPulse
return
;-------------- write memory scratch scratch pad ------------------------
; write one byte into scratch PAD
; input
; Addr = starting address to write
; TxBuffer = data to save
; output
; ErrCode = 0 -> write ok
; = 1 -> write fail
;---------------------------------------------------------------------------
call DS2430AInitState
movlw SkipROM ; 0xCC
movwf TxB
call TxBYTE ; SkipROM
movlw WScratch ; write memory scratch pad, 0x0f
movwf TxB
call TxBYTE
movf Addr,W ; starting address of memory scratch pad
movwf TxB ; TxBYTE use TxB
call TxBYTE
movf TxBuffer,W ;
movwf TxB
call TxBYTE
call RstPulse ; reset pulse
call delay500us ; wait presence pulse
return
;---------- CP2EE ---copy whole scratch pad to EE ----------------------
; write memory scratch
; verify memory scratch
; copy memory scratch to EE
;----------------------------------------------------------------------
CP2EE
call DS2430AInitState ; 0x55 + 0xa5 + hi 10ms // [ScratchPad -> EEPROM ]
banksel TxB
movlw SkipROM
movwf TxB
call TxBYTE ; SkipROM
movlw CPScratch ; 0x55
movwf TxB
call TxBYTE
movlw H'a5'
movwf TxB
call TxBYTE
call ForceHi ; min 10ms refter to datasheet
return
; copy EE to whole memory scatch
; read memory scratch
;format I: 0xf0 + Addr +R +R + reset pulse, copy byte by byte
;format II: 0xf0 + Addr + reset pulse, copy whole
;------------------------------------------------------------------------
REE2ScratchPAD
call DS2430AInitState
banksel TxB
movlw SkipROM
movwf TxB
call TxBYTE ; SkipROM
movlw REEROM ;; Read from EE into ScratchPAD
movwf TxB
call TxBYTE ;;
call RstPulse ;; copy all
return
;----------R2430A ---- Host read the scratch PAD ------------------------
; Read 2430A Scratch PAD
; LSB first
; save the result in RxB
;------------------------------------------------------------------------
movlw .8
movwf LoopCounter
clrf RxB
RLoop
call SetLo ;
nop
call SetHi ; it will pull up by resistor
nop ; delay to sample reliable bit
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
banksel PORTB
movf PORTB,W
movwf Temp
btfss Temp,Bit2
bsf CARRY
goto rol
gLo
bcf CARRY
rol
banksel RxB
rrf RxB,F
call delay60us ; tdrv + trelease
banksel LoopCounter
decfsz LoopCounter,F
goto RLoop
movf RxB,W ; save the result in W
return
;----------------------------------------------------------
; strong pull up
;
;----------------------------------------------------------
ForceHi
movf PBDir,W ;; input
movwf TRISB ;; set input, pull by external resistor
call delay100ms
bcf PBDir,Bit2 ;; output
movf PBDir,W
movwf TRISB
return
;-------------------------------------------------------------
; reset pulse
;
;--------------------------------------------------------------
RstPulse
call SetHi
call SetLo
call delay500us
call SetHi ;Pull up by resistor
return
;---------------------------------------------------------------
; reset pulse followed presence pulse
;
;---------------------------------------------------------------
DS2430AInitState
call SetHi
call SetLo
call delay500us ; reset pulse
call SetHi
call delay500us ; presence pulse, pull up by resistor
return
;-----------------------------------------------------------------------
init
movlw H'3f'
movwf PBDir ; 0x00111111
banksel TRISB
movwf TRISB ; force all portC as input
; movlw b'00000000' ; GP2 pull-up,GP4 output
; movwf WPU ; connect the D of DS2430A to Port A
;--------------------------------------------------------------------
; toggle from bank0 to bank1
; option register
; 7: 1: port A pull-up OFF, 0:port A pull-up ON
; 6: 1: rising INT , 0:fall INT
; 5: 1: T0CKI to TMR0, 0: internal cycle to TMR0
; 4: 1: Hi to Lo count 0: Lo to Hi count
; 3: 1: Precale to WDT 0: Prescale to TMR0
; 2:0 prescale value
;---------------------------------------------------------------------
movlw b'11000010' ;; pull-up ON,rising INT, internal cycle to TMR0,Lo to Hi count,Pre to TMR0,1:8
movwf OPTION_REG ;; ,prescal over 8
banksel INTCON
clrf INTCON
clrf PORTB
movlw 0x07 ;; comparator off
movwf CMCON ;; comparator off
clrf TMR0
;; 7: X
;; 6: 1: Timer1 on if T1G
;; 5:4 : 11:/8,10:/4,01:/2,00:/1
;; 3 : 1 LP for timer 1 on, 0: LP for timer1 of
;; 2 : 1 do not sync external , 0 sync external clock
;; 1 : 1: clock source external , 0: clock source internal
;; 0 : 1: enable timer 1 ,0: disable timer 1
;;---------------------------------------------------------
; movlw b'00000000' ;x,no gate control,over 8,LP osc to timer1 off,x,internal clock,stop timer
; movwf T1CON
movlw b'00111000'
movwf T1CON
clrf PIR1
return
;;-------------------------
;; init interrup enable,
;;-------------------------
init_int_en [!--empirenews.page--]
bsf INTCON,GIE ;; GIE=1
bcf INTCON,PEIE ;;
bcf INTCON,T0IE ;; T0IE=1
bcf INTCON,INTE ;; GP2 interrupt enable
; bcf INTCON,RAIE ;; disable GPIO port change interrupt
; clear int flag
;------------------------------------------------
bcf INTCON,T0IF
bcf INTCON,INTF
; bcf INTCON,RAIF
bcf PIR1,TMR1IF
; movlw H'00'
; movwf INTCON
bcf PIE1,EEIE
bcf PIE1,ADIE
bcf PIE1,CMIE
bsf PIE1,TMR1IE ; enable Timer 1, timer 1 use as delay
return
;--------------------------------------------
; Tx BYTE to 2430A
; LSB first, MSB last
;--------------------------------------------
TxBYTE
movlw .8
movwf LoopCounter
bcf CARRY
RollTxB
banksel TxB
rrf TxB,F
btfss CARRY
goto LoBit
call TxHi
goto bloop
LoBit
call TxLo
bloop
banksel LoopCounter
decfsz LoopCounter,F
goto RollTxB
return
TxL
call SetLo
call delay60us ; min 60 us
call SetHi
nop ; recovery time min 1us
nop
return
;-----------------------------------------------------------
; tx hi
;-----------------------------------------------------------
call SetLo ;1us<tlow1<15us
nop
call SetHi
call delay60us
nop
nop ;recovery time min 1us
return
;;---------------------------------------------------------------------------
;; toggle the RC0 as input and the bus was pulled up by externl resistor
;; application default PCDir.Bit0 to output
;;---------------------------------------------------------------------------
SetHi:
bsf PBDir,Bit2
movf PBDir,w
; bsf bank1
banksel TRISB
movwf TRISB
return
;;----------------------------------------------------------------------------
;; clear register file RC0
;;----------------------------------------------------------------------------
banksel PORTB
bcf PORTB,Bit2 ; data lo
bcf PBDir,Bit2 ; direction out
movf PBDir,W
banksel TRISB
movwf TRISB
return
;---------------------------
; fix delay 60 us
; 0xffff - 8 = 0xfff7
;---------------------------
delay60us
banksel PIR1
bcf PIR1,TMR1IF
movlw H'EE'
movwf TMR1L
movlw H'FF'
movwf TMR1H
bsf T1CON,TMR1ON
btfss PIR1,TMR1IF
goto $-1
bcf T1CON,TMR1ON
bcf PIR1,TMR1IF
return
; fix delay 500 us
; 0xffff - 0x3e = 0xffc1
;---------------------------
delay500us
bcf PIR1,TMR1IF
movlw H'C0'
movwf TMR1L
movlw H'FF'
movwf TMR1H
bsf T1CON,TMR1ON
btfss PIR1,TMR1IF
goto $-1
bcf T1CON,TMR1ON
bcf PIR1,TMR1IF
return
;---------------------------
; fix delay 100 ms
; 0xffff - 30d4 = 0xcf26
;---------------------------
delay100ms
banksel PIR1
bcf PIR1,TMR1IF
movlw H'26'
movwf TMR1L
movlw H'CF'
movwf TMR1H
bsf T1CON,TMR1ON
btfss PIR1,TMR1IF
goto $-1
bcf T1CON,TMR1ON
bcf PIR1,TMR1IF
return
org H'800'
VendorTable
movf Offset,W ; Save offset in Temp
andlw H'ff'
addwf PCL,f ; PCL = PCL+Offset
dt "MiCallChip",0
end