;****Interfacing 2 wire serial EEPROM**** ; by: Eng'r Roland Michael A. dela Peņa * ;**************************************** LIST P=16F84 ERRORLEVEL -302 #INCLUDE P16F84.INC ;************************************************************ ; REGISTER DEFINITIONS ;************************************************************ CBLOCK 0CH COUNT ; COUNTER ROLAND ; STORAGE REGISTER MICHAEL ; STORAGE REGISTER ECE23314 ; REGISTER TO BE STORED IN EEPROM ENGINEER ; REGISTER TO BE STORED IN EEPROM EEPROM ; BIT BUFFER DATAI ; DATA INPUT REGISTER DATAO ; DATA OUTPUT REGISTER TXBUF ; TRANSMIT BUFFER BUFF ; DATA BUFFER ENDC ;************************************************************ ; BIT DEFINITIONS ;************************************************************ DI EQU 7 ; EEPROM INPUT BIT DO EQU 6 ; EEPROM OUTPUT BIT #DEFINE SDATA PORTB,7 ; SERIAL EE DATA LINE #DEFINE SCLK PORTB,6 ; SERIAL EE CLOCK LINE ;************************************************************************ ; THIS PART INITIALIZES THE PORTS AND OTHER PHERIPERALS ; IN MICROCONTROLLER ;************************************************************************ ORG 0000h ; SET POWER ON RESET VECTOR. CLRF PORTB CLRF PORTA GOTO INIT INIT BSF STATUS,RP0 ; SET BANK = 1. BCF OPTION_REG,7 ; ENABLE BUILT-IN PULL-UP RESISTORS. MOVLW b'00000000' ; SET PORTA TO ALL OUTPUT. MOVWF TRISA MOVLW b'00001110' ; SET RB0,RB4,RB5,RB6,RB7 TO OUTPUT MOVWF TRISA ; AND RB1,RB2,RB3 TO INPUT. BCF STATUS,RP0 ; SET BANK = 0. ;**************************************************************************** ; MAIN ROUTINE ;**************************************************************************** START ; RESERVED FOR PROGRAM LINES ; ; GOTO START ;**************************************************************************** ; THIS SUB ROUTINE READS THE 2 BYTES DATA STORED IN EEPROM ;**************************************************************************** READ CALL BSTART ; INITIALIZE THE READ OPERATION. MOVLW B'10100000' ; SEND SLAVE ADDRESS. CALL TX ; TRANSMIT IT. MOVLW B'00000000' ; SEND HIGHER ADDRESS. CALL TX ; TRANSMIT IT. MOVLW B'00000000' ; SEND LOWER ADDRESS. CALL TX ; TRANSMIT IT. CALL BSTART MOVLW B'10100001' ; SET TO READ MODE. CALL TX CALL RX MOVWF ROLAND CALL ACKNOW CALL RX MOVWF MICHAEL CALL NOACKNOW GOTO BSTOP ;**************************************************************************** ; THIS SUB ROUTINE STORE THE 2 BYTES DATA IN EEPROM ;**************************************************************************** STORE CALL BSTART ; INITIALIZE THE WRITE. MOVLW B'10100000' ; SEND WRITE COMMAND. CALL TX ; X'MIT IT. MOVLW B'00000000' ; SEND HIGHER ADDRESS. CALL TX ; X'MIT IT. MOVLW B'00000000' ; SEND LOWER ADDRESS. CALL TX MOVFW ECE23314 CALL TX MOVFW ENGINEER CALL TX ; X'MIT IT. CALL BSTOP ; TERMINATE THE WRITE. ;**************************************************************************** ; THIS SUB ROUTINE DETERMINES IF THE EEPROM DONE WRITING ;**************************************************************************** POLL CLRF COUNT ; SET 256 LOOPS TO WAIT FOR ACCKNOWLEDGE ; FROM EEPROM. POLL1 CALL BSTART MOVLW B'10100000' CALL TX BTFSS EEPROM,DI ; IS EEPROM DONE WRITING? RETLW D'0' ; YES. DECFSZ COUNT ; NO, THEN WAIT UNTIL EEPROM DONE WRITING. GOTO POLL1 GOTO POLL ; SHOULD NOT GET HERE. ;**************************************************************************** ; START BIT SUBROUTINE THIS ROUTINE GENERATES A START BIT ; (LOW GOING DATA LINE WHILE CLOCK IS HIGH) ;**************************************************************************** BSTART BSF SDATA ; MAKE SURE DATA IS HIGH. BSF STATUS,RP0 MOVLW EEWRITE MOVWF IOPIN ; SET DATA AND CLOCK LINES FOR OUTPUT. BCF STATUS,RP0 BCF SCLK ; MAKE SURE CLOCK IS LOW. CALL NOPER BSF SCLK ; SET CLOCK HIGH. CALL NOPER ; SIT AND WAIT. BCF SDATA ; DATA LINE GOES LOW DURING HIGH CLOCK FOR START BIT. CALL NOPER ; TIMING ADJUSTMENT. BCF SCLK ; START CLOCK TRAIN. GOTO NOPER1 ;**************************************************************************** ; STOP BIT SUBROUTINE ; THIS ROUTINE GENERATES A STOP BIT ; (HIGH GOING DATA LINE WHILE CLOCK IS HIGH) ;**************************************************************************** BSTOP BCF SDATA ; MAKE SURE DATA LINE IS LOW. BSF STATUS,RP0 MOVLW EEWRITE MOVWF IOPIN ; SET DATA/CLOCK LINES AS OUTPUTS. BCF STATUS,RP0 BCF SDATA ; MAKE SURE DATA LINE IS LOW. CALL NOPER ; SIT AND WAIT. BSF SCLK ; SET CLOCK HIGH. CALL NOPER ; SIT AND WAIT. BSF SDATA ; DATA GOES HIGH WHILE CLOCK HIGH ; FOR STOP BIT. CALL NOPER1 BCF SCLK ; SET CLOCK LOW AGAIN. GOTO NOPER ; SIT AND WAIT. ;**************************************************************************** ; BITOUT ROUTINE TAKES THE BIT OF DATA IN 'DO' AND ; TRANSMITS IT TO THE SERIAL EE DEVICE ;**************************************************************************** ACKNOW BCF EEPROM,DO ; SET ACK BIT = 0. GOTO BITOUT ; TO FINISH TRANSMISSION. NOACKNOW BSF EEPROM,DO ; SET ACK BIT = 1. BITOUT BSF STATUS,RP0 MOVLW EEWRITE MOVWF IOPIN ; SET DATA/CLOCK LINES AS OUTPUTS. BCF STATUS,RP0 BTFSC EEPROM,DO ; CHECK FOR STATE OF DATA BIT TO XMIT. BSF SDATA ; HIGH? SET DATA LINE HIGH. BTFSS EEPROM,DO ; CHECK FOR STATE OF DATA BIT TO XMIT. BCF SDATA ; OUTPUT A LOW BIT. CLKOUT BSF SCLK ; SET CLOCK LINE HIGH. CALL NOPER ; SIT AND WAIT. BCF SCLK ; RETURN CLOCK LINE LOW. RETLW D'0' ;**************************************************************************** ; BITIN ROUTINE READS ONE BIT OF DATA FROM THE ; SERIAL EE DEVICE AND STORES IT IN THE BIT 'DI' ;**************************************************************************** BITIN BSF EEPROM,DI ; ASSUME INPUT BIT IS HIGH. BSF STATUS,RP0 MOVLW EEREAD MOVWF IOPIN ; SET DATA LINE AS INPUT. BCF STATUS,RP0 BSF SCLK ; SET CLOCK LINE HIGH. CALL NOPER ; SIT AND WAIT. BTFSS SDATA ; READ THE DATA BIT. BCF EEPROM,DI ; INPUT BIT WAS LOW, SET 'DI' ACCORDINGLY. BCF SCLK ; SET CLOCK LINE LOW. RETLW D'0' ;**************************************************************************** ; TRANSMIT DATA SUBROUTINE ; THIS ROUTINE TAKES THE BYTE OF DATA STORED IN THE ; 'DATAO' REGISTER AND TRANSMITS IT TO THE SERIAL EE DEVICE. ;**************************************************************************** TX MOVWF TXBUF MOVLW D'8' MOVWF COUNT ; SET THE #BITS TO 8. TXLP BCF EEPROM,DO ; ASSUME BIT OUT IS LOW. BTFSC TXBUF,7 ; IS BIT OUT REALLY LOW? BSF EEPROM,DO ; NO, SET IT HIGH. CALL BITOUT ; SEND THE BIT TO SERIAL EE. RLF TXBUF ; ROTATE TXBUF LEFT. DECFSZ COUNT ; 8 BITS DONE? GOTO TXLP ; NO - GO AGAIN. CALL BITIN ; READ ACK BIT. NOPER NOP ; SIT AND WAIT. NOP NOP NOP NOP NOPER1 NOP NOP RETURN ;**************************************************************************** ; RECEIVE DATA ROUTINE THIS ROUTINE READS ONE BYTE OF DATA FROM THE PART ; INTO THE 'DATAI' REGISTER. IT THEN SENDS A HIGH ACKNOWLEDGE BIT TO INDICATE ; THAT NO MORE DATA IS TO BE READ ;**************************************************************************** RX CLRF DATAI ; CLEAR INPUT BUFFER. MOVLW D'8' ; SET # BITS TO 8. MOVWF COUNT BCF STATUS,0 ; MAKE SURE CARRY BIT IS LOW. RXLP RLF DATAI ; ROTATE DATAI 1 BIT LEFT. CALL BITIN ; READ A BIT. BTFSC EEPROM,DI BSF DATAI,0 ; SET BIT 0 IF NECESSARY. DECFSZ COUNT ; 8 BITS DONE? GOTO RXLP ; NO, DO ANOTHER. MOVFW DATAI RETURN END