hmm ich kann dir das nur für n PIC und LCD geben. aber im anschluss dran ist noch was fürs multiplexen:
Code:
list p=16f628
;**************************************************************
;*
;* Pinbelegung
;* ----------------------------------
;* PORTA: 0 -
;* 1 -
;* 2 -
;* 3 -
;* 4 -
;* 5 -
;* 6 -
;* 7 -
;*
;* PORTB: 0 > LCD Display E
;* 1 < Rücksetz_Taster für Uhrzeit
;* 2 > LCD Display RS
;* 3 > LCD Display R/W
;* 4 - LCD Display D4
;* 5 - LCD Display D5
;* 6 - LCD Display D6
;* 7 - LCD Display D7
;*
;**************************************************************
;
; sprut (zero) Bredendiek 02/2004 mod 06/2005
;
; Uhr mit LCD-Display
; Anzeige hh:mm:ss
; Takt : 32768Hz
;
;
;**************************************************************
; Includedatei für den 16F84 einbinden
#include <P16f628.INC>
ERRORLEVEL -302 ;SUPPRESS BANK SELECTION MESSAGES
; Configuration festlegen
; 32768Hz: Power on Timer, kein Watchdog, LP-Oscillator
__CONFIG _PWRTE_ON & _WDT_OFF & _LP_OSC & _BODEN_OFF & _LVP_OFF
;**************************************************************
; Konstanten
; Variablennamen vergeben
w_copy Equ 0x20 ; Backup für Akkuregister
s_copy Equ 0x21 ; Backup für Statusregister
Flags Equ 0x22
loops equ 0x23 ; timer für wait
LcdStatus equ 0x24 ;
LcdDaten equ 0x25 ;
ES equ 0x26 ; Einer Sekunden
ZS equ 0x27 ; Zehner Sekunden
EM equ 0x28 ; Einer Minuten
ZM equ 0x29 ; Zehner Minuten
EH equ 0x2A ; Einer Stunden
ZH equ 0x2B ; Zehner Stunden
; für LCD-Pins
#define LcdE PORTB,0 ; enable Lcd
#define LcdRw PORTB,3 ; read Lcd
#define LcdRs PORTB,2 ; Daten Lcd (nicht control)
#define LcdPort PORTB ; Datenbus des LCD (obere 4 Bit)
#define neu Flags,0
Ini_con Equ B'00000000' ; TMR0 -> Interupt disable
Ini_opt Equ B'00000010' ; pull-up
;**************************************************************
; los gehts mit dem Programm
org 0
goto Init
;**************************************************************
; die Interuptserviceroutine
org 4
intvec
movwf w_copy ; w retten
swapf STATUS, w ; STATUS retten
bcf STATUS, RP0 ; Bank 0
movwf s_copy ;
; Intrupt servic routine
Int_serv
bsf neu
incf ES, f ; 1 Sekunden erhöhen
movlw D'10'
subwf ES, w
btfss STATUS, Z
goto Int_end ; 1 Sekunden <> 10
clrf ES
incf ZS, f ; 10 Sekunden erhöhen
movlw D'6'
subwf ZS, w
btfss STATUS, Z
goto Int_end ; 10 Sekunden <> 6
clrf ZS
incf EM, f ; 1 Minuten erhöhen
movlw D'10'
subwf EM, w
btfss STATUS, Z
goto Int_end ; 1 Minuten <> 10
clrf EM
incf ZM, f ; 10 Minuten erhöhen
movlw D'6'
subwf ZM, w
btfss STATUS, Z
goto Int_end ; 10 Minuten <> 6
clrf ZM
incf EH, f ; 1 Stunden erhöhen
movlw D'10'
subwf EH, w
btfss STATUS, Z
goto Test24 ; 1 Stunden <> 10
clrf EH
incf ZH, f ; 10 Stunden erhöhen
goto Int_end
Test24
movlw D'2'
subwf ZH, w
btfss STATUS, Z
goto Int_end ; 10 Stunden <> 2
movlw D'4'
subwf EH, w
btfss STATUS, Z
goto Int_end ; 1 Stunden <> 4
clrf EH ; Mitternacht
clrf ZH
goto Int_end
Int_end
bcf INTCON, T0IF ; Interupt-Flag löschen
swapf s_copy, w ; STATUS zurück
movwf STATUS
swapf w_copy, f ; w zurück mit flags
swapf w_copy, w
retfie
;**************************************************************
; Port B auf Ausgabe stellen
Init bsf STATUS, RP0 ; Bank 1
movlw Ini_opt ; pull-up on
movwf OPTION_REG
movlw B'00000010' ; PortB alle outputs außer RB1
movwf TRISB
bcf STATUS, RP0 ; Bank 0
clrf PORTB
movlw Ini_con ; Interupt disable
movwf INTCON
;Display initialisieren
call InitLcd
clrf Flags
; Zeit 0 einstellen
call Zeit_Null
; 1 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
bcf STATUS, RP0 ; auf Bank 0 zurückschalten
clrf TMR0 ; ((32,768 kHz : 32 ): 256 = 1 Hz)
bsf INTCON, T0IE ; Timer0 interupt erlauben
bsf INTCON, GIE ; Interupt erlauben
loop
btfss PORTB,1
call Zeit_Null ; wenn Taste gedrückt, dann Zeit=0
btfss neu
goto loop ; eine Endlosschleife
; Kursor home
movlw B'10000000' ; 1. Zeile
call OutLcdControl
movfw ZH
iorlw '0' ;wandeln in ASCCI
call OutLcdDaten
movfw EH
iorlw '0' ;wandeln in ASCCI
call OutLcdDaten
movlw ':' ; Lücke
call OutLcdDaten
movfw ZM
iorlw '0' ;wandeln in ASCCI
call OutLcdDaten
movfw EM
iorlw '0' ;wandeln in ASCCI
call OutLcdDaten
movlw ':' ; Lücke
call OutLcdDaten
movfw ZS
iorlw '0' ;wandeln in ASCCI
call OutLcdDaten
movfw ES
iorlw '0' ;wandeln in ASCCI
call OutLcdDaten
bcf neu
goto loop ; eine Endlosschleife
Zeit_Null
clrf TMR0
bsf neu
clrf ES
clrf ZS
clrf EM
clrf ZM
clrf EH
clrf ZH
return
;*****************************************************
;+++LCD-Routinen**************************************
;*****************************************************
;LCD initialisieren
InitLcd
movlw D'255' ; 250 ms Pause nach dem Einschalten
movwf loops
call WAIT
movlw B'00110000' ; 1
movwf LcdPort
bsf LcdE
nop
bcf LcdE
movlw D'50' ; 50 ms Pause
movwf loops
call WAIT
movlw B'00110000' ; 2
call Control8Bit
movlw B'00110000' ; 3
call Control8Bit
movlw B'00100000' ; 4
call Control8Bit
movlw B'00000001' ; löschen und cusor home
call OutLcdControl
movlw B'00101000' ; 5 function set, 4-bit 2-zeilig, 5x7
call OutLcdControl
movlw B'00001000' ; 6 display off
call OutLcdControl
movlw B'00000110' ; 7 entry mode, increment, disable display-shift
call OutLcdControl
movlw B'00000011' ; 8 cursor home, cursor home
call OutLcdControl
movlw B'00001100' ; 9 display on, Kursor aus , Blinken aus
call OutLcdControl
return
;*****************************************************
; ein Steuerbyte 8-bittig übertragen
Control8Bit
movwf LcdPort
bsf LcdE
nop
bcf LcdE
movlw D'10'
movwf loops
call WAIT
return
;*****************************************************
; darauf warten, daß das Display bereit zur Datenannahme ist
LcdBusy
bsf STATUS, RP0 ; make Port B4..7 input
movlw B'11110000'
iorwf TRISB, f
bcf STATUS, RP0
BusyLoop
bcf LcdRs
bsf LcdRw ; Lesen
bsf LcdE
nop
movf LcdPort, w
movwf LcdStatus
bcf LcdE
nop
bsf LcdE ; Enable
nop
bcf LcdE
btfsc LcdStatus, 7 ; teste bit 7
goto BusyLoop
bcf LcdRw
bsf STATUS, RP0 ; make Port B4..7 output
movlw B'00001111'
andwf TRISB, f
bcf STATUS, RP0
return
;*****************************************************
; aus W ein Byte mit Steuerdaten zum Display übertragen
OutLcdControl
movwf LcdDaten
call LcdBusy
movf LcdDaten, w
andlw H'F0'
movwf LcdPort ; Hi-teil Daten schreiben
bsf LcdE
nop
bcf LcdE ; Disable LcdBus
swapf LcdDaten, w
andlw H'F0'
movwf LcdPort ; Lo-teil Daten schreiben
bsf LcdE
nop
bcf LcdE ; Disable LcdBus
return
;*****************************************************
; aus W ein Datenbyte zum Display übertragen
OutLcdDaten
movwf LcdDaten
call LcdBusy
movf LcdDaten, w
andlw H'F0'
movwf LcdPort ; Hi-teil Daten schreiben
bsf LcdRs ; Daten
bsf LcdE ; Enable LcdBus
nop
bcf LcdE ; Disable LcdBus
swapf LcdDaten, w
andlw H'F0'
movwf LcdPort ; Lo-teil Daten schreiben
bsf LcdRs ; Daten
bsf LcdE
nop
bcf LcdE ; Disable LcdBus
bcf LcdRs ;
return
;*****************************************************
;Zeitverzögerung um loops * 1 ms
; 32768Hz externer Takt bedeutet ca 8 kHz interner Takt
; also dauert 1 ms etwa 8 Befehle
WAIT
top
nop
nop
nop
nop
nop
decfsz loops, F ; outer loops complete?
goto top ; no, go again
retlw 0 ; yes, return from WAIT
;*****************************************************
end
hier multiplexen:
Code:
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
ich bezweifle, dasses hilfreich ist aber wie du meinst
Lesezeichen