	list p=16f84
;**************************************************************
;*
;* Pinbelegung
;*	----------------------------------	
;*	PORTA: 	0 Ziffer	-----------------------------------------------------+
;*		1 Ziffer	-------------------------------------+               I
;*		2 Ziffer	---------------------+               I               I
;*		3 Ziffer	-----+               I               I               I
;*		4 Eingang	     I               I               I               I  
;*	PORTB:	0 Segment B	   AAAAA	   AAAAA	   AAAAA	   AAAAA
;*		1 Segment F	  F     B	  F     B	  F     B	  F     B
;*		2 Segment A	  F     B	  F     B	  F     B	  F     B
;*		3 Segment G	   GGGGG  	   GGGGG  	   GGGGG  	   GGGGG  
;*		4 Segment H	  E     C	  E     C	  E     C	  E     C
;*		5 Segment C	  E     C	  E     C	  E     C	  E     C
;*		6 Segment E	   DDDDD  HH	   DDDDD  HH	   DDDDD  HH	   DDDDD  HH
;*		7 Segment D    
;*
;**************************************************************
;
; sprut (zero) Bredendiek 06/2000 (mod. 15.01.2002)
;
; 4-stellige LED-Anzeige
;
; Tektquelle: 4 MHz
; es wird probehalber die Zahl "1234" angezeigt
;
;**************************************************************
; Includedatei für den 16F84 einbinden

	#include <P16f84.INC>


; Configuration festlegen
; bis 4 MHz: Power on Timer, kein Watchdog, XT-Oscillator

	__CONFIG	_PWRTE_ON & _WDT_OFF & _XT_OSC

;**************************************************************

; Variablennamen vergeben

w_copy	Equ	0x20		; Backup für Akkuregister
s_copy	Equ	0x21		; Backup für Statusregister
Ziffer1	Equ	0x22		; Wert des LSD
Ziffer2	Equ	0x23		; Wert der zweitkleinsten Stelle
Ziffer3	Equ	0x24		; Wert der zweitgrößten Stelle
Ziffer4	Equ	0x25		; Wert des MSD
Digit	Equ	0x26		; Ziffernzähler
ar	Equ	0x27

;**************************************************************
; los gehts mit dem Programm

	org 	0
	goto	Init	

;**************************************************************
; die Interuptserviceroutine

	org 	4 	
intvec	bcf	INTCON, GIE	; disable Interupt 

	movwf	w_copy		; w retten
	swapf	STATUS, w 	; STATUS retten
	movwf	s_copy		;

	movlw	D'131'		; 256-125=131 ((1MHz : 32 ): 125 = 250 Hz)
	movwf	TMR0

; Intrupt servic routine
Int_serv 

	bsf	PORTA, 0	; Ziffer1 aus
	bsf	PORTA, 1	; Ziffer2 aus
	bsf	PORTA, 2	; Ziffer3 aus
	bsf	PORTA, 3	; Ziffer4 aus

	decf	Digit,f		; Ziffernzähler verringern
;Digit=4: anzeigen Ziffer 4
;Digit=3: anzeigen Ziffer 3
;Digit=2: anzeigen Ziffer 2
;Digit=1: anzeigen Ziffer 1
;Digit=0: andere Aktionen, keine Anzeige

	btfsc	STATUS, Z
	goto	Int_0		; Z-Flag=1 ergo Digit=0
	movfw	Digit
	movwf	ar
	decf	ar, f
	btfsc	STATUS, Z
	goto	Int_1		; Digit=1
	decf	ar, f
	btfsc	STATUS, Z
	goto	Int_2		; Digit=2
	decf	ar, f
	btfsc	STATUS, Z
	goto	Int_3		; Digit=3
	goto	Int_4		; Digit=4

Int_0
	movlw	5
	movwf	Digit
	goto	Int_end

Int_1
	movfw	Ziffer1		; Wert der 1. Ziffer
	call	Segmente
	movwf	PORTB		; Segmente einschalten
	bcf	PORTA, 0	; 1. Ziffer einschalten
	goto	Int_end

Int_2
	movfw	Ziffer2		; Wert der 2. Ziffer
	call	Segmente
	movwf	PORTB		; Segmente einschalten
	bcf	PORTA, 1	; 2. Ziffer einschalten
	goto	Int_end

Int_3
	movfw	Ziffer3		; Wert der 3. Ziffer
	call	Segmente
	movwf	PORTB		; Segmente einschalten
	bcf	PORTA, 2	; 3. Ziffer einschalten
	goto	Int_end

Int_4
	movfw	Ziffer4		; Wert der 4. Ziffer
	call	Segmente
	movwf	PORTB		; Segmente einschalten
	bcf	PORTA, 3	; 4. Ziffer einschalten
	goto	Int_end


Int_end	swapf	s_copy, w	; STATUS zurück
	movwf	STATUS 
	swapf	w_copy, f	; w zurück mit flags
	swapf	w_copy, w

	bcf	INTCON, T0IF	; Interupt-Flag löschen
	bsf	INTCON, GIE	; enable Interupt

	retfie

; 7-Segment-Tabelle
Segmente
	addwf	PCL, f
	retlw	B'00011000'	; 0
	retlw	B'11011110'	; 1
	retlw	B'00110010'	; 2
	retlw	B'01010010'	; 3
	retlw	B'11010100'	; 4
	retlw	B'01010001'	; 5
	retlw	B'00010001'	; 6
	retlw	B'11011010'	; 7
	retlw	B'00010000'	; 8
	retlw	B'01010000'	; 9

;**************************************************************

; Port A/B auf Ausgabe stellen

Init
	movlw	B'11111111'
	movwf	PORTA
	movwf	PORTB		; Anzeige dunkel
	bsf     STATUS, RP0	; auf Bank 1 umschalten
	movlw	B'11110000'	; PortA RA0-RA3 output
	movwf	TRISA
	movlw	B'00000000'	; PortB alle output
	movwf	TRISB
	bcf     STATUS, RP0	; auf Bank 0 zurückschalten


; eine beliebige Zahl einstellen (hier: 1234)
	movlw	4
	movwf	Ziffer1
	movlw	3
	movwf	Ziffer2
	movlw	2
	movwf	Ziffer3
	movlw	1
	movwf	Ziffer4

	movlw	5
	movwf	Digit

; 250 Hz-Timer-Interupt einstellen
	bsf     STATUS, RP0	; auf Bank 1 umschalten
	movlw	B'10000100'	; internen Takt zählen, Vorteiler zum Timer0, 32:1
	movwf	OPTION_REG
	movlw	D'131'		; 256-125=131 ((1MHz : 32 ): 125 = 250 Hz)
	bcf     STATUS, RP0	; auf Bank 0 zurückschalten
	movwf	TMR0
	bsf	INTCON, T0IE	; Timer0 interupt erlauben
	bsf	INTCON, GIE	; Interupt erlauben

loop	goto	loop		; eine Endlosschleife

;**********************************************************


	end



