t2imoor
Newbie level 4
Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;; OVERVIEW ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; FINAL CHANGES REQUIRED: UNCOMMENT LVDEN
; REVIEW COMMENTED PARTS
; RB0: GENERATES INTERRUPT ON ANOTHER MCU
; PROGRAM COMMUNICATES WITH EEPROM VIA I2C
;;;;;;; ASSEMBLER DIRECTIVES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LIST P=PIC18F452, F=INHX32, C=160, N=0, ST=OFF, MM=OFF, R=DEC, X=ON
#INCLUDE P18F452.INC
; __CONFIG _CONFIG1H, _HS_OSC_1H ;HS OSCILLATOR
__CONFIG _CONFIG1H, _XT_OSC_1H
__CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_ON_2L & _BORV_42_2L ;RESET
__CONFIG _CONFIG2H, _WDT_OFF_2H ;WATCHDOG TIMER DISABLED
__CONFIG _CONFIG3H, _CCP2MX_ON_3H ;CCP2 TO RC1 (RATHER THAN TO RB3)
__CONFIG _CONFIG4L, _LVP_OFF_4L ;RB5 ENABLED FOR I/O
;;;;;;; VARIABLES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CBLOCK 0X000 ;BEGINNING OF ACCESS RAM
TEMP
SENREG
HIREG
LOREG
RECREG
CONREG
ENDC
;;;;;;; MACRO DEFINITIONS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOVLF MACRO DEST, LITERAL
MOVLW LITERAL
MOVWF DEST
ENDM
SETWATCH MACRO
; WATCHDOG TIMER ENABLE
BSF WDTCON, SWDTEN
ENDM
CLRWATCH MACRO
BCF WDTCON, SWDTEN
ENDM
; SEND VIA I2C
I2CSEND MACRO DATA1, ADDRESSH, ADDRESSL
CALL GENSTART ; GENERATE START CONDITION
MOVLF CONREG, H'A0'
CALL CALLEEPROM ; ADDRESS THE EEPROM
MOVLF HIREG, ADDRESSH ; HIGH BYTE OF ADDRESS
MOVLF LOREG, ADDRESSL ; ADD LOW
CALL SENDADDR
MOVLF TEMP, DATA1 ; DATA
CALL SENDDATA
CALL GENSTOP
ENDM
;;;;;;; VECTORS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ORG 0X0000 ;RESET VECTOR
NOP
GOTO START
ORG 0X0008 ;HIGH PRIORITY INTERRUPT VECTOR
CLRWDT
CLRWATCH
GOTO HPINT
ORG 0X0018 ;LOW PRIORITY INTERRUPT VECTOR
GOTO $ ;TRAP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;; MAIN CODE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; INITIALIZATION
ORG H'30'
START CLRF TRISB
CLRF PORTB
CLRF TRISD
CLRF TMR1L
CLRF TMR1H
BSF TRISA, 0 ; ANALOG INPUT CHANNEL
; INTERRUPTS
MOVLF INTCON, B'11000000'
; TIMER1 SETTINGS - TIMER1 CAUSES A/D UPDATE
BSF PIE1, TMR1IE ; ENABLE TIMER1 INTERRUPT
BSF IPR1, TMR1IP
; BSF T1CON, TMR1ON
; ADC SETTINGS
MOVLF ADCON0, B'00000000'
MOVLF ADCON1, B'01000001'
CLRF ADRESH
CLRF ADRESL
BSF ADCON0, ADON
; I2C SETTINGS - IN I2C MODE, SCL AND SDA LINES ARE
; MANIPULATED BY MSSP HARDWARE BUT STILL... :(
MOVLF SSPSTAT, B'10000000' ; SLEW RATE CONTROL DISABLED
MOVLF SSPCON1, B'00101000' ; MASTER MODE, SSP ENABLED
MOVLF SSPCON2, B'01100000' ; ACKSTAT, ACKDT SET
MOVLF SSPADD, H'13' ; 50KHZ BAUD RATE
; TIMER0 INITIALIZATION
MOVLF T0CON, B'11000101'
; LOW VOLTAGE DETECT MODULE (LVD) CONFIGURATION
MOVLF LVDCON, B'00001101' ; 4.2 -- 4.45 V IS THE TRIGGER LEVEL
BCF PIE2, LVDIE
; BSF LVDCON, LVDEN
LVDENPOLL BTFSS LVDCON, 5
; GOTO LVDENPOLL
BCF PIR2, LVDIF
bsf IPR2, LVDIP
BSF PIE2, LVDIE ; STEPS FOLLOWED AS IN DATA SHEET
; ALL MY ANSWERS WILL REFER YOU
; TO THE DATA SHEET...
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;; ACTUAL CODE BEGINS HERE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CLRWDT
;SETWATCH
LOOP ;SLEEP
;CLRWDT
I2CSEND H'AB', H'01', H'00'
CALL WAIT
I2CSEND H'15', H'00', H'00'
CALL WAIT
CALL WAIT
CALL GETI2C
MOVWF PORTD
GOTO $
;;;;;;;;;;; SUBROUTINES;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; I2C SUBROUTINES
SENI2C CALL GENSTART
MOVLF CONREG, H'A0'
CALL CALLEEPROM
CALL SENDADDR
CALL SENDDATA
CALL GENSTOP
call WAIT
RETURN
WAITFORACK BTFSC SSPCON2, ACKSTAT
GOTO WAITFORACK
BSF SSPCON2, ACKSTAT
RETURN
GETI2C CALL GENSTART
MOVLF CONREG, H'A0'
CALL CALLEEPROM
CALL SENDADDR
CALL GENSTOP
CALL WAIT
CALL WAIT
CALL GENSTART
MOVLF CONREG, H'A1'
CALL CALLEEPROM
BSF SSPCON2, RCEN
call POLLBUFF
; BFCHK BTFSS SSPSTAT, BF
; GOTO BFCHK
BSF SSPCON2, ACKDT ; ACK = 1
BSF SSPCON2, ACKEN ; SEND ACK
; BCF PIR1, SSPIF
; CALL POLLBUFF
CALL GENSTOP
MOVF SSPBUF, W
RETURN
; GENERATE START CONDITION
GENSTART BCF PIR1, SSPIF ; CLEAR SSPIF
BSF SSPCON2, ACKSTAT
BSF SSPCON2, SEN ; GENERATE START CONDITION
CALL POLLBUFF ; START CONDITION COMPLETELY GENERATED
RETURN
; ADDRESS EEPROM
CALLEEPROM BCF PIR1, SSPIF ; A0 A1 AND A2 ARE GROUNDED
MOVFF CONREG, SSPBUF
CALL WAITFORACK
CALL POLLBUFF
BSF SSPCON2, ACKSTAT ; ASSUMING THAT ACK HAS OCCURED
RETURN
; ADDRESSES THE LOCATION POINTED TO BY 'HIREG' AND 'LOREG'
SENDADDR BCF PIR1, SSPIF
MOVFF HIREG, SSPBUF
CALL WAITFORACK
BSF SSPCON2, ACKSTAT
CALL POLLBUFF
BSF SSPCON2, ACKSTAT ; ASSUMING THAT ACK HAS OCCURED
MOVFF LOREG, SSPBUF
CALL WAITFORACK
CALL POLLBUFF
BSF SSPCON2, ACKSTAT
RETURN
; WRITES THE DATA IN 'TEMP' TO THE LOCATION POINTED BY 'HIREG' AND 'LOREG'
SENDDATA BCF PIR1, SSPIF
MOVFF TEMP, SSPBUF
CALL WAITFORACK
CALL POLLBUFF
BSF SSPCON2, ACKSTAT
RETURN
; GENERATE A STOP CONDITION
GENSTOP BCF PIR1, SSPIF
BSF SSPCON2, PEN
CALL POLLBUFF
RETURN
; 20 MICRO SECONDS DELAY: REQUIRED FOR ADC
DEL20U MOVLF TEMP, D'20'
LOOP_ADCACQ DECF TEMP
BNZ LOOP_ADCACQ
BCF STATUS, Z
RETURN
; POLL SSPIF
POLLBUFF BTFSS PIR1, SSPIF
GOTO POLLBUFF
BCF PIR1, SSPIF
RETURN
GETADC CALL DEL20U
BSF ADCON0, GO
LOOPGETADC BTFSC ADCON0, GO
GOTO LOOPGETADC
MOVF ADRESH, 0
RETURN
; WAIT 10MS TWR (TIME REQUIRED TO WRITE INTERNALLY)
WAIT NOP
MOVLW D'156' ; SET STARTING VALUE
MOVWF TMR0L ; AND LOAD INTO TIMER
BCF INTCON,T0IF ; RESET TIMER OUT FLAG
WEM BTFSS INTCON,T0IF ; WAIT 10MS
GOTO WEM ; FOR TIMEOUT
RETURN ; BYTE WRITE DONE....
;;;;;;;;;; INTERRUPT SERVICE ROUTINES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; HIGH PRIORITY INTERRUPT POLL
HPINT BTFSC PIR2, LVDIF
GOTO LVDINT
BTFSC PIR1, TMR1IF
GOTO TMR1INT
SETWATCH
RETFIE
TMR1INT
BCF PIR1, TMR1IF
CALL GETADC
; SAVE TO ROM
MOVWF TEMP
INCF LOREG
CALL SENI2C
CALL WAIT
GOTO HPINT
LVDINT
BTG PORTB, 0
BTG PORTB, 0
GOTO HPINT
END
Could you please check why my read subroutine fails to get the correct data from the eeprom? I have also attached the proteus design
Added after 16 minutes:
The attachment: Proteus design for the query