PICVB
15.10.2007, 18:23
Hallo Leute,
muss man denn immer Fehler posten? Ich kann doch auch ein Erfolg hier rein Stellen oder?
Ich habe mit einem PIC eine Digitaluhr Programmiert. Sie funktioniert auch.
;************************************************* ************************************************** ***********************
; Einstellbare Digitaluhr
; Autor: Carsten Keller
; 35325 Mücke Sellnrod
;************************************************* ************************************************** ***********************
list p=16F88
#include <p16f88.inc>
__CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_ON & _MCLR_OFF & _PWRTE_OFF & _WDT_OFF & _HS_OSC
__CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF
ERRORLEVEL -302 ; Unterdrücken BANK SELECTION MESSAGES
org 0x000 ; Startadresse des PICs
goto init ; Springe zu init
org 0x004 ; Interruptstartadresse
movlw 0A0 ; Laden des Wertes A0 nach INTCON, bewirkt die Freigabe für Interrupts, Timer0 Intterupt freigegeben,
movwf INTCON ; EEPROM schreib Interrupt gesperrt, Sperren RB0 Interrupt, Sperren RB Port Interrupt un löschen der Interrupt Flag bits
movlw 0x6 ; TMR0 mit dem Wert 6 laden
movwf TMR0 ; Timer0 läuft jetzt
decfsz millisekunden,1 ; Register millisekunden um 1 runterzählen und bei 0 nächsten Befehl überspringen
goto endin
movlw 0x10 ; Register millisekunden und Register sekunden mit dem Wert 65 laden
movwf millisekunden ;
goto weiter ;
neu ; Wenn Register millisekunden 0 und Register sekunden nicht 0 wird hier millisekunden neu mit 65 geladen
movlw 0x10 ;
movwf millisekunden ;
goto endin ;
weiter ; Register sekunden und milisekunden sind 0. Damit ist eine Sekunde um
call zählen ;
movfw nullzähler ;
sublw 0x18 ; Subtrahiere W mit 18 um zu überprüfen ob 24 Stunden um sind
btfss STATUS,Z ; Überspringe den nächsten Befehl wenn Z Flag nicht gesetzt ist
goto endin ;
clrf sekunden1 ;
clrf sekunden10 ;
clrf minuten1 ;
clrf minuten10 ;
clrf stunden1 ;
clrf stunden10 ;
clrf nullzähler ;
endin ; Ende des Interrupts
clrw ; Lösche Register W um Fehler zuvermeiden
retfie ; Rücksprung zu der Adresse wo das Hauptprogramm unterprochen wurde
;************************************************* ************************************************** ***********************
; Reisterzuweisung
cblock 0x20
sekunden1
sekunden10
minuten1
minuten10
stunden1
stunden10
millisekunden
sekunden
nullzähler
endc
; Bitzuweisung
minein equ 0
minzehn equ 1
stunein equ 2
stunzehn equ 3
;************************************************* ************************************************** ***********************
#include <7-Segment-Tabelle.inc> ; Einbinden der 7-Segment-Tabelle
#include <Pause.inc>
;************************************************* ************************************************** ***********************
; Initialiesierung
init
clrf sekunden1 ; Alle Register auf 0 setzen
clrf sekunden10 ;
clrf minuten1 ;
clrf minuten10 ;
clrf stunden1 ;
clrf stunden10 ;
clrf nullzähler ;
bsf STATUS, RP0 ; Auswahl Bank 1
movlw 0x30
movwf PORTA ; Setzen des PORTA als Ausgang
movlw 0x1
movwf PORTB ; Setzen des PORTB als Ausgang
movlw 0x97 ; Vorteiler für Timer0, Vorteiler ist 1:256
movwf OPTION_REG ;
clrf ANSEL
movlw 0x7
movwf CMCON
bcf STATUS, RP0 ; Auswahl Bank 0
movlw 0xA0 ; Laden des Wertes A0 nach INTCON, bewirkt die Freigabe für Interrupts, Timer0 Intterupt freigegeben.
movwf INTCON ; Sperren der anderen Interrupts unt löschen der Interrupt Flags.
movlw 0x6 ; Lade 6 nach TMR0
movwf TMR0 ; Timer0 läuft jetzt
movlw 0x10 ; Register millisekunden und Register sekunden mit dem Wert 64 lade.
movwf millisekunden
;************************************************* ************************************************** ***********************
; Hauptprogramm Das Hauptprogramm besteht nur aus der Ausgabe der Aktuellen Werte. Alles Andere wird nach einem Interrupt gemacht
; Ausgabe
Haupt
call Ausgabe
goto $-1
goto $-2
Ausgabe
btfss PORTB,0
call Stellen
A1
clrf PORTA
movfw minuten1
call tab
movwf PORTB
bsf PORTA,minein
nop
nop
clrf PORTA
movfw minuten10
call tab
movwf PORTB
bsf PORTA,minzehn
nop
nop
clrf PORTA
movfw stunden1
call tab
movwf PORTB
bsf PORTA,stunein
nop
nop
clrf PORTA
movfw stunden10
call tab
movwf PORTB
bsf PORTA,stunzehn
nop
nop
clrf PORTA
return
;************************************************* ************************************************** ***********************
; Unterprogramm zum Zählen
zählen
incf sekunden1,1
movlw 0xA
subwf sekunden1,W
btfss STATUS,Z
return
clrf sekunden1
incf sekunden10,1
movlw 0x6
subwf sekunden10,W
btfss STATUS,Z
return
clrf sekunden10
Z1 incf minuten1,1
movlw 0xA
subwf minuten1,W
btfss STATUS,Z
return
clrf minuten1
incf minuten10,1
movlw 0x6
subwf minuten10,W
btfss STATUS,Z
return
clrf minuten10
incf nullzähler,1
Z2 incf stunden1,1
movlw 0xA
subwf stunden1,W
btfss STATUS,Z
return
clrf stunden1
incf stunden10,1
return
;************************************************* ************************************************** ***********************
; Unterprogramm zum Stellen der Uhrzeit
Stellen
clrf INTCON
call A1
btfss PORTA,4
goto p1
btfss PORTA,5
goto p2
btfsc PORTB,0
goto ende
goto Stellen
p1
call Entprellen
btfss PORTA,4
goto $-1
call Z1
goto Stellen
p2
call Entprellen
btfss PORTA,5
goto $-1
call Z2
goto Stellen
ende
call Entprellen
movlw 0x6 ; Lade 6 nach TMR0
movwf TMR0 ; Timer0 läuft jetzt
movlw 0xA0
movwf INTCON
return
end ; Pogrammende
Das ist der vollständige Code. Schaltplan habe ich keinen gezeichnet. Kommt vllt. noch.
;************************************************* ************************************************** *********************************
; Tabelle der Siebensegmentcodes von 0 bis 9 an RB1...RB7
;************************************************* ************************************************** *********************************
tab addwf PCL,1 ; Addiert W und PCL. Ergebnis steht in PCL,was Sprung zum entsprechenden Ausgabewert ergibt
retlw 0x7E ; 0
retlw 0xC ; 1
retlw 0xB6 ; 2
retlw 0x9E ; 3
retlw 0xCC ; 4
retlw 0xDA ; 5
retlw 0xFA ; 6
retlw 0xE ; 7
retlw 0xFE ; 8
retlw 0xDE ; 9
Das ist die Include Datei 7-Segment-Tabelle.inc
cblock
Pause
Pause1
Pause2
endc
Pause1ms ; Pausenzeit 1ms bei 4Mhz
movlw D'200'
movwf Pause
loop nop
nop
decfsz Pause,1
goto loop
return
Pause250ms ; Pausenzeit 250ms
movlw D'250'
movwf Pause1
loop1 call Pause1ms
decfsz Pause1,1
goto loop1
return
Entprellen ; Pausenzeit 30ms
movlw D'30'
movwf Pause2
loop2 call Pause1ms
decfsz Pause2,1
goto loop2
return
Das ist die Include Datei Pause.inc
Gruß Carsten[/code]
muss man denn immer Fehler posten? Ich kann doch auch ein Erfolg hier rein Stellen oder?
Ich habe mit einem PIC eine Digitaluhr Programmiert. Sie funktioniert auch.
;************************************************* ************************************************** ***********************
; Einstellbare Digitaluhr
; Autor: Carsten Keller
; 35325 Mücke Sellnrod
;************************************************* ************************************************** ***********************
list p=16F88
#include <p16f88.inc>
__CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_ON & _MCLR_OFF & _PWRTE_OFF & _WDT_OFF & _HS_OSC
__CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF
ERRORLEVEL -302 ; Unterdrücken BANK SELECTION MESSAGES
org 0x000 ; Startadresse des PICs
goto init ; Springe zu init
org 0x004 ; Interruptstartadresse
movlw 0A0 ; Laden des Wertes A0 nach INTCON, bewirkt die Freigabe für Interrupts, Timer0 Intterupt freigegeben,
movwf INTCON ; EEPROM schreib Interrupt gesperrt, Sperren RB0 Interrupt, Sperren RB Port Interrupt un löschen der Interrupt Flag bits
movlw 0x6 ; TMR0 mit dem Wert 6 laden
movwf TMR0 ; Timer0 läuft jetzt
decfsz millisekunden,1 ; Register millisekunden um 1 runterzählen und bei 0 nächsten Befehl überspringen
goto endin
movlw 0x10 ; Register millisekunden und Register sekunden mit dem Wert 65 laden
movwf millisekunden ;
goto weiter ;
neu ; Wenn Register millisekunden 0 und Register sekunden nicht 0 wird hier millisekunden neu mit 65 geladen
movlw 0x10 ;
movwf millisekunden ;
goto endin ;
weiter ; Register sekunden und milisekunden sind 0. Damit ist eine Sekunde um
call zählen ;
movfw nullzähler ;
sublw 0x18 ; Subtrahiere W mit 18 um zu überprüfen ob 24 Stunden um sind
btfss STATUS,Z ; Überspringe den nächsten Befehl wenn Z Flag nicht gesetzt ist
goto endin ;
clrf sekunden1 ;
clrf sekunden10 ;
clrf minuten1 ;
clrf minuten10 ;
clrf stunden1 ;
clrf stunden10 ;
clrf nullzähler ;
endin ; Ende des Interrupts
clrw ; Lösche Register W um Fehler zuvermeiden
retfie ; Rücksprung zu der Adresse wo das Hauptprogramm unterprochen wurde
;************************************************* ************************************************** ***********************
; Reisterzuweisung
cblock 0x20
sekunden1
sekunden10
minuten1
minuten10
stunden1
stunden10
millisekunden
sekunden
nullzähler
endc
; Bitzuweisung
minein equ 0
minzehn equ 1
stunein equ 2
stunzehn equ 3
;************************************************* ************************************************** ***********************
#include <7-Segment-Tabelle.inc> ; Einbinden der 7-Segment-Tabelle
#include <Pause.inc>
;************************************************* ************************************************** ***********************
; Initialiesierung
init
clrf sekunden1 ; Alle Register auf 0 setzen
clrf sekunden10 ;
clrf minuten1 ;
clrf minuten10 ;
clrf stunden1 ;
clrf stunden10 ;
clrf nullzähler ;
bsf STATUS, RP0 ; Auswahl Bank 1
movlw 0x30
movwf PORTA ; Setzen des PORTA als Ausgang
movlw 0x1
movwf PORTB ; Setzen des PORTB als Ausgang
movlw 0x97 ; Vorteiler für Timer0, Vorteiler ist 1:256
movwf OPTION_REG ;
clrf ANSEL
movlw 0x7
movwf CMCON
bcf STATUS, RP0 ; Auswahl Bank 0
movlw 0xA0 ; Laden des Wertes A0 nach INTCON, bewirkt die Freigabe für Interrupts, Timer0 Intterupt freigegeben.
movwf INTCON ; Sperren der anderen Interrupts unt löschen der Interrupt Flags.
movlw 0x6 ; Lade 6 nach TMR0
movwf TMR0 ; Timer0 läuft jetzt
movlw 0x10 ; Register millisekunden und Register sekunden mit dem Wert 64 lade.
movwf millisekunden
;************************************************* ************************************************** ***********************
; Hauptprogramm Das Hauptprogramm besteht nur aus der Ausgabe der Aktuellen Werte. Alles Andere wird nach einem Interrupt gemacht
; Ausgabe
Haupt
call Ausgabe
goto $-1
goto $-2
Ausgabe
btfss PORTB,0
call Stellen
A1
clrf PORTA
movfw minuten1
call tab
movwf PORTB
bsf PORTA,minein
nop
nop
clrf PORTA
movfw minuten10
call tab
movwf PORTB
bsf PORTA,minzehn
nop
nop
clrf PORTA
movfw stunden1
call tab
movwf PORTB
bsf PORTA,stunein
nop
nop
clrf PORTA
movfw stunden10
call tab
movwf PORTB
bsf PORTA,stunzehn
nop
nop
clrf PORTA
return
;************************************************* ************************************************** ***********************
; Unterprogramm zum Zählen
zählen
incf sekunden1,1
movlw 0xA
subwf sekunden1,W
btfss STATUS,Z
return
clrf sekunden1
incf sekunden10,1
movlw 0x6
subwf sekunden10,W
btfss STATUS,Z
return
clrf sekunden10
Z1 incf minuten1,1
movlw 0xA
subwf minuten1,W
btfss STATUS,Z
return
clrf minuten1
incf minuten10,1
movlw 0x6
subwf minuten10,W
btfss STATUS,Z
return
clrf minuten10
incf nullzähler,1
Z2 incf stunden1,1
movlw 0xA
subwf stunden1,W
btfss STATUS,Z
return
clrf stunden1
incf stunden10,1
return
;************************************************* ************************************************** ***********************
; Unterprogramm zum Stellen der Uhrzeit
Stellen
clrf INTCON
call A1
btfss PORTA,4
goto p1
btfss PORTA,5
goto p2
btfsc PORTB,0
goto ende
goto Stellen
p1
call Entprellen
btfss PORTA,4
goto $-1
call Z1
goto Stellen
p2
call Entprellen
btfss PORTA,5
goto $-1
call Z2
goto Stellen
ende
call Entprellen
movlw 0x6 ; Lade 6 nach TMR0
movwf TMR0 ; Timer0 läuft jetzt
movlw 0xA0
movwf INTCON
return
end ; Pogrammende
Das ist der vollständige Code. Schaltplan habe ich keinen gezeichnet. Kommt vllt. noch.
;************************************************* ************************************************** *********************************
; Tabelle der Siebensegmentcodes von 0 bis 9 an RB1...RB7
;************************************************* ************************************************** *********************************
tab addwf PCL,1 ; Addiert W und PCL. Ergebnis steht in PCL,was Sprung zum entsprechenden Ausgabewert ergibt
retlw 0x7E ; 0
retlw 0xC ; 1
retlw 0xB6 ; 2
retlw 0x9E ; 3
retlw 0xCC ; 4
retlw 0xDA ; 5
retlw 0xFA ; 6
retlw 0xE ; 7
retlw 0xFE ; 8
retlw 0xDE ; 9
Das ist die Include Datei 7-Segment-Tabelle.inc
cblock
Pause
Pause1
Pause2
endc
Pause1ms ; Pausenzeit 1ms bei 4Mhz
movlw D'200'
movwf Pause
loop nop
nop
decfsz Pause,1
goto loop
return
Pause250ms ; Pausenzeit 250ms
movlw D'250'
movwf Pause1
loop1 call Pause1ms
decfsz Pause1,1
goto loop1
return
Entprellen ; Pausenzeit 30ms
movlw D'30'
movwf Pause2
loop2 call Pause1ms
decfsz Pause2,1
goto loop2
return
Das ist die Include Datei Pause.inc
Gruß Carsten[/code]