LIST P=16F877A, R=DEC
	#include <p16f877a.inc>
TMP0	equ		30h
TMP1	equ		31h
adresa	equ		32h
dáta	equ		33h

; base frequency
XTAL_FREQ   EQU   4000000   ; OSC freq in Hz
; used for I2C calculations
#define  I2CClock    D'100000'           ; define I2C bite rate
#define  I2C_ClockValue  (((XTAL_FREQ/I2CClock)/4) -1) ;  


org	0x2007		; adresa konfigurace PIC16F873,876/PIC16F874,877
 	dw _BODEN_OFF & _CP_OFF & _PWRTE_OFF & _WDT_OFF & _XT_OSC & _DEBUG_OFF & _CPD_OFF & _LVP_OFF

	org	0x0000		; zacatek programu
	goto	INIT		; skok na počáteční inicializaci
  

;**************************************************************************
;podpogramy pro I2C
;**************************************************************************
Start_I2C
;	return
	banksel		PIR1			; 
	bcf			PIR1,SSPIF		; vynulovat priznak operace
	banksel		SSPCON2
	bsf			SSPCON2,SEN		; send i2c START [S] bit
	banksel		PIR1			; dokonceno ?
	btfss		PIR1,SSPIF		; vcetne vseho?
	goto		$-1				; NE, tak pockat a testovat a cekat	goto $-1
	return						; navrat
;***********
Start2_I2C	
;	return
	banksel		PIR1			; 
	bcf			PIR1,SSPIF		; vynulovat priznak operace
	banksel		SSPCON2			;
	bsf			SSPCON2,RSEN	; opakovany START,	
	banksel		PIR1			; dokonceno ?
	btfss		PIR1,SSPIF		; vcetne vseho?
	goto		$-1				; NE, tak pockat a testovat a cekat
	return
;***********
Write_I2C
;	return
	banksel		SSPCON
	bcf			SSPCON,WCOL 
	banksel		PIR1			; START odeslan, jinak bych sem nedosel
	bcf			PIR1,SSPIF		; vynulovat priznak operace
	banksel		SSPBUF			;
	movwf		SSPBUF			; registru odesilani
	banksel		PIR1			; dokonceno ?
	btfss		PIR1,SSPIF		; vcetne ACK od cidla?
	goto		$-1				; NE, tak pockat a testovat a cekat
	return
;***********
Read_I2C_Ack
;	return
	banksel		SSPCON
	bcf			SSPCON,SSPOV	; vynulovat neprectena data,stejne jsou v pr....
	banksel		PIR1			; Data odeslana, jinak bych sem nedosel
	bcf			PIR1,SSPIF		; vynulovat priznak operace
	banksel		SSPCON2 		;
	bsf			SSPCON2,RCEN	; zapnout prijem
	banksel		PIR1			;
	btfss		PIR1,SSPIF		; precteno?
	goto		$-1				; NE, tak pockat a testovat a cekat
	bcf			PIR1,SSPIF		; vynulovat priznak operace
	banksel		SSPBUF			;
	movfw		SSPBUF			; precist  bufer
	banksel		PIR1			; Data prectena, jinak bych sem nedosel
	bcf			PIR1,SSPIF		; vynulovat priznak operace
	banksel		SSPCON2         
	bcf			SSPCON2,ACKDT   ; vyslat AKC
	bsf			SSPCON2,ACKEN   ; nastavit odeslani ACK
	banksel		PIR1			; dokonceno ?
	btfss		PIR1,SSPIF		; vcetne ACK do cidla?
	goto		$-1				; NE, tak pockat a testovat a cekat
	return				
;***********
Read_I2C_NoAck
;	return
	banksel		SSPCON
	bcf			SSPCON,SSPOV	; vynulovat neprectena data,stejne jsou v pr....
	banksel		PIR1			; Data odeslana, jinak bych sem nedosel
	bcf			PIR1,SSPIF		; vynulovat priznak operace
	banksel		SSPCON2 		;
	bsf			SSPCON2,RCEN	; zapnout prijem
	banksel		PIR1			; 
	btfss		PIR1,SSPIF		; precteno?
	goto		$-1				; NE, tak pockat a testovat a cekat
	bcf			PIR1,SSPIF		; vynulovat priznak operace
	banksel		SSPBUF			;
	movfw		SSPBUF			; precist  bufer
	banksel		PIR1			; Data prectena, jinak bych sem nedosel
	bcf			PIR1,SSPIF		; vynulovat priznak operace
	banksel		SSPCON2         
	bsf			SSPCON2,ACKDT   ; nevyslat AKC
	bsf			SSPCON2,ACKEN   ; nastavit neodeslani ACK
	banksel		PIR1			; dokonceno ?
	btfss		PIR1,SSPIF		; vcetne neACK do cidla?
	goto		$-1				; NE, tak pockat a testovat a cekat
	return				
;***********
Stop_I2C
;	return
	banksel		PIR1			; Data odeslana, jinak bych sem nedosel
	bcf			PIR1,SSPIF		; vynulovat priznak operace
	banksel		SSPCON2
	bsf			SSPCON2,PEN		; odeslat STOP
	banksel		PIR1      
	btfss		PIR1,SSPIF      ; odeslan
	goto		$-1				; ne
	return						; navrat

;***********
I2C_prijmi_ack
	BSF		STATUS,RP0		; banka 1
	BTFSC		SSPCON2,ACKSTAT		; zkontroluj zda bylo přijato potvrzení ACK
	goto	$+2
	goto	$+3
	BCF		STATUS,RP0
	BSF		PORTD,7				; pokud ne, tak nastav bit PORTD,7,0
	BCF		STATUS,RP0		; banka 0
	RETURN



;**************************************************************************
;I2C init
;**************************************************************************
INIT_I2C
   ; setup MSSP adress register
	bcf		STATUS,IRP
	banksel	0
	MOVLW	SSPADD   ; get adress for synch serial port status reg
	MOVWF	FSR   ; setup fsr
	MOVLW	I2C_ClockValue ; setup clock rate
	MOVWF	INDF   ; and store it


   ; setup MSSP status reg
	MOVLW	SSPSTAT   ; get adress for synch serial port status reg
	MOVWF	FSR   ; setup fsr
	MOVLW	(0<<SMP) ; enable slowrate control
	MOVWF	INDF   ; and store it

   ; setup MSSP control reg
	bcf		STATUS,IRP
	MOVLW	SSPCON   ; get adress for synch serial port control reg
	MOVWF	FSR   ; setup fsr
	MOVLW	((1<<SSPEN)|(0<<CKP)|(1<<SSPM3)); enable syncronous port, enable clock ,
                  ; I2C master mode clock = OSC/(4*(SSPADD)+1)
	MOVWF	INDF   ; and set it

;   ; enable MSSP interrupt
;   MOVLW   PIE1   ; get adress for periphial irq's
;   MOVWF   FSR   ; setup fsr
;   BSF   INDF,SSPIE  ; enable MSSP irq
;   BSF   INTCON,PEIE ; and periphial irq must also be enabled (if not already )

	return



INIT	movlw	b'000000'	; prednastaveni PORTu A
	movwf	PORTA
	movlw	b'00000000'	; prednastaveni PORTu B
	movwf	PORTB
	movlw	b'00000000'	; prednastaveni PORTu C
	movwf	PORTC
	movlw	b'00000000'	; přednastavení PORTu D
	movwf	PORTD		; !!! jen PIC16F874 a PIC16F877 !!!
	movlw	b'000'		; přednastavení PORTu E
	movwf	PORTE		; !!! jen PIC16F874 a PIC16F877 !!!
;       ------------------------
	banksel	CMCON; banka registru 1

	movlw	b'00000111'	; A/D vstupy OFF
	movwf	CMCON

	movlw	b'000000'	
	movwf	TRISA


	movlw	b'00000000'	
	movwf	TRISB

	movlw	b'00000000'	
	movwf	TRISC

	movlw	b'00000000'	
	movwf	TRISD

	movlw	b'000'	
	movwf	TRISE		

	

	banksel	0	; banka registru 0



	movlw	b'00000000'	; žiadne prerušenia!!!
	movwf	INTCON

	BSF		STATUS,RP0
	BCF		STATUS,RP1		; výběr banky 1
	MOVLW		b'00011000'		; SDA a SCL musi být nastaveny jako vstupy
	MOVWF		TRISC
	BCF		STATUS,RP0
	call		INIT_I2C

	clrf		adresa
	clrf		dáta

	;call	I2C_prijmi_ack	


jump1	nop
	call		Start_I2C
	movlw		b'10100000'	;adresa device
	call		Write_I2C	;zápis adresy dev.

	call		I2C_prijmi_ack

	movfw		adresa	;adresa v eeprom 24c16
	call		Write_I2C	;zápis adr.do eeprom

	call		I2C_prijmi_ack

	movfw		dáta	;dáta pre eeprom
	call		Write_I2C	;zápis dát do eeprom

	call		I2C_prijmi_ack

	call		Stop_I2C	;koniec zápisu


	call		delay

	
	call		Start_I2C
	movlw		b'10100000'	;adresa device

	call		I2C_prijmi_ack

	call		Write_I2C	;zápis adresy dev.

	call		I2C_prijmi_ack

	movfw		adresa	;adresa v eeprom 24c16
	call		Write_I2C	;zápis adr.do eeprom

	call		I2C_prijmi_ack

	call		Start2_I2C	;druhý start
	movlw		b'10100001'	;čítanie z eeprom
	call		Write_I2C	;zápis do eeprom

	call		I2C_prijmi_ack

	call		Read_I2C_NoAck
	banksel		PORTB
	movwf		PORTB

	call		Stop_I2C	;koniec čítania z eeprom 24C16
	call		long_delay


	incf		adresa	;zvýš adresu o jedna
	incf		dáta	;zvýš dáta o jedna
	goto		jump1







delay	MOVLW 0x50  ;80 DEC		50 ms
        MOVWF TMP1
        MOVLW 0x0CF  ;207 DEC
        MOVWF TMP0
        DECFSZ TMP0,F
        GOTO $-1
        DECFSZ TMP1,F
        GOTO $-5
		return
	
long_delay	MOVLW 0x00  ;0 DEC
        MOVWF TMP1
        MOVLW 0x00  ;0 DEC
        MOVWF TMP0
        DECFSZ TMP0,F
        GOTO $-1
        DECFSZ TMP1,F
        GOTO $-3
		return













end
