	list p=16f628A
;**************************************************************
;*  	Pinbelegung
;*	----------------------------------	
;*	PORTA: 	0 SDA out
;*		1 CLK in
;*		2 SDA in
;*		3 CLK out
;*		4 -
;*		5 -
;*		6 -
;*		7 -
;*
;*	PORTB:	0 : 7segment kijelzõ anódok
;*		1 		
;*		2 
;*		3 
;*		4 
;*		5 
;*		6 
;*	
;**************************************************************
;
;sprut (zero) Bredendiek 12/2003 
;
; Temperaturmessung mit LM75
;
; Prozessor 16F628 
;
; Prozessor-Takt 10 MHz
;
; IIC am PortA
; 7 segment PortB
;
; 
;
;
;**********************************************************
; Includedatei für den 16F628 einbinden

	#include <P16f628A.INC>

	ERRORLEVEL      -302    	;SUPPRESS BANK SELECTION MESSAGES


; Configuration festlegen:
; Power on Timer, kein Watchdog, HS-Oscillator, kein Brown out, kein LV-programming

   __CONFIG _CP_OFF & _PWRTE_OFF & _WDT_OFF & _BODEN_OFF & _INTRC_OSC_NOCLKOUT & _LVP_OFF & _MCLRE_ON

; Variablen festlegen

buf			equ	0x22	; puffer für I2C
Temp_h		equ	0x23	; Temperatur in grad
Temp_l		equ	0x24	; 0.5°C auf Bit 7
count		equ	0x2B	; universeller zähler
loops		equ	0x2C	; timer für wait
loops2		equ	0x2D	; timer für wait


; 8-Bit Rechenregister
xw0		EQU	0x32	;LSB

; 8-Bit Rechenregister
f0		EQU	0x3A	;LSB

; Dezimalstellen
HdH		EQU	0x4B	;3  Hunderter
HdZ		EQU	0x4C	;2  Zehner
HdE		EQU	0x4D	;1  Einer
HdX		EQU	0x4E	; Puffer für eine Dezimalstelle
dig2	equ	0x51
dig3	equ	0x52
One		equ	0x53
W_temp	equ	0x54

; für I2C
#define	SDAo	PORTA,0		;Daten output
#define	SDAi	PORTA,2		;Daten input
#define	SCL		PORTA,3		;Takt
#define	SCLo	PORTA,3		;Takt
#define	SCLi	PORTA,1		;Takt input



;********************************************************

	org	0
	goto	Init

;********************************************************
; Das Programm beginnt mit der Initialisierung

	org 0x04
	goto	ISR

Init
	bsf     STATUS, RP0	; Bank 1
	movlw	B'00000000'	; PortB alle outputs 
	movwf	TRISB
	movlw	B'00110110'	; PortA 0,3,6,7 out a többi input
	movwf	TRISA
	bcf     STATUS, RP0	; Bank 0
	clrf	PORTA		
	clrf	PORTB		


	banksel	PORTA
		CLRF	 PORTA ;Initialize PORTA by setting
		MOVLW	 0X07 ;Turn comparators off 
		MOVWF	 CMCON

   		banksel TRISA
		movlw b'00010110'
	
		movwf	TRISA
		clrf	TRISB
		movlw	b'10000100'
		movwf	OPTION_REG
		banksel PORTA
		movlw	.96
		bsf		PORTA,6
		movwf	TMR0
		movlw	b'10100000'
		movwf	INTCON
	
	
		
		clrf	One
		clrf	PORTA

mainloop
	 ;Temp messen

	call	i2c_on		; Bus aktiv 

	movlw 	H'91'		; 1001 0001 
	call	i2c_tx		; LM75 zum lesen adressieren 

	call 	i2c_rxack 
	movwf   Temp_h		; Byte in Speicherzelle Datenpuffer retten

	call 	i2c_rx 
	movwf   Temp_l		; Byte in Speicherzelle Datenpuffer retten 

	call	i2c_off		; Bus freigeben

	

	; Temp anzeigen
	movfw	Temp_h
	movwf	f0
	movlw	.2
	addwf	f0
	call	Hex2Dez8


	movlw	D'250'		; 250 ms Pause 


	



	movfw	HdZ				;Amit ide írok azt kiirja a kijelzõkre
	movwf	dig2
	movfw	HdE
	movwf	dig3
		
		
	call	WAIT
	goto	mainloop

;*****************************************************************
; Routinen für I2C
;	Bus übernehmen	i2c_on
;	W senden	i2c_tx
;	Byte empfangen	i2c_rx (nach w und RXData und SSPBUF)
;	Bus freigeben	i2c_off
;*****************************************************************
i2c_reset
	bsf	SDAo
	bsf	SCLo
	nop
	movlw	9
	movwf	buf
i2c_reset1
	nop
	bcf	SCLo
	nop
	nop
	nop
	nop
	nop
	bsf	SCLo
	nop
	decfsz	buf, f
	goto	i2c_reset1
	nop
	call	i2c_on
	nop
	bsf	SCLo
	nop
	nop
	bcf	SCLo
	nop
	call	i2c_off
	return

i2c_on
	; wenn SDA und SCL beide High, dann SDA auf Low ziehen
	bsf	SCL		; failsave
	bsf	SDAo		; failsave

	;testen, ob der Bus frei ist
	btfss	SCLi
	goto	i2c_on		; Taktleitung frei?
	btfss	SDAi
	goto	i2c_on		; Datenleitung frei?

	bcf	SDAo
	nop
	bcf	SCL
	return


i2c_tx
	; w über i2c senden
	; takt ist unten
	; daten sind unten
	call	WrI2cW		; 8 Bit aus W nach I2C
	; ACK muß nun empfangen werden
	; Takt ist low
	bsf	SDAo		;Datenleitung loslassen

	bsf	SCL		; ACK Takt high
i2c_tx2
	btfss	SCLi
	goto	i2c_tx2

	nop
;i2c_tx1
;	btfsc	SDAi		; ACK empfangen?
;	goto	i2c_tx1		; nein SDA ist high
	bcf	SCL		; ja , Takt beenden
	bcf	SDAo
	return 


i2c_rxack
	; takt ist unten
	; daten sind unten
	call	RdI2cW		; 8 von I2C nach W
	; Takt ist unten
	; ACK muß nun gesendet werden
	bcf	SDAo
	nop
	nop
	nop
	nop
	bsf	SCL
i2c_rxack1
	btfss	SCLi
	goto	i2c_rxack1

	nop
	bcf	SCL
	bcf	SDAo
	return

i2c_rx
	; takt ist unten
	; daten sind unten
	call	RdI2cW		; 8 von I2C nach W
	; Takt ist unten
	; kein ACK
	nop
	nop
	bsf	SDAo
	nop

	bsf	SCL
i2c_rx1
	btfss	SCLi
	goto	i2c_rx1

	nop
	bcf	SCL
	bcf	SDAo
	return


i2c_off
	; SCL ist Low und SDA ist Low
	nop
	nop
	bsf	SCL
	nop
	bsf	SDAo
	return



;*****************************************************
; I2C-Peride ist 2,5 µs
; PIC-Zyklus ist 4/10MHz = 0,4µs
; -> Takt muß für 3 Zyklen H und für 3 Zyklen L sein
;     + 1 Zyklus Reserve


;schiebt das Byte aus W in den I2C
; MSB zuerst
; 78 Takte
WrI2cW
	; Takt unten, Daten unten
	; Datenbyte in w
	movwf	buf
	movlw	8
	movwf	count		; 8 Bits
WrI2cW1

	; Datenleitung setzen
	bcf	SDAo
	rlf	buf,f
	btfsc	STATUS,C	; 0?
	bsf	SDAo		; nein, 1
	nop

	bsf	SCL		; Taht high
WrI2cW2
	btfss	SCLi
	goto	WrI2cW2

	bcf	SCL		; Takt low
	decfsz	count,f		; 8 Bits raus?
	goto	WrI2cW1		; nein
	return			; ja
			


;liest das Byte aus I2C nach W
	; takt ist unten
	; daten sind unten
RdI2cW
	clrf	buf
	movlw	8
	movwf	count
	bsf	SDAo		;failsave
RdI2cW1
	nop
	clrc
	btfsc	SDAi
	setc
	rlf	buf,f

	bsf	SCL		; Takt high
RdI2cW2
	btfss	SCLi
	goto	RdI2cW2

	bcf	SCL		; Takt low
	decfsz	count,f		; 8 Bits drinn?
	goto	RdI2cW1		; nein
	movfw	buf		; ja fertig
	return


;*****************************************************************	
;Zeitverzögerung um loops * 1 ms
; 10 MHz externer Takt bedeutet 2,5 MHz interner Takt
; also dauert 1 ms genau 2500 Befehle
; 250 Schleifen a 10 Befehle sind 2500 Befehle = 1 ms

WAIT
top     movlw   .250           ; timing adjustment variable (1ms)
        movwf   loops2
top2    nop                    ; sit and wait
        nop
        nop
        nop
	nop
        nop
        nop
        decfsz  loops2, F      ; inner loops complete?
        goto    top2           ; no, go again
                               ;
        decfsz  loops, F       ; outer loops complete?
        goto    top            ; no, go again
        retlw   0              ; yes, return from subWAIT








Hex2Dez8			; 8-bit (f1) in 3-stellen BCD
	movlw	0x64
	movwf	xw0
	call	Hex2Dez1	; 100er
	movfw	HdX
	movwf	HdH

	movlw	0x0A
	movwf	xw0
	call	Hex2Dez1	; 10er
	movfw	HdX
	movwf	HdZ

	movfw	f0
	movwf	HdE
	return


Hex2Dez1
	clrf	HdX
	decf	HdX, f
HdLoop
	incf	HdX, f

	movf    xw0, w		; f0=f0-xw0
	subwf   f0, f

	btfsc	STATUS, C	;Überlauf
	goto	HdLoop		;Stelle 1 mehr

	movf	xw0,W		; low byte
	addwf	f0,F 		; low byte add

	return


ISR	
		Movwf	W_temp
		Movlw	.96
		movwf	TMR0

		bcf	INTCON,T0IF
		

		bcf	PORTA,6
		bcf	PORTA,7
		movf	One,f
		btfsc	STATUS,Z
 		goto	Msdon
	
Lsdon
		bcf	One,0
		movlw high Bcdto7seg

		movwf	PCLATH
		 
        
		movf	dig3,w
		call	Bcdto7seg
			
		movwf	PORTB
		banksel	PORTA

		bsf	PORTA,7
	

		movf	W_temp,w
	
		retfie
Msdon

		bsf	One,0
		movlw high Bcdto7seg
		movwf	PCLATH

		
		
		movf	dig2,w
		call	Bcdto7seg

	
		movwf	PORTB
		banksel	PORTA
		bsf	PORTA,6
		
	
		movf	W_temp,w
		retfie

		org	0x300

Bcdto7seg

		addwf	PCL,f
				RETLW   b'11000000'		;0
            	RETLW   b'11111001'		;1
            	RETLW   b'10100100'		;2
            	RETLW   b'10110000'		;3
            	RETLW   b'10011001'		;4
            	RETLW   b'10010010'		;5
            	RETLW   b'10000010'		;6
            	RETLW   b'11111000'		;7
            	RETLW   b'10000000'		;8
            	RETLW   b'10010000'		;9
            	RETLW   b'11111111'		;blank
		End
