 | Код: ;================================================================== ; Purpose: ; ; This application note is intended to serve as a reference for ; communicating with Microchip’s I2C serial EEPROM devices with the ; use of the PICmicro MSSP module. ;================================================================== ; ПРОГРАМА ЗА I2C ОБМЕН ; Използва се апаратен протокол чрез шини ; RC3 - CLOCK ; RC4 - DATA ; Port C pin descriptions ; SCL bit = 3 ; SDA bit = 4 ;================================================================== ; 4Mhz - кварц - това има значение за определяне на четотата за I2C ; DS1307 ; ; ; ;============================================================================= LIST P=16F873 ; LIST DIRECTIVE TO DEFINE PROCESSOR #INCLUDE <P16F873.INC> ; PROCESSOR SPECIFIC VARIABLE DEFINITIONS ERRORLEVEL -302 ; SUPPRESS BANK SELECTION MESSAGES
__config _cp_ALL & _wdt_off & _BODEN_ON & _pwrte_on & _hs_osc & _LVP_OFF & _DEBUG_OFF & _CPD_OFF
;=============================================================================
;===================RAM register definitions====================== CBLOCK H'20' datai ;20h Data input byte buffer datao ;21h Data output byte buffer bytecount ;22h Counter for byte loops pollcnt ;23h Counter for polling loops loops ;24h Delay loop counter loops2 ;25h Delay loop counter SDATA ADRESS
HOUR_H HOUR_L MIN_H MIN_L SEC_H SEC_L
DAY_H DAY_L MONTH_H MONTH_L YEAR_H YEAR_L
TEMP NOTEMP DLAY DD1 DD2 DD3
d1 d2 d3 ENDC ;===================Macro definitions============================= WRITE_ADDR equ H'D0' ; Control byte for write operations READ_ADDR equ H'D1' ; Control byte for read operations ;===================Include file==================================
; MACROS
BANK0 MACRO BCF STATUS,RP0 BCF STATUS,RP1 ENDM BANK1 MACRO BSF STATUS,RP0 BCF STATUS,RP1 ENDM
;================================================================ ; НАЧАЛО НА ПРОГРАМАТА ;================================================================ ORG H'0' ; RESET VECTOR LOCATION GOTO START ; Go to the beginning of main
;===================Begin Main Program============================ START CALL DELAY1S ;изчакване на 1 сек за установяване на системата BANK1 MOVLW H'07' MOVWF ADCON1 ; AN0-AN7 - DIGITAL INPUTS BANK0 ;========================================================== CLRF PORTC
MOVLW B'00000000' MOVWF PORTB CLRF PORTA ;==================== PORT A ============================== BANK1 MOVLW B'00010111' ; RA0-PA3,RA5 - ВХОДОВЕ MOVWF TRISA ; RA4- ИЗХОД ;==================== PORT B ============================== MOVLW B'00000000' ;RB7-RB0 - ИЗХОДИ MOVWF TRISB ; ;==================== PORT C ============================== MOVLW B'11111111' ;RC0-RC7 - ВХОДОВЕ MOVWF TRISC ;========================================================== MOVLW B'0001111' ;Prescaler Rate=256, PULL-up ENABLE MOVWF OPTION_REG BANK0 CLRF INTCON ;========================================================== CLRF PORTA CLRF PORTC CLRF PORTB ;========================================================== ; Нулирана на константите ; Нулира се адресното поле H'20' - H'7F' ;========================================================== MOVLW H'20' MOVWF FSR CL CLRF INDF INCF FSR,F BTFSS FSR,7 ; достигнато ли е H'80' GOTO CL
BANK0 ; ИНИЦИАЛИЗАЦИЯ НА LCD CALL LCD_INIT1 CALL INIT ; Initialize device
;=============================================================
CALL INIT_DS1307
goto v1 MOVLW D'2' MOVWF HOUR_H MOVLW D'2' MOVWF HOUR_L
MOVLW D'2' MOVWF MIN_H MOVLW D'5' MOVWF MIN_L v1 CALL READ_CLOCK
call CLOCK_LCD
goto v1
;===================Initialization subroutine===================== ; This routine initializes the MSSP module ; for I2C Master mode, with a 100 kHz clock. ;================================================================= INIT BANK1 ; Select Bank 01 BSF TRISC, 3 ;RC3,RC4 - ВХОДОВЕ BSF TRISC, 4 ;
CLRF SSPSTAT ; Disable SMBus inputs BSF SSPSTAT,SMP ; Disable slew rate control ; може да се пробва и с D'99' за скорост 10kHz MOVLW D'99' ;50 KHZ FOR FOSC = 4000 KHZ MOVWF SSPADD ;I2C MASTER MODE, CLOCK = FOSC/(4 *(SSPADD+1)) CLRF SSPCON2 ; Clear control bits
BANK0 ; Select Bank 00 MOVLW B'00101000' MOVWF SSPCON ; Enable SSP, select I2C Master mode BCF PIR1,SSPIF ; Clear SSP interrupt flag BCF PIR2,BCLIF ; Clear Bit Collision flag RETLW 0 ;===================Start bit subroutine========================== INIT_DS1307 CLRF ADRESS CLRF SDATA CALL BYTEWRITE
MOVLW 7 MOVWF ADRESS MOVLW B'10010000' MOVWF SDATA CALL BYTEWRITE RETURN ;================================================ ; ЗАПИС НА ВРЕМЕ В DS1307 ???????????????? ;================================================ WRITE_CLOCK CALL BSTART ; Generate Start condition ; запис на адреса на чипа BANK0 ; Select Bank 00 MOVFW WRITE_ADDR MOVWF DATAO ; Copy to datao for output CALL TX
; запис на адрес 0 BANK0 ; Select Bank 00 CLRW ;ADRESS MOVWF DATAO ; Copy to datao for output CALL TX ; Send word address to device
;НУЛИРАНЕ СЕКУНДИ BANK0 ; Select Bank 00 CLRW MOVWF DATAO ; Copy to datao for output CALL TX ; Send data byte to device
;ЗАПИС МИНУТИ BANK0 SWAPF MIN_H,W ;ПАКЕТИРА МИН ADDWF MIN_L,W MOVWF DATAO CALL TX
; ЧАСОВЕ BANK0 SWAPF HOUR_H,W ;ПАКЕТИРА ЧАСА ADDWF HOUR_L,W MOVWF DATAO CALL TX
CALL BSTOP ; Generate Stop condition
; CALL POLL ; Poll for write completion
RETLW 0 ;================================================ ; ЗАПИС НА ДАТА В DS1307 ;================================================ WRITE_DATA CALL BSTART ; Generate Start condition ; запис на адреса на чипа BANK0 ; Select Bank 00 MOVFW WRITE_ADDR MOVWF DATAO ; Copy to datao for output CALL TX
; запис на адрес 0 BANK0 ; Select Bank 00 MOVLW H'4' ;ADRESS MOVWF DATAO ; Copy to datao for output CALL TX ; Send word address to device
;ЗАПИС ДНИ BANK0 SWAPF DAY_H,W ;ПАКЕТИРА ДЕНЯ ADDWF DAY_L,W MOVWF DATAO ; Copy to datao for output CALL TX ; Send word address to device
;ЗАПИС МЕСЕЦИ BANK0 SWAPF MONTH_H,W ;ПАКЕТИРА МЕСЕЦ ADDWF MONTH_L,W MOVWF DATAO ; Copy to datao for output CALL TX ; Send word address to device
;ЗАПИС ГОДИНИ SWAPF YEAR_H,W ;ПАКЕТИРА ГОДИНА ADDWF YEAR_L,W MOVWF DATAO ; Copy to datao for output CALL TX ; Send word address to device
CALL BSTOP ; Generate Stop condition
RETLW 0 ;================================================ ; ПОДПРОГРАМА ЗА ЧЕТЕНЕ НА ВРЕМЕ ОТ DS1307 ;================================================ READ_CLOCK CALL BSTART ; Generate Start condition
; запис на адреса на чипа BANK0 ; Select Bank 00 MOVFW WRITE_ADDR MOVWF DATAO ; Copy to datao for output CALL TX
; запис на адрес 0 BANK0 ; Select Bank 00 CLRW ;ADRESS MOVWF DATAO ; Copy to datao for output CALL TX ; Send word address to device
;************************* call BRESTART
; запис на адреса на чипа BANK0 ; Select Bank 00 MOVFW READ_ADDR MOVWF DATAO ; Copy to datao for output CALL TX ;ЧЕТЕ СЕКУНДИ BANK1 ; Select Bank 01 BCF SSPCON2,ACKDT ; Select to send ACK bit CALL RX ; Input data from device MOVFW DATAI ANDLW B'00001111' MOVWF SEC_L SWAPF DATAI,W ANDLW B'00001111' MOVWF SEC_H
;ЧЕТЕ МИНУТИ BANK1 ; Select Bank 01 BCF SSPCON2,ACKDT ; Select to send ACK bit CALL RX ; Input data from device MOVFW DATAI ANDLW B'00001111' MOVWF MIN_L SWAPF DATAI,W ANDLW B'00001111' MOVWF MIN_H
;ЧЕТЕ ЧАСОВЕ BANK1 ; Select Bank 01 BCF SSPCON2,ACKDT ; Select to send ACK bit CALL RX ; Input data from device MOVFW DATAI ANDLW B'00001111' MOVWF HOUR_L SWAPF DATAI,W ANDLW B'00001111' MOVWF HOUR_H CALL BSTOP ; Generate stop bit RETLW 0 ;================================================ ; ПОДПРОГРАМА ЗА ЧЕТЕНЕ НА ДАТА ОТ DS1307 ;================================================ READ_DATA CALL BSTART ; Generate Start condition ; запис на адреса на чипа BANK0 ; Select Bank 00 MOVFW WRITE_ADDR MOVWF DATAO ; Copy to datao for output CALL TX
; запис на адрес 0 BANK0 ; Select Bank 00 MOVLW H'4' ;ADRESS MOVWF DATAO ; Copy to datao for output CALL TX ; Send word address to device ;************************* CALL BSTART ; Generate Start condition ; запис на адреса на чипа BANK0 ; Select Bank 00 MOVFW READ_ADDR MOVWF DATAO ; Copy to datao for output CALL TX
;ЧЕТЕ ДЕН BANK1 ; Select Bank 01 BCF SSPCON2,ACKDT ; Select to send ACK bit CALL RX ; Input data from device MOVFW DATAI ANDLW B'00001111' MOVWF DAY_L SWAPF DATAI,W ANDLW B'00001111' MOVWF DAY_H
;ЧЕТЕ МЕСЕЦ BANK1 ; Select Bank 01 BCF SSPCON2,ACKDT ; Select to send ACK bit CALL RX ; Input data from device MOVFW DATAI ANDLW B'00001111' MOVWF MONTH_L SWAPF DATAI,W ANDLW B'00001111' MOVWF MONTH_H
;ЧЕТЕ ГОДИНА BANK1 ; Select Bank 01 BCF SSPCON2,ACKDT ; Select to send ACK bit CALL RX ; Input data from device MOVFW DATAI ANDLW B'00001111' MOVWF YEAR_L SWAPF DATAI,W ANDLW B'00001111' MOVWF YEAR_H CALL BSTOP ; Generate stop bit RETLW 0 ;===================Start bit subroutine========================== ; This routine generates a Start condition ; (high-to-low transition of SDA while SCL ; is still high. ;================================================================= BSTART BANK0 ; Select Bank 00 BCF PIR1,SSPIF ; Clear SSP interrupt flag
BANK1 ; Select Bank 01 BSF SSPCON2,SEN ; Generate Start condition BANK0 ; Select Bank 00
BSTART_WAIT BTFSS PIR1,SSPIF ; Check if operation completed GOTO BSTART_WAIT ; If not, keep checking
RETLW 0
;===================Restart bit subroutine========================== ; This routine generates a Repeated Start ; condition (high-to-low transition of SDA ; while SCL is still high. ;================================================================= BRESTART BANK0 ; Select Bank 00 BCF PIR1,SSPIF ; Clear SSP interrupt flag
BANK1 ; Select Bank 01 BSF SSPCON2,RSEN ; Generate Restart condition BANK0 ; Select Bank 00
BRESTART_WAIT BTFSS PIR1,SSPIF ; Check if operation completed GOTO BRESTART_WAIT ; If not, keep checking
RETLW 0 ;===================Stop bit subroutine=========================== ; This routine generates a Stop condition ; (low-to-high transition of SDA while SCL ; is still high. ;================================================================= BSTOP BANK0 BCF PIR1,SSPIF ; Clear SSP interrupt flag BANK1 ; Select Bank 01 BSF SSPCON2,PEN ; Generate Stop condition BANK0
BSTOP_WAIT BTFSS PIR1,SSPIF ; Check if operation completed GOTO BSTOP_WAIT ; If not, keep checking
RETLW 0
;===================Data transmit subroutine====================== ; This routine transmits the byte of data ; stored in 'datao' to the serial EEPROM ; device. Instructions are also in place ; to check for an ACK bit, if desired. ; Just replace the 'goto' instruction, ; or create an 'ackfailed' label, to provide ; the functionality. ;================================================================= TX BANK0 BCF PIR1,SSPIF ; Clear SSP interrupt flag MOVF DATAO,W ; Copy datao 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 ;================= ; BSF STATUS,RP0 ; Select Bank 01 ; BTFSC SSPCON2,ACKSTAT ; Check if ACK bit was received ; GOTO ACKFAILED ; This executes if no ACK received ;================= RETLW 0
;===================Data receive subroutine======================= ; This routine reads in one byte of data from ; the serial EEPROM device, and stores it in ; 'datai'. It then responds with either an ; ACK or a NO ACK bit, depending on the value ; of 'ACKDT' in 'SSPCON2'. ;================================================================= RX BANK0 ; Select Bank 00 BCF PIR1,SSPIF ; Clear SSP interrupt flag BANK1 ; Select Bank 01 BSF SSPCON2,RCEN ; Initiate reception of byte BANK0 ; 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 DATAI ; Copy WREG to datai BCF PIR1,SSPIF ; Clear SSP interrupt flag BANK1 ; Select Bank 01 BSF SSPCON2,ACKEN ; Generate ACK/NO ACK bit BANK0 ; Select Bank 00
RX_WAIT2 BTFSS PIR1,SSPIF ; Check if operation completed GOTO RX_WAIT2 ; If not, keep checking
RETLW 0
;===================Byte write test subroutine==================== ; This routine tests the byte write feature ; of the serial EEPROM device. It will write ; 1 byte of data to the device at address 0x5AA5. ;================================================================= BYTEWRITE CALL BSTART ; Generate Start condition
BANK0 ; Select Bank 00 MOVFW WRITE_ADDR MOVWF DATAO ; Copy to datao for output CALL TX
BANK0 ; Select Bank 00 MOVFW ADRESS MOVWF DATAO ; Copy to datao for output CALL TX ; Send word address to device
BANK0 ; Select Bank 00 MOVFW SDATA MOVWF DATAO ; Copy to datao for output CALL TX ; Send data byte to device
CALL BSTOP ; Generate Stop condition
CALL POLL ; Poll for write completion
RETLW 0 ;===================Byte read test subroutine===================== ; This routine tests the byte read feature ; of the serial EEPROM device. It will read ; 1 byte of data at address 0x5AA5 from the device. ;================================================================= BYTEREAD CALL BSTART ; Generate Start condition
BANK0 ; Select Bank 00 MOVFW WRITE_ADDR MOVWF DATAO ; Copy to datao for output CALL TX ; Send high byte to device
BANK0 ; Select Bank 00 MOVFW ADRESS MOVWF DATAO ; Copy to datao for output CALL TX ; Send word address to device
CALL BRESTART ; Generate Restart condition
BANK0 ; Select Bank 00 MOVFW READ_ADDR MOVWF DATAO ; Copy to datao for output CALL TX ; Send control byte to device
BANK1 ; Select Bank 01 BSF SSPCON2,ACKDT ; Select to send NO ACK bit CALL RX ; Read data byte from device
CALL BSTOP ; Generate Stop condition
RETLW 0
;===================Acknowledge Polling subroutine================ ; This subroutine polls the EEPROM device ; for an ACK bit, which indicates that the ; internal write cycle has completed. Code ; is in place for a timeout routine, just ; uncomment the 'goto TimedOut' line, and ; provide a 'TimedOut' label. ;================================================================= POLL BANK0 ; Select Bank 00 MOVLW .40 MOVWF POLLCNT ; Set max polling times to 40 POLLING CALL BRESTART ; Generate start bit
BANK0 ; Select Bank 00 MOVLW WRITE_ADDR ; Now send the control byte MOVWF DATAO ; Copy control byte to buffer CALL TX ; Output control byte to device BANK1 ; Select Bank 01 BTFSS SSPCON2,ACKSTAT ; Was the ACK bit low? GOTO EXITPOLL ; If yes, stop polling ; If no, check if polled 40 times BANK0 ; Select Bank 00 DECFSZ POLLCNT,F ; Is poll counter down to zero? GOTO POLLING ; If no, poll again ; GOTO TIMEDOUT ; If yes, part didn't respond ; in time, so take action EXITPOLL CALL BSTOP ; Generate stop bit RETLW 0 ;================================================================
;=========================================================== END
|  |