pratzz
Member level 5
Code:
list p=16F877a
#include <p16F877a.inc>
errorlevel -302
__config _XT_OSC & _WDT_OFF & _LVP_OFF
;-------------------------------------------
; SPECIAL FUNCTION REGISTERS
;-------------------------------------------
indf equ 00
tmr0 equ 01
pcl equ 02
status equ 03
fsr equ 04
portb equ 06
portc equ 07
portd equ 08
pclath equ 0Ah
pir1 equ 0ch
pir2 equ 0dh
sspcon equ 14h
adcon1 equ 1Fh ; other bank
sspcon2 equ 11h
sspadd equ 13h
sspstat equ 14h
;-------------------------------------------
; GENERAL PURPOSE REGISTERS
;-------------------------------------------
CBLOCK 20h
count
count1
dat
disp
pollcnt
ENDC
;-------------------------------------------
; PORTC bits
;-------------------------------------------
SCK equ 3
SDI equ 4
SDO equ 5
CS equ 7
;-------------------------------------------
; PORTB bits
;-------------------------------------------
rs equ 0
rw equ 1
en equ 2
;-------------------------------------------
;*******************Macro definitions*****************************
WRITE_ADDR equ b'10100000' ; Control byte for write operations
READ_ADDR equ b'10100001' ; Control byte for read operations
;----- PIR1 Bits ----------------------------------------------------------
PSPIF EQU H'0007'
ADIF EQU H'0006'
RCIF EQU H'0005'
TXIF EQU H'0004'
SSPIF EQU H'0003'
CCP1IF EQU H'0002'
TMR2IF EQU H'0001'
TMR1IF EQU H'0000'
;----- PIR2 Bits ----------------------------------------------------------
CMIF EQU H'0006'
EEIF EQU H'0004'
BCLIF EQU H'0003'
CCP2IF EQU H'0000'
;----- SSPCON Bits --------------------------------------------------------
WCOL EQU H'0007'
SSPOV EQU H'0006'
SSPEN EQU H'0005'
CKP EQU H'0004'
SSPM3 EQU H'0003'
SSPM2 EQU H'0002'
SSPM1 EQU H'0001'
SSPM0 EQU H'0000'
;----- SSPCON2 Bits --------------------------------------------------------
GCEN EQU H'0007'
ACKSTAT EQU H'0006'
ACKDT EQU H'0005'
ACKEN EQU H'0004'
RCEN EQU H'0003'
PEN EQU H'0002'
RSEN EQU H'0001'
SEN EQU H'0000'
;----- SSPSTAT Bits -------------------------------------------------------
SMP EQU H'0007'
CKE EQU H'0006'
D EQU H'0005'
I2C_DATA EQU H'0005'
NOT_A EQU H'0005'
NOT_ADDRESS EQU H'0005'
D_A EQU H'0005'
DATA_ADDRESS EQU H'0005'
P EQU H'0004'
I2C_STOP EQU H'0004'
S EQU H'0003'
I2C_START EQU H'0003'
R EQU H'0002'
I2C_READ EQU H'0002'
NOT_W EQU H'0002'
NOT_WRITE EQU H'0002'
R_W EQU H'0002'
READ_WRITE EQU H'0002'
UA EQU H'0001'
BF EQU H'0000'
;----- STATUS Bits --------------------------------------------------------
IRP EQU H'0007'
RP1 EQU H'0006'
RP0 EQU H'0005'
NOT_TO EQU H'0004'
NOT_PD EQU H'0003'
Z EQU H'0002'
DC EQU H'0001'
C EQU H'0000'
;--------------------------------------------------------------------
ORG 0
clrf status
movlw 00
movwf pclath
goto start
;-------------------------------------------
org 04
retfie
;-----------------------------------------------------------------
lcd_cmd
movwf portd
bcf portb,rs
bcf portb,rw
bsf portb,en
call delay
bcf portb,en
retlw 00h
;------------------------------------------------------------------
lcd_data
movwf portd
bsf portb,rs
bcf portb,rw
bsf portb,en
call delay
bcf portb,en
retlw 00h
;------------------------------------------------------------------
lcd_init
movlw 38h
call lcd_cmd
call delay
movlw 0eh
call lcd_cmd
call delay
movlw 01h
call lcd_cmd
call delay
movlw 06h
call lcd_cmd
call delay
movlw 80h
call lcd_cmd
call delay
call delay
retlw 00h
;-------------------------------------------------------------------
delay
movlw 02h
movwf count
here2 movlw 0ffh
movwf count1
here decfsz count1,1
goto here
decfsz count,1
goto here2
retlw 00h
;-----------------------------------------------------------------
initialise
bcf status,RP1
bsf status,RP0
clrf portb
clrf portd
movlw b'00000111'
movwf adcon1
movlw b'11111111'
movwf portc ; Set PORTC to all inputs
clrf sspstat ; Disable SMBus inputs
bsf sspstat,SMP ; Disable slew rate control
movlw 09h ; Load 0x18 into WREG
movwf sspadd ; Setup 100 kHz I2C clock
clrf sspcon2
bcf status,RP0
movlw b'00101000'
movwf sspcon ; Enable SSP, select I2C Master mode
bcf pir1,SSPIF ; Clear SSP interrupt flag
bcf pir2,BCLIF
retlw 00
;--------------------------------------------------------------
genstart
bcf STATUS,RP1
bcf STATUS,RP0 ; Select Bank 00
bcf PIR1,SSPIF ; Clear SSP interrupt flag
bsf STATUS,RP0 ; Select Bank 01
bsf SSPCON2,SEN ; Generate Start condition
bcf STATUS,RP0 ; Select Bank 00
start_wait
btfss PIR1,SSPIF ; Check if operation completed
goto start_wait ; If not, keep checking
retlw 0
genstop
bcf STATUS,RP1
bcf STATUS,RP0 ; Select Bank 00
bcf PIR1,SSPIF ; Clear SSP interrupt flag
bsf STATUS,RP0 ; Select Bank 01
bsf SSPCON2,PEN ; Generate Stop condition
bcf STATUS,RP0 ; Select Bank 00
stop_wait
btfss PIR1,SSPIF ; Check if operation completed
goto stop_wait ; If not, keep checking
retlw 00
genrepstart
bcf STATUS,RP1
bcf STATUS,RP0 ; Select Bank 00
bcf PIR1,SSPIF ; Clear SSP interrupt flag
bsf STATUS,RP0 ; Select Bank 01
bsf SSPCON2,RSEN ; Generate Restart condition
bcf STATUS,RP0 ; Select Bank 00
repstart_wait
btfss PIR1,SSPIF ; Check if operation completed
goto repstart_wait ; If not, keep checking
retlw 0
;-------------------------------------------------------------
receive
movlw 0c0h
call lcd_cmd
bcf STATUS,RP1
bcf STATUS,RP0 ; Select Bank 00
bcf PIR1,SSPIF ; Clear SSP interrupt flag
bsf STATUS,RP0 ; Select Bank 01
bsf SSPCON2,RCEN ; Initiate reception of byte
bcf STATUS,RP0 ; Select Bank 00
rx_wait
btfss PIR1,SSPIF ; Check if operation completed
goto rx_wait ; If not, keep checking
movf SSPBUF,w ; Copy byte to WREG
; movwf dat ; Copy WREG to datai
;movf dat,w
call lcd_data
bcf PIR1,SSPIF ; Clear SSP interrupt flag
bsf STATUS,RP0 ; Select Bank 01
bsf SSPCON2,ACKEN ; Generate ACK/NO ACK bit
bcf STATUS,RP0 ; Select Bank 00
rx_wait2
btfss PIR1,SSPIF ; Check if operation completed
goto rx_wait2 ; If not, keep checking
retlw 0
;-------------------------------------------------------------
transmit
bcf STATUS,RP1
bcf STATUS,RP0 ; Select Bank 00
bcf PIR1,SSPIF ; Clear SSP interrupt flag
movf dat,w ; Copy dat to WREG
movwf SSPBUF ; Write byte out to device
tx_wait
btfss PIR1,SSPIF ; Check if operation completed
goto tx_wait ; If not, keep checking
bcf pir1,SSPIF
bsf STATUS,RP0 ; Select Bank 01
btfsc SSPCON2,ACKSTAT ; Check if ACK bit was received
call ackfailed ; This executes if no ACK received
retlw 0
;--------------------------------------------------------------
;-----------------------------------------------------------
byteread
call genstart ; Generate Start condition
; Send control byte
bcf STATUS,RP0 ; Select Bank 00
movlw WRITE_ADDR ; Load control byte for write
movwf dat ; Copy to datao for output
call transmit ; Send control byte to device
; Send word address high byte
bcf STATUS,RP0 ; Select Bank 00
movlw 12h ; Load 0x5A for word address
movwf dat ; Copy to datao for output
call transmit ; Send high byte to device
; Send word address low byte
call genrepstart ; Generate Restart condition
; Send control byte
bcf STATUS,RP0 ; Select Bank 00
movlw READ_ADDR ; Load control byte for read
movwf dat ; Copy to datao for output
call transmit ; Send control byte to device
; Read data byte
bsf STATUS,RP0 ; Select Bank 01
bsf SSPCON2,ACKDT ; Select to send NO ACK bit
bcf status,RP0
call receive ; Read data byte from device
call genstop ; Generate Stop condition
retlw 0
bytewrite
call genstart ; Generate Start condition
; Send control byte
bcf STATUS,RP0 ; Select Bank 00
movlw WRITE_ADDR ; Load control byte for write
movwf dat ; Copy to dat for output
call transmit ; Send control byte to device
movlw 12h
movwf dat
call transmit
movlw 'a'
movwf dat
movwf disp
call transmit
call genstop
movf disp,w
call lcd_data
retlw 00
ackfailed
bcf status,RP0
movlw 'E'
call lcd_data
retlw 00
;-------------------------------------------
; Main program starts
;-------------------------------------------
start call initialise
call lcd_init
call bytewrite
call byteread
x goto x
end
Code:
btfsc SSPCON2,ACKSTAT ; Check if ACK bit was received
call ackfailed
Last edited: