Mit nur 2 CALL befehle habe ich ein lernprogramm geschrieben.
Ich hoffe es hilft auch jemanden.
lg
Schlapfi
Code:;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Dateiname: Eieruhr ( Lernprogramm ) ; LED mit 3 x 7 Segment Multiplex betrieb ; Autor: Schlapfi ; Datum: Dez. 2013 ; PIC 16F631 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Funktionsbeschreibung des Programms: ; Prozessor-Takt 8 MHz Intern ; Mit PAUSE wird gewartet bis Timer-0 überleuft, über ZAEHL wird diese Zeit erweitert ; auf 1,000999 Sec.( für Eierkochen ausreichend, Fehlmessung 0,6 Sec. in 10 Min.) ; und "einer" wird mit diesem Takt hochgezählt. ; Anoden sind RB6 = hundert , RB5 = zehner, RB4 = einer ; einer = Sekunde-einer ; zehner = Sekunde-zehner ; hundert = Minute ; 7-Segment mit gemeinsamer Anode. ; Katoden ausgänge sind: PORT-C ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ list p=16F631 #include <p16f631.inc> __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _CPD_OFF ERRORLEVEL -302 ; Unterdrücken BANK SELECTION MESSAGES ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Deklaration der Variablen und Konstanten ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ einer EQU H'0022' ; Variable für die Einerstelle der Zahl zehner EQU H'0023' ; Variable für die Zehnerstelle der Zahl hundert EQU H'0024' ; Variable für die Hunderterstelle der Zahl ZAEHL EQU H'0025' ; Zähler für Sekunde ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Masken für das Einschalten der LEDs ; Masken sind wegen besserer beschaltung so gwählt ; und können leicht verändert werden. ; gfedcba #define D0 B'01000000' ; 0 #define D1 B'01111001' ; 1 #define D2 B'00100100' ; 2 #define D3 B'00110000' ; 3 #define D4 B'00011001' ; 4 #define D5 B'00010010' ; 5 #define D6 B'00000010' ; 6 #define D7 B'01111000' ; 7 #define D8 B'00000000' ; 8 #define D9 B'00010000' ; 9 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Startadresse des PIC-Controllers nach einem RESET oder Neustart ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ org 0x000 ; Startadresse des PICs ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; PIC Einstellungen ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; START bsf STATUS,RP0 ; Auswahl Bank 1 movlw B'01110000' ; Int-Oszilator 8 MHz, movwf OSCCON movlw b'00000100' ; TMR0 vorbereiten (intern, Vorteiler 32,) movwf OPTION_REG movlw b'00000000' ; TRISC = Ausgang movwf TRISC ; damit ist Port C = Ausgang movwf TRISB ; und Port B movwf TRISA ; und Port A bcf STATUS,RP0 ; Auswahl Bank 0 ; Interrupt movlw b'10000000' ; alle movwf INTCON ; Interrupts freigeben movlw .250 movwf ZAEHL clrf PORTA ; Löschen aller Ausgänge clrf PORTB clrf PORTC ; Löschen aller Ausgänge clrf einer clrf zehner ; Löschen clrf hundert ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Hauptprogramm: LED Anzeigen 3x7 Segmente ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ LEDAnz clrf PORTB ; Löschen aller Ausgänge clrf PORTC ; führende null unterdrücken. ZEROPIT abfragen ob gesetzt. movlw d'0' ; 0 nach " W " laden addwf hundert,w ; inhalt von hundert dazu addieren, schreibe in " W " btfsc STATUS,Z ; ist nicht null ? : überspringe nächste Zeile goto $+9 ; wenn null, 9 Zeilen nach unten movlw B'01000000' ; hunderter Katode movwf PORTB ; und an PORTB ausgeben movf hundert,w ; Laden der Variable "hundert" in das W-Register call LED ; Sprung zum Laden der LED-Variablen movwf PORTC ; und an PORTC ausgeben call PAUSE clrf PORTB ; Löschen aller Ausgänge clrf PORTC movlw B'00100000' movwf PORTB movf zehner,w ; Laden der Variablen "zehner" in das W-Register call LED ; Sprung zum Laden der LED-Variablen movwf PORTC call PAUSE clrf PORTB ; Löschen aller Ausgänge clrf PORTC movlw B'00010000' movwf PORTB movf einer,w ; Laden der Variablen "einer" in das W-Register call LED ; Sprung zum Laden der LED-Variablen movwf PORTC call PAUSE goto LEDAnz ; und wieder zu Anzeige ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Ab hier folgen die Unterprogramme ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; PAUSE: ; wartet bis Timer0 überleuft ( alle 4 mSec. ) und verringert ZAEHL bis null, ; 4 mSec ( Timer0 ) X 250 ( ZAEHL ) = Eine Sekunde ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ PAUSE btfss INTCON,T0IF ; Pause von 4 ms Dauer goto $-1 ; warten bis Interruptflag gesetzt ist movlw 06 ; Timer-0 auf 250 stellen movwf TMR0 ; W -> Timer-0 bcf INTCON,T0IF ; TMR0-Flag löschen decfsz ZAEHL ; ZAEHL minus 1 bis 0 return ; ZAEHL > 0 movlw .250 ; ZAEHL = 0 movwf ZAEHL ; und wird neu geladen ; erhöht "einer" um 1 und alle weiteren stellen bei überlauf incf einer,1 ; Erhöhen der Variablen "einer" um +1 movfw einer ; Laden der Variablen "einer" ins W-Register sublw D'10' ; 10 in W laden und abziehen. btfss STATUS,Z ; ergebnis = 0 : überspringe nächste Zeile return ; rechenergebnis nicht 0 = return ; Ja, dann incf zehner,1 ; Zählervariable für die zweite Stelle erhöhen clrf einer ; einer löschen movfw zehner ; Laden der Variablen "zehner" ins W-Register sublw D'6' ; Maximaler Zählwert erreicht? btfss STATUS,Z ; erreicht : überspringe nächste Zeile return ; nicht 0 = return ; Ja, dann incf hundert,1 ; Zhundert um 1 erhöhen clrf zehner ; zehner löschen movfw hundert ; Laden der Variablen "hundert" ins W-Register sublw D'10' ; Maximaler Zählwert erreicht? btfss STATUS,Z ; erreicht : überspringe nächste Zeile return ; nicht 0 = return clrf hundert ; Zählervariable löschen return ; Rücksprung ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ LED addwf PCL,1 retlw D0 retlw D1 retlw D2 retlw D3 retlw D4 retlw D5 retlw D6 retlw D7 retlw D8 retlw D9 END







Zitieren

Lesezeichen