![]() |
|||
| HSG |
|
Das folgende kleine Programm sollte nicht wirklich in den PIC geladen werden, sondern mit Hilfe des Debuggers bearbeitet werden. Es soll die Bedeutung und Wirkung der Flags bei arithmetischen Operationen zeigen. Bei der Operation 7+11 wird das Digit-Carry gesetzt, warum? Wann wird das Carry-Flag gesetzt, wann das Zero-Flag? Zur Klärung dieser Fragen soll das Programm variiert werden. Das Original-Handbuch erläutert das STATUS-Register auf Seite 22. Eine prima "Lesson" zum Thema ist bei John McDonoughs PIC Elmer 160 Course Lessons zu finden.
processor pic16f877a
#include p16f877a.inc
__config _HS_OSC & _WDT_OFF & _PWRTE_ON
; Variablen
S1 equ 0x20 ; 1.Summand
S2 equ 0x21 ; 2.Summand
org 0x00
reset clrf STATUS
movlw 0x00
movwf PCLATH
goto main
org 0x10
main
movlw d'7'
movwf S1
movlw d'11'
movwf S2
bcf STATUS,C ; Carry-Flag zurücksetzen
bcf STATUS,DC ; Digit-Carry-Flag zurücksetzen
bcf STATUS,Z ; Zero-Flag zurücksetzen
movfw S1
addwf S2,f
loop goto loop
end
Wer nicht den Simulator benutzen will, kann sich durch folgenden Code das STATUS-Register und damit die Flags auch auf PortB ausgeben lassen:
; Port-Setup
bsf STATUS,5 ; wechsle zu Bank1
movlw b'00000000' ; setze Port B, Bit 0-7
movwf TRISB ; als Ausgang
bcf STATUS,5 ; wieder in Bank 0 wechseln
; STATUS auf PortB ausgeben
movfw STATUS
movwf PORTB
bcf STATUS,C ; Carry-Flag löschen
rlf y,1
bcf STATUS,C ; Carry-Flag löschen
rrf x,1
Ein passender Algorithmus ist die sogenannte ägyptische Bauern-Multiplikation .
# -*- coding: iso-8859-1 -*-
# Autor: mk, 29.1.09
x = 13
y = 17
p = 0
while x > 0:
if x%2 == 1:
p = p + y
y = y*2
x = x/2
print p
processor pic16f877a
#include p16f877a.inc
__config _HS_OSC & _WDT_OFF & _PWRTE_ON
; Variablen
x equ 0x20 ; 1.Faktor
y equ 0x21 ; 2.Faktor
p equ 0x22 ; Produkt
org 0x00
reset clrf STATUS
movlw 0x00
movwf PCLATH
goto main
org 0x10
main
movlw d'13'
movwf x
movlw d'17'
movwf y
movlw 0x0
movwf p
sb movf x,1
btfsc STATUS,Z ; x = 0?
goto se ; x = 0
btfss x,0 ; x ungerade?
goto notaddy ; x gerade
movf p
addwf y,0
movwf p
notaddy bcf STATUS,C ; Carry-Flag löschen
rlf y,1
bcf STATUS,C ; Carry-Flag löschen
rrf x,1
goto sb
se
loop goto loop
end
# -*- coding: iso-8859-1 -*-
# Autor: mk, 9.6.09
x = 101
y = 23
q = 0
r = x
while r-y >= 0:
r = r-y
q = q+1
print x,'div',y,'=',q
print x,'mod',y,'=',r
processor pic16f877a
#include p16f877a.inc
__config _HS_OSC & _WDT_OFF & _PWRTE_ON
; Variablen
x equ 0x20
y equ 0x21
q equ 0x22
r equ 0x23
org 0x00
reset:
clrf STATUS
movlw 0x00
movwf PCLATH
goto main
org 0x10
main:
; Eingaben
movlw d'101'
movwf x
movlw d'23'
movwf y
; Division
call divmod
; Dauerschleife
loop:
goto loop
; --------------------------------------------
divmod:
movlw d'0' ; q -> 0
movwf q
movf x,0 ; x -> r
movwf r
bsf STATUS,C ; Carry-Flag setzen
dmloop:
movf y,0 ; y -> w
subwf r,0 ; r-w -> w
btfsc STATUS,C ; Carry-Flag wird bei Unterlauf gelöscht
goto dmweiter
goto dmunterlauf
dmweiter:
movf y,0 ; y -> w
subwf r,1 ; r-w -> r
incf q ; q+1 -> q
goto dmloop
dmunterlauf:
return
; --------------------------------------------
end