|
Bitte beachte die Copyrighthinweise.
PIC 16C84
1 Aufgabenstellung
· Programmierung und Ausführung eines Testprogramms zum Überprüfen der Hardware
· Weiterprogrammierung eines Programms zur Realisierung eines Zähler mit vier 7-Segment LEDs.
2 Schaltung
Folgende Schaltung war bereits von Christian/Deimel 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. Da jedoch der Zähler selbst nicht mehr getestet worden war, wurde dieser Widerstand nicht weiter beachtet.
Die Betriebsspannung wurde mit dem Multimeter P2 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.
3 Hardwaretest
Vor der Inbetriebnahme des Zählers wurde die Funktion der PIC-bezogenen Hardware geprüft.
3.1 Oszillator
Nach dem Anschließen der Betriebsspannung wurde mittels des Oszilloskops am Quarz und am entsprechenden Pin des ICs eine Sinusspannung mit einer Frequenz von etwa 4MHz gemessen.
3.2 Testprogramm
Es wurde ein Programm geschrieben, welches in einer Schleife auf allen Ausgängen von PORTB ein Rechteck ausgibt:
;===========================
;
; Hardware-Test des Pic
;
; Florian Rosenauer
; 5 EA 17.10.1997
;===========================
list p=16c84
include"16c84.inc"
org 0x00
goto init
org 0x08
init BSF STATUS,RP0 ; Bank 1
CLRF TRISB ; Tristate ausschalten
BCF STATUS,RP0 ; Bank 0
start MOVLW 0x00
MOVWF PORTB
MOVLW 0xFF
MOVWF PORTB
GOTO start
end
RSTEST.ASM:
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 seriellen Schnittstelle eines PCs angeschlossen wurde. Hierzu musste der Treiber COM84.EXE 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).
An allen Pins von PORTB konnte das erwartete Rechteck gemessen werden.
4 Zähler mit 7-Segment LEDs
4.1 Deimel/Christian Programm
Hauptprogramm
Zuerst wurde das bereits vorhandene Programm von Deimel/Christian getestet, es blieben jedoch alle Anzeigen dunkel:
Multiplexen
Interruptprogramm
DEIMEL.ASM:
;===============================
; Zählerprogramm PRT VEA
; 03.10.1997, Deimel & Christian
; PA0 7-Segmentstelle 1
; PA1 7-Segmentstelle 2
; PA2 7-Segmentstelle 3
; PA3 7-Segmentstelle 4
; PA4 Zähleingang
; PB1-PB7 7-Segment-Balken
;===============================
List p=16C84
include "16C84.inc"
BYTE1 equ 0x0C
BYTE2 equ 0x0D
BYTE3 equ 0x0E
BYTE4 equ 0x0F
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
BSF STATUS,RP0 ;Bank 1
MOVLW 0x82 ;Prescaler auf 488Hz setzen
MOVWF OPTION_REG ;mit 1X0X0010 -> 82HEX
BCF INTCON,T0IE ;Interrupt für Timer 0 freigeben
BSF INTCON,GIE ;Globales Interruptbit freigeben
MOVLW 0x01 ;ZAEHL auf
MOVWF ZAEHL ;00000001 setzen
EEPROML BCF STATUS,RP0 ;Bank 0
MOVLW 0x00
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 0x01
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 0x02
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 0x03
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 löschen
START BCF STATUS,RP0 ;Bank 0
BTFSC PORTA,4 ;PA4 testen ob 0
GOTO ZAEHLE
BCF HILFE,X ;Hilfebit löschen
GOTO START
HILFEK BTFSC HILFE,X ;Hilfebit testen ob 0
GOTO START
ZAEHLE BSF HILFE,X ;Hilfebit setzen
INCF BYTE1 ;BYTE1 um 1 erhöhen
MOVLW 0x0A ;BYTE1 mit
SUBWF BYTE1,0 ;..
BTFSS STATUS,Z ;10 vergleichen
GOTO EEPROS1
MOVLW 0x00 ;BYTE1 falls 10
MOVWF BYTE1 ;löschen
INCF BYTE2 ;BYTE2 um 1 erhöhen
MOVLW 0x0A ;BYTE2 mit
SUBWF BYTE2,0 ;..
BTFSS STATUS,Z ;10 vergleichen
GOTO EEPROS1
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 EEPROS1
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 EEPROS1
MOVLW 0x00 ;BYTE4 falls 10
MOVWF BYTE4 ;löschen
EEPROS1 MOVF BYTE1,W ;BYTE1 in Akku
MOVWF EEDATA ;Daten von BYTE1 in EEPROM-Daten-Register
MOVLW 0x00 ;Adresse für Daten von BYTE1 festlegen
MOVWF EEADR ;schreiben der Adresse auf EEPROM-Adress-Register
BSF STATUS,RP0 ;Bank 1
BCF INTCON,GIE ;Globales Interupt Bit sperren
BSF EECON1,WREN ;Schreibezyklus
MOVLW 0x55 ;..
MOVWF EECON2 ;..
MOVLW 0xAA ;..
MOVWF EECON2 ;ermöglichen
BSF EECON1,WR ;Schreibezyklus starten
BSF INTCON,GIE ;Globales Interupt Bit setzen
NOP
BCF INTCON,GIE ;Globales Interupt Bit sperren
EEPROS2 BTFSC EECON1,WR ;Testen ob Schreibezyklus beendet
GOTO EEPROS2
MOVF BYTE2,W ;BYTE2 in Akku
MOVWF EEDATA ;Daten von BYTE1 in EEPROM-Daten-Register
MOVLW 0x01 ;Adresse für Daten von BYTE2 festlegen
MOVWF EEADR ;schreiben der Adresse auf EEPROM-Adress-Register
BSF STATUS,RP0 ;Bank 1
BCF INTCON,GIE ;Globales Interupt Bit sperren
BSF EECON1,WREN ;Schreibezyklus
MOVLW 0x55 ;..
MOVWF EECON2 ;..
MOVLW 0xAA ;..
MOVWF EECON2 ;ermöglichen
BSF EECON1,WR ;Schreibezyklus starten
BSF INTCON,GIE ;Globales Interupt Bit setzen
NOP
BCF INTCON,GIE ;Globales Interupt Bit sperren
EEPROS3 BTFSC EECON1,WR ;Testen ob Schreibezyklus beendet
GOTO EEPROS3
MOVF BYTE3,W ;BYTE3 in Akku
MOVWF EEDATA ;Daten von BYTE3 in EEPROM-Daten-Register
MOVLW 0x02 ;Adresse für Daten von BYTE3 festlegen
MOVWF EEADR ;schreiben der Adresse auf EEPROM-Adress-Register
BSF STATUS,RP0 ;Bank 1
BCF INTCON,GIE ;Globales Interupt Bit sperren
BSF EECON1,WREN ;Schreibezyklus
MOVLW 0x55 ;..
MOVWF EECON2 ;..
MOVLW 0xAA ;..
MOVWF EECON2 ;ermöglichen
BSF EECON1,WR ;Schreibezyklus starten
BSF INTCON,GIE ;Globales Interupt Bit setzen
NOP
BCF INTCON,GIE ;Globales Interupt Bit sperren
EEPROS4 BTFSC EECON1,WR ;Testen ob Schreibezyklus beendet
GOTO EEPROS4
MOVF BYTE4,W ;BYTE4 in Akku
MOVWF EEDATA ;Daten von BYTE4 in EEPROM-Daten-Register
MOVLW 0x03 ;Adresse für Daten von BYTE4 festlegen
MOVWF EEADR ;schreiben der Adresse auf EEPROM-Adress-Register
BSF STATUS,RP0 ;Bank 1
BCF INTCON,GIE ;Globales Interupt Bit sperren
BSF EECON1,WREN ;Schreibezyklus
MOVLW 0x55 ;..
MOVWF EECON2 ;..
MOVLW 0xAA ;..
MOVWF EECON2 ;ermöglichen
BSF EECON1,WR ;Schreibezyklus starten
BSF INTCON,GIE ;Globales Interupt Bit freigeben
BSF INTCON,GIE ;Globales Interupt Bit setzen
NOP
BCF INTCON,GIE ;Globales Interupt Bit sperren
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 MOVLW 0x01 ;PA0 auf
MOVWF PORTA ;1 setzen
MOVLW 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 MOVLW 0x01 ;PA1 auf
MOVWF PORTA ;1 setzen
MOVLW 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,0 ;1 Stelle von ZAEHL löschen
BSF ZAEHL,1 ;2 Stelle von ZAEHL setzen
RETFIE
LABZ03 MOVLW 0x01 ;PA2 auf
MOVWF PORTA ;1 setzen
MOVLW 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,0 ;1 Stelle von ZAEHL löschen
BSF ZAEHL,1 ;2 Stelle von ZAEHL setzen
RETFIE
LABZ04 MOVLW 0x01 ;PA3 auf
MOVWF PORTA ;1 setzen
MOVLW 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,0 ;1 Stelle von ZAEHL löschen
BSF ZAEHL,1 ;2 Stelle von ZAEHL setzen
RETFIE
MUX BCF STATUS,RP0
MOVLW 0x00
SUBWF ZAHL,0
BTFSS STATUS,Z
GOTO ZAHL1
MOVLW 0x00 ;"Bitmuster" für 0
MOVWF PORTB
RETURN
ZAHL1 MOVLW 0x01
SUBWF ZAHL,0
BTFSS STATUS,Z
GOTO ZAHL2
MOVLW 0x00 ;"Bitmuster" für 1
MOVWF PORTB
RETURN
ZAHL2 MOVLW 0x02
SUBWF ZAHL,0
BTFSS STATUS,Z
GOTO ZAHL3
MOVLW 0x00 ;"Bitmuster" für 2
MOVWF PORTB
RETURN
ZAHL3 MOVLW 0x03
SUBWF ZAHL,0
BTFSS STATUS,Z
GOTO ZAHL4
MOVLW 0x00 ;"Bitmuster" für 3
MOVWF PORTB
RETURN
ZAHL4 MOVLW 0x04
SUBWF ZAHL,0
BTFSS STATUS,Z
GOTO ZAHL5
MOVLW 0x00 ;"Bitmuster" für 4
MOVWF PORTB
RETURN
ZAHL5 MOVLW 0x05
SUBWF ZAHL,0
BTFSS STATUS,Z
GOTO ZAHL6
MOVLW 0x00 ;"Bitmuster" für 5
MOVWF PORTB
RETURN
ZAHL6 MOVLW 0x06
SUBWF ZAHL,0
BTFSS STATUS,Z
GOTO ZAHL7
MOVLW 0x00 ;"Bitmuster" für 6
MOVWF PORTB
RETURN
ZAHL7 MOVLW 0x07
SUBWF ZAHL,0
BTFSS STATUS,Z
GOTO ZAHL8
MOVLW 0x00 ;"Bitmuster" für 7
MOVWF PORTB
RETURN
ZAHL8 MOVLW 0x08
SUBWF ZAHL,0
BTFSS STATUS,Z
GOTO ZAHL9
MOVLW 0x00 ;"Bitmuster" für 8
MOVWF PORTB
RETURN
ZAHL9 MOVLW 0x00 ;"Bitmuster" für 9
MOVWF PORTB
RETURN
end
4.2 Teiltests
Danach wurde mit dem Test der einzelnen Programmteile begonnen:
;===============================
; Zählerprogramm PRT VEA
; Hardwaretest
;===============================
List p=16C84
include "16C84.inc"
BYTE1 equ 0x0C
BYTE2 equ 0x0D
BYTE3 equ 0x0E
BYTE4 equ 0x0F
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
BSF STATUS,RP0 ;Bank 1
MOVLW 0x82 ;Prescaler auf 488Hz setzen
MOVWF OPTION_REG ;mit 1X0X0010 -> 82HEX
;BCF INTCON,T0IE ;Interrupt für Timer 0 freigeben
;BSF INTCON,GIE ;Globales Interruptbit freigeben
MOVLW 0x01 ;ZAEHL auf
MOVWF ZAEHL ;00000001 setzen
hwtest BCF STATUS,RP0 ;Bank 0
MOVLW FFh
MOVWF PORTB
BSF PORTA,0
goto hwtest
end
7SEG-TST.ASM
Hier ist nur die Initialisierung des Deimel/Christian Programms enthalten. Bei den Interrupts (nicht getestet) ist jedoch vermutlich das BCF für T0IE falsch, außerdem fehlt möglicherweise die erstmalige Löschung von T0IF.
Nach dem Starten leuchteten alle Segment aller 7-Segment LEDs, d.h. die Hardware war in diesem Punkt in Ordnung. Wegen BSF PORTA,0 wurde zwar nur die erste Anzeige aktiviert, allerdings waren die anderen Pins zufällig ebenfalls auf HIGH.
5 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.