|
Bitte beachte die Copyrighthinweise.
PIC 16C84 (2)
1 Aufgabenstellung
· Weiterprogrammierung eines Programms zur Realisierung eines Zähler mit vier 7-Segment LEDs.
2 Allgemeines
2.1 Schaltung
Folgende Schaltung war bereits aufgebaut:
Dieser Schaltplan wurde mit der Realität verglichen. Dabei wurde festgestellt, dass in der Zählerleitung vor PA4 (Pin3) ein zusätzlicher Widerstand eingebaut war.
Die Betriebsspannung wurde mit dem Multimeter P1 auf 5V eingestellt.
Funktion der Schaltung: Nur wenn an den entsprechenden Leitungen an PORTB und an PORTA 0 bis 3 eine Eins anliegt, leuchtet das entsprechende LED-Segment. Mittels eines Timerinterrupts werden die Anzeigen multiplext. Nach jeder Änderung soll der Zählerstand in EEPROM gespeichert und nach einem Reset wieder ausgelesen werden.
2.2 PIC-Programmierung
Vorgangsweise bei der Programmierung:
· Übersetzen
des Quelltexts mit MPASM (Prozessor 16C84, Hextype INHX8M). Beim Übersetzen
des Programms wurde bei allen Zugriffen auf die Bank 1 (Bankzugriff mit
Adressen ab 80h) eine Message ausgegeben, dass nur die unteren
Bits berücksichtigt werden (das höchstwertige Bit muss durch die
Bankumschaltung richtig eingestellt sein):
Message[302]: Argument out of range. Least significant bits used.
· Die Programmierung erfolgte mittels eines Adapters, der an der 2. seriellen Schnittstelle eines PCs angeschlossen wurde. Hierzu musste der Treiber COM84.EXE COM2 geladen werden. Danach wurde mittels des Programms PIP-02.EXE der PIC programmiert. Hierzu musste zuerst (!) das Device 16C84 eingestellt und erst danach die .HEX Datei geladen werden. Danach wurde das Programm in den PIC übertragen (FUSE-Settings: Oszillator auf XT, WatchDogTimer/PwUpTimer/CodeProtect auf OFF).
2.3 Programme
2.3.1 Hardwaretest mit bestehendem Programm (ohne EEPROM)
Zuerst wurde das bereits vorhandene, funktionierende Programm (jedoch noch ohne EEPROM-Steuerung) getestet.
Mit der Zähltaste konnte der Zähler um 1 erhöht, mit dem Resettaster auf 0000 zurückgesetzt werden.
Am externen Zähleingang konnte mittels des Funktionsgenerators G1 ein Zählsignal eingespeist werden.
Somit war gleichzeitig die Funktionstüchtigkeit der Hardware überprüft worden.
2.3.2 Zähler mit EEPROM lesen
Interruptroutine
Multiplexen
Hauptprogramm
RS7SEG5.ASM:
Gegenüber dem Programm aus 2.3.1 (rs7seg4.asm) wurden die im Quelltext kursiv gedruckten Zeilen geändert. Anstelle der Initialisierung des Zählers mit 0000 wurden somit die Werte aus dem EEPROM geladen.
;*********************************************************************
; Editor: Florian Rosenauer @ HTBLA Karlstein, Austria-3830 Waidhofen
; Datum: 21/Nov/1997 Klasse/Gruppe/Kat.Nr : IV-EA/-/--
;*********************************************************************
; Sprache : ASM fr PIC16C84
; Programm Nr. : Labor PIC2 7-Seg. Zaehler
; Version : 0.51
; Kurzbeschreibung : 7seg-Zaehler mit EEPROM lesen, geht
; PA0 7-Segmentstelle 1
; PA1 7-Segmentstelle 2
; PA2 7-Segmentstelle 3
; PA3 7-Segmentstelle 4
; PA4 Zaehleingang
; PB1-PB7 7-Segment-Balken
;*********************************************************************
List p=16C84
include "16C84.inc"
BYTE1 equ 0x0C ; Zaehlerstand fuer Betrieb
BYTE2 equ 0x0D
BYTE3 equ 0x0E
BYTE4 equ 0x0F
EEBYTE1 equ 0x00 ; Zaehlerstand EEPROM Speicheradresse
EEBYTE2 equ 0x01
EEBYTE3 equ 0x02
EEBYTE4 equ 0x03
HILFE equ 0x10
X equ 0x00
ZAEHL equ 0x11
ZAHL equ 0x12
org 0x00
goto init
org 0x04
goto Ausgabe
org 0x08
init BCF STATUS,RP0 ;Bank 0
CLRF PORTB ;PORTB löschen
BSF STATUS,RP0 ;Bank 1
MOVLW 0x00 ;
MOVWF TRISB ;PB0 - PB7 auf Eingabe setzen
MOVLW 0x10 ;
MOVWF TRISA ;PA0 - PA3 auf Ausgabe und PA4 auf Eingabe
BCF STATUS,RP0
CLRF PORTA
BSF STATUS,RP0 ;Bank 1
MOVLW 0x82 ;Prescaler auf 488Hz setzen
MOVWF OPTION_REG ;mit 1X0X0010 -> 82HEX
MOVLW 0x01 ;ZAEHL auf
MOVWF ZAEHL ;00000001 setzen
; MOVLW 0x00
; MOVWF BYTE1
; MOVWF BYTE2
; MOVWF BYTE3
; MOVWF BYTE4
; BCF HILFE,X
; -- Zaehlerstand aus EEPROM laden --
; Vorher im Programmer EEPROM loeschen!
BCF STATUS,RP0 ;Bank 0
MOVLW EEBYTE1
MOVWF EEADR ;EEPROM-Adresse mit 00 festlegen
BSF STATUS,RP0 ;Bank 1
BSF EECON1,RD ;Lesevorgang aktivieren
BCF STATUS,RP0 ;Bank 0
MOVF EEDATA,W ;EEPROM-Daten in Akku schreiben
MOVWF BYTE1 ;Daten auf BYTE1 schreiben
MOVLW EEBYTE2
MOVWF EEADR ;EEPROM-Adresse mit 01 festlegen
BSF STATUS,RP0 ;Bank 1
BSF EECON1,RD ;Lesevorgang aktivieren
BCF STATUS,RP0 ;Bank 0
MOVF EEDATA,W ;EEPROM-Daten in Akku schreiben
MOVWF BYTE2 ;Daten auf BYTE2 schreiben
MOVLW EEBYTE3
MOVWF EEADR ;EEPROM-Adresse mit 02 festlegen
BSF STATUS,RP0 ;Bank 1
BSF EECON1,RD ;Lesevorgang aktivieren
BCF STATUS,RP0 ;Bank 0
MOVF EEDATA,W ;EEPROM-Daten in Akku schreiben
MOVWF BYTE3 ;Daten auf BYTE3 schreiben
MOVLW EEBYTE4
MOVWF EEADR ;EEPROM-Adresse mit 03 festlegen
BSF STATUS,RP0 ;Bank 1
BSF EECON1,RD ;Lesevorgang aktivieren
BCF STATUS,RP0 ;Bank 0
MOVF EEDATA,W ;EEPROM-Daten in Akku schreiben
MOVWF BYTE4 ;Daten auf BYTE4 schreiben
BCF HILFE,X ;Hilfebit loeschen
BSF INTCON,T0IE ;Interrupt fr Timer 0 freigeben
BSF INTCON,GIE ;Globales Interruptbit freigeben
START BCF STATUS,RP0 ;Bank 0
BTFSC PORTA,4 ;PA4 testen ob 0
GOTO ZAEHLE
BCF HILFE,X ;Hilfebit löschen
GOTO START
ZAEHLE BTFSC HILFE,X
GOTO START ;Hilfebit setzen
INCF BYTE1 ;BYTE1 um 1 erhhen
MOVLW 0x0A ;BYTE1 mit
SUBWF BYTE1,0 ;..
BTFSS STATUS,Z ;10 vergleichen
GOTO HILF
MOVLW 0x00 ;BYTE1 falls 10
MOVWF BYTE1 ;löschen
INCF BYTE2 ;BYTE2 um 1 erhhen
MOVLW 0x0A ;BYTE2 mit
SUBWF BYTE2,0 ;..
BTFSS STATUS,Z ;10 vergleichen
GOTO HILF
MOVLW 0x00 ;BYTE2 falls 10
MOVWF BYTE2 ;löschen
INCF BYTE3 ;BYTE3 um 1 erhöhen
MOVLW 0x0A ;BYTE3 mit
SUBWF BYTE3,0 ;..
BTFSS STATUS,Z ;10 vergleichen
GOTO HILF
MOVLW 0x00 ;BYTE3 falls 10
MOVWF BYTE3 ;löschen
INCF BYTE4 ;BYTE4 um 1 erhöhen
MOVLW 0x0A ;BYTE4 mit
SUBWF BYTE4,0 ;..
BTFSS STATUS,Z ;10 vergleichen
GOTO HILF
MOVLW 0x00 ;BYTE4 falls 10
MOVWF BYTE4 ;löschen
HILF BSF HILFE,X
GOTO START
Ausgabe BTFSC ZAEHL,0 ;ZAEHL-Bit0 testen ob 1
GOTO LABZ01
BTFSC ZAEHL,1 ;ZAEHL-Bit1 testen ob 1
GOTO LABZ02
BTFSC ZAEHL,2 ;ZAEHL-Bit2 testen ob 1
GOTO LABZ03
BTFSC ZAEHL,3 ;ZAEHL-Bit3 testen ob 1
GOTO LABZ04
LABZ01 BCF STATUS,RP0
MOVLW 0x01 ;PA0 auf
MOVWF PORTA ;1 setzen
MOVFW BYTE1 ;BYTE1 auf
MOVWF ZAHL ;ZAHL schreiben
CALL MUX ;Zahl auf 1.7-Segment-Anzeige ausgeben
BCF INTCON,T0IF ;Timer-Interruptflag löschen
BCF ZAEHL,0 ;1 Stelle von ZAEHL löschen
BSF ZAEHL,1 ;2 Stelle von ZAEHL setzen
RETFIE
LABZ02 BCF STATUS,RP0
MOVLW 0x02 ;PA1 auf
MOVWF PORTA ;1 setzen
MOVFW BYTE2 ;BYTE2 auf
MOVWF ZAHL ;ZAHL schreiben
CALL MUX ;Zahl auf 2.7-Segment-Anzeige ausgeben
BCF INTCON,T0IF ;Timer-Interruptflag löschen
BCF ZAEHL,1 ;1 Stelle von ZAEHL löschen
BSF ZAEHL,2 ;2 Stelle von ZAEHL setzen
RETFIE
LABZ03 BCF STATUS,RP0
MOVLW 0x04 ;PA2 auf
MOVWF PORTA ;1 setzen
MOVFW BYTE3 ;BYTE3 auf
MOVWF ZAHL ;ZAHL schreiben
CALL MUX ;Zahl auf 3.7-Segment-Anzeige ausgeben
BCF INTCON,T0IF ;Timer-Interruptflag löschen
BCF ZAEHL,2 ;1 Stelle von ZAEHL löschen
BSF ZAEHL,3 ;2 Stelle von ZAEHL setzen
RETFIE
LABZ04 BCF STATUS,RP0
MOVLW 0x08 ;PA3 auf
MOVWF PORTA ;1 setzen
MOVFW BYTE4 ;BYTE4 auf
MOVWF ZAHL ;ZAHL schreiben
CALL MUX ;Zahl auf 4.7-Segment-Anzeige ausgeben
BCF INTCON,T0IF ;Timer-Interruptflag löschen
BCF ZAEHL,3 ;1 Stelle von ZAEHL löschen
BSF ZAEHL,0 ;2 Stelle von ZAEHL setzen
RETFIE
MUX BCF STATUS,RP0
INCF ZAHL
MOVLW 0x01
SUBWF ZAHL,0
BTFSS STATUS,Z
GOTO ZAHL1
MOVLW b'11101110' ;"Bitmuster" für 0
MOVWF PORTB
RETURN
ZAHL1 DECF ZAHL
MOVLW 0x01
SUBWF ZAHL,0
BTFSS STATUS,Z
GOTO ZAHL2
MOVLW b'00000110' ;"Bitmuster" für 1
MOVWF PORTB
RETURN
ZAHL2 MOVLW 0x02
SUBWF ZAHL,0
BTFSS STATUS,Z
GOTO ZAHL3
MOVLW b'11011100' ;"Bitmuster" für 2
MOVWF PORTB
RETURN
ZAHL3 MOVLW 0x03
SUBWF ZAHL,0
BTFSS STATUS,Z
GOTO ZAHL4
MOVLW b'10011110' ;"Bitmuster" für 3
MOVWF PORTB
RETURN
ZAHL4 MOVLW 0x04
SUBWF ZAHL,0
BTFSS STATUS,Z
GOTO ZAHL5
MOVLW b'00110110' ;"Bitmuster" für 4
MOVWF PORTB
RETURN
ZAHL5 MOVLW 0x05
SUBWF ZAHL,0
BTFSS STATUS,Z
GOTO ZAHL6
MOVLW b'10111010' ;"Bitmuster" für 5
MOVWF PORTB
RETURN
ZAHL6 MOVLW 0x06
SUBWF ZAHL,0
BTFSS STATUS,Z
GOTO ZAHL7
MOVLW b'11111010' ;"Bitmuster" für 6
MOVWF PORTB
RETURN
ZAHL7 MOVLW 0x07
SUBWF ZAHL,0
BTFSS STATUS,Z
GOTO ZAHL8
MOVLW b'00001110' ;"Bitmuster" für 7
MOVWF PORTB
RETURN
ZAHL8 MOVLW 0x08
SUBWF ZAHL,0
BTFSS STATUS,Z
GOTO ZAHL9
MOVLW b'11111110' ;"Bitmuster" für 8
MOVWF PORTB
RETURN
ZAHL9 MOVLW b'10111110' ;"Bitmuster" für 9
MOVWF PORTB
RETURN
end
Beim Programmieren wurde im Programmer PIP-02.EXE der Startwert für den Zähler auf das EEPROM geschrieben. Leider war es ohne Maus nur möglich, FFh in das EEPROM zu schreiben.
Somit startete der Zähler nach jedem Reset mit dem Wert 9999. Dies ist hier jedoch tatsächlich FF FF FF FF! Somit wurde beim Übergang von FFh auf 0 kein Überlauf produziert und der Zähler zählte nach folgendem Schema:
9999 9990 - 9991 - 9992 - 9993 - 9994 - 9995 - 9996 - 9997 - 9998 - 9999 - 9900 - 9901 - 9902 - 9903 9904 etc.
Erst beim Übergang von 9 auf 0 wurde die nächste Stelle weitergeschaltet.
Deshalb wurde testweise der Zähler im Programm mit tatsächlichen 9999 initialisiert er zählte korrekt.
2.3.3 Zähler mit EEPROM lesen und schreiben
Konnte aus Zeitgründen nicht mehr fertiggestellt werden.
3 Interpretation der Messergebnisse
Der PIC ermöglicht eine Lösung komplexer Aufgaben mit geringem Hardwareaufwand.
Bei den entsprechenden Programmiertools muss auf die richtigen Einstellungen/Bedienung geachtet werden.
Die Initialisierung des EEPROMs beim Programmieren ist für die Praxis durchaus denkbar z.B. bei einem Kilometerzähler. Eventuell wäre es jedoch gut, wenn bei Nicht-BCD-Zahlen (hier FFh) eine Errormeldung angegeben würde.