list	P=16F84, R=DEC
include	"p16f84.inc"

RAM		equ	0Ch	; první adresa paměti RAM pro PIC16F84 - 68bajtů (0C-2F)
TMP_W		equ	RAM+1	; temp preruseni
TMP_S		equ	RAM+2	; temp preruseni
TMP_PCL		equ	RAM+3	; temp preruseni
c1		equ	RAM+4		
c2		equ	RAM+5
c3		equ	RAM+6
CYKL_IC		equ	RAM+7	;I2C
TMP_IC		equ	RAM+8	;I2C
TMP_IC1		equ	RAM+8	;I2C	
PSW		equ	RAM+14	;I2C



TX_REG		equ	RAM+10	;
RX_REG		equ	RAM+11	;
DELAY		equ	RAM+12	;
CITAC		equ	RAM+13	;


#define	PCON	PORTA,4		; vstup kontroly spuštěného PC
#define	PIN_RX	PORTA,2		; Rx - PRIJEM	or
#define	PIN_TX	PORTA,3		; Tx - vysilani b or

#define	SDA	TRISA,0		;I2C
#define	SCL	TRISA,1		;I2C
#define	F_ACK	PSW,0		;i2c

#define	OUT0	PORTB,0		; OUT0 nastavení jmena portu 
#define	OUT1	PORTB,1
#define	OUT2	PORTB,2
#define	OUT3	PORTB,3
#define	OUT4	PORTB,4
#define	OUT5	PORTB,5
#define	OUT6	PORTB,6
#define	OUT7	PORTB,7


	org	0x2007		; adresa konfigurace PIC16F84
	dw _XT_OSC & _PWRTE_OFF & _WDT_OFF & _CP_ON

	org	0x0000		; zacatek programu
	goto	INIT		; skok na počáteční inicializaci

	org	0x0004		; vektor přerušení

	goto	PRERUS

;**************************************************************************
;*                      preruseni kazdych 8,192ms (122Hz)                 *
;**************************************************************************
PRERUS	movwf	TMP_W		; (ulozeni hodnot registru W a STATUS)
	movf	STATUS,W	; prohodi nibble STATUS a ulozi do W
	clrf	STATUS		; nastaveni banky 0
	movwf	TMP_S		; ulozit STATUS

	movf	PCLATH,W
	movwf	TMP_PCL
	clrf	PCLATH		; nastaveni banky 0
;       ------------------------
	bcf	INTCON,T0IF	; vynulovat priznak preruseni (pretekl casovac TMR0)
;-------------------------------





;------------------------------- (obnovení hodnot registru W a STATUS)
INT_END movf	TMP_PCL,W
	movwf	PCLATH		; obnova PCLATH

	movf	TMP_S,W		; prohodi nibble TMP_S a ulozi do W
;	swapf	TMP_S,W		; prohodi nibble TMP_S a ulozi do W
	movwf	STATUS		; obnova STATUS

	swapf	TMP_W,F		; prohodi nibble TMP_W a ulozi do W
	swapf	TMP_W,W		; obnova W
	retfie
;**************************************************************************
INIT	movlw	b'00000'
	movwf	PORTA
	movlw	b'00000000'
	movwf	PORTB
;       ------------------------

	bsf	STATUS,RP0	; banka registru 1
	movlw	b'00000000'	; 
	movwf	TRISB

	movlw	b'11010100'	; PULL-UPy OFF, preddelic=1:32 pripojen k TMR0
	movwf	OPTION_REG	; f:4  :32  :256 = 122,1Hz (8,192ms)
	movlw	b'00010111' 	; portA4-0, 3*vstupy, 1*vystupy
	movwf	TRISA

	bcf	STATUS,RP0	; banka registru 0
;       ------------------------
;	movlw	b'10100000'	; povolena všechna přerušení a od přetečení TMR0
;	movwf	INTCON

;	bsf	INTCON,TOIE	; 1=povoleno přerušení při přetečení TMR0
;	BCF	INTCON,INTE	; 0=ZAKAZANO přerušení z portu RB0/INT
;	bsf	INTCON,GIE	; 1=povolena všechna nemaskovaná přerušení

	goto	MAIN
;**************************************************************************

MAIN

	call	START_IC		
	MOVLW	b'01110000'	;pcf8574A ZAPIS		
	call	WRITE_IC
	MOVLW	b'10101010'	;ODESLANI DAT	
	call	WRITE_IC
	call	STOP_IC	
	call	CEKEJ
	call	CEKEJ
	call	CEKEJ
	call	CEKEJ

	call	START_IC
	MOVLW	b'01110000'
	call	WRITE_IC
	MOVLW	b'01010101'
	call	WRITE_IC
	call	STOP_IC	
	call	CEKEJ
	call	CEKEJ
	call	CEKEJ
	call	CEKEJ

	call	START_IC
	MOVLW	b'01110001'	;pcf8574A CTENI
	call	WRITE_IC
	call	READ_IC
	call	STOP_IC	
	movwf	PORTB		;ULOZENI TMP_IC1 DO PORTU B
	call	CEKEJ
	call	CEKEJ
	call	CEKEJ
	call	CEKEJ

	goto	MAIN


;.......................................................
;RUTINA PRO KOMUNIKACI I2C
;DEFINOVAT TMP_IC,CYKL PLATNE VE VSECH BANKACH!!!!!!!!

START_IC

	bsf   STATUS,RP0
	BSF	SCL	
	BSF	SDA		;KLIDOVY STAV
	CALL	CEK5
	BCF	SDA
	CALL	CEK5
	BCF	SCL
   bcf   STATUS,RP0
	RETURN
;................

;DATA DO W, ACK DO F_ACK

WRITE_IC	MOVWF	TMP_IC
	MOVLW	8
	MOVWF	CYKL_IC		;8CYKLU-BITU

WRITE_IC1	RLF	TMP_IC,F
	bsf   STATUS,RP0
	BCF	SDA		;do 0
	BTFSC	STATUS,C		;C=0 ?		
	BSF	SDA		;NEE, PODLE C NASTAV SDA
	CALL	CEK5
	BSF	SCL
	CALL	CEK5
	BCF	SCL
	CALL	CEK5		;HODINOVY IMPULZ
   bcf   STATUS,RP0
	DECFSZ	CYKL_IC,F		;BYL POSLEDNI BIT??
	GOTO	WRITE_IC1		;NEE
	CALL	CEK5		;ANO, PRECIST ACK
	bsf   STATUS,RP0
	BSF	SDA
	CALL	CEK5
	BSF	SCL
	CALL	CEK5
   bcf   STATUS,RP0
	BCF	F_ACK
	BTFSC	SDA
	BSF	F_ACK		;PODLE SDA/ACK/ F_ACK		
	bsf   STATUS,RP0
	BCF	SCL
   bcf   STATUS,RP0
	RETURN
;................................
;VYSTUP V TMP_IC1, W, FLAG-ACK

READ_IC	MOVLW	8
	MOVWF	CYKL_IC		;8CYKLU-BITU
	bsf   STATUS,RP0
	BSF	SDA		;NASTAVIT TRETI STAV NA SDA
READ_IC1	CALL	CEK5
	bsf   STATUS,RP0
	BSF	SCL		;NABEZNA HRANA HODIN
	CALL	CEK5
   bcf   STATUS,RP0
	BCF	STATUS,C
	BTFSC	SDA	
	BSF	STATUS,C		;PODLE SDA NASTAV C
	RLF	TMP_IC1,F		;PROTOC C DO TMP_IC1
	bsf   STATUS,RP0	
	BCF	SCL		;KONEC HODIN
	CALL	CEK5
   bcf   STATUS,RP0
	DECFSZ	CYKL_IC,F		;JE POSLEDNI BIT??
	GOTO	READ_IC1		;NEE
	CALL	CEK5
	bsf   STATUS,RP0
	BCF	SDA		;ACK
   bcf   STATUS,RP0
	BTFSS	F_ACK		;PODLE PRIZNAKU,NASTAV SDA
	GOTO	READ_IC2
	bsf   STATUS,RP0
	BSF	SDA		;ACK-NOACK
READ_IC2	CALL	CEK5
	bsf   STATUS,RP0
	BSF	SCL
	CALL	CEK5
	BCF	SCL		;HODINOVY IMPULZ
   bcf   STATUS,RP0
	MOVFW	TMP_IC1		;ZKOPIROVAT DO W

	RETURN

;......................
STOP_IC	
	bsf   STATUS,RP0
	BCF	SDA	
	CALL	CEK5
	BSF	SCL
	CALL	CEK5
	BSF	SDA		;UVEDENI DO KLIDOVEHO STAVU
   bcf   STATUS,RP0
	RETURN

;....................			
CEK5	NOP
	NOP
	NOP
	NOP
	RETURN



CEKEJ		MOVLW	100
		MOVWF	c3
wait3		MOVLW	100
		MOVWF	c2
wait2		MOVLW	50
		MOVWF	c1
wait1		DECFSZ	c1,1
		GOTO	wait1
		DECFSZ	c2,1
		GOTO	wait2
		DECFSZ	c3,1
		GOTO	wait3	

	RETURN

CTYRY	NOP
	NOP
	NOP
	NOP
	RETURN


	end			; konec programu

