Θέτοντας σε 1 τα bits των GPR
Η εντολή SBR (Set Bits in Register) θέτει σε 1 καθορισμένα bits των καταχωρητών γενικού σκοπού. Έχει την ακόλουθη σύνταξη:
SBR Rd, K ; set bits in register Rd
Όπου Κ είναι μια 8-bit τιμή που μπορεί να είναι μεταξύ 0x00 έως 0xFF και ο καταχωρητής Rd ένας από τους R16 – R31 καταχωρητές GPR. Η εντολή SBR είναι ένα άλλο όνομα για την εντολή ORI η οποία θέτει σε 1 καθορισμένα bits των καταχωρητών γενικού σκοπού και εκείνα των οποίων το bit στη μεταβλητή Κ είναι 1. Για παράδειγμα στο ακόλουθο πρόγραμμα η εντολή SBR θέτει σε 1 τα bits 2, 5 και 6 ανεξάρτητα των προηγούμενων τιμών τους.
LDI R17, 0b01011001 ; R17 = 0x59
SBR R17, 0b01100100 ; set 2, 5 and 6 in register R17
Όταν η εκτέλεση των προηγούμενων εντολών εκπληρωθεί ο R17 περιέχει την τιμή 0x7D
Θέτοντας σε 0 τα bits των GPR
Η εντολή CBR (Clear Bits in Register) μηδενίζει καθορισμένα bits των καταχωρητών γενικού σκοπού. Έχει την ακόλουθη σύνταξη:
CBR Rd, K ; clear bits in register Rd
Η σταθερά Κ είναι μια 8-bit τιμή, η οποία μπορεί να είναι από 0x00 έως 0xFF και ο Rd είναι ένας καταχωρητής σκοπού από τον R16 έως τον R31. H εντολή CBR θέτει σε 0 τα bits του καταχωρητή γενικού σκοπού, εκείνα του οποίου η θέση των bits της σταθεράς Κ είναι 1. Για παράδειγμα, στο ακόλουθο πρόγραμμα η εντολή CBR μηδενίζει τα bits 2, 5 και 6 ανεξάρτητα από τις προηγούμενες τιμές τους.
LDI R17, 0b01011001 ; R17 = 0x59
CBR R17, 0b01100100 ; clear bits 2, 5 and 6 in register R17
Μετά την εκτέλεση των παραπάνω εντολών ο R17 περιέχει την τιμή 0x19
Αντιγράφοντας ένα bit
Όπως είδαμε σε προηγούμενη ενότητα, ένα bit του SREG (καταχωρητή κατάστασης) ονομάζεται T (temporary) το οποίο χρησιμοποιείται όταν θέλουμε να αντιγράψουμε ένα bit δεδομένων από ένα καταχωρητή γενικού σκοπού GPR σε ένα άλλο. Οι εντολές BST (Bit Store from register to T) και BLD (Bit Load from T to register) μπορούν να χρησιμοποιηθούν για να αντιγράψουν ένα bit ενός καταχωρητή σε ένα συγκεκριμένο bit ενός άλλου καταχωρητή.
Η εντολή “BST Rd, b” αποθηκεύει το bit b από τον καταχωρητή Rd στη σημαία Τ του καταχωρητή κατάστασης, ενώ η εντολή “BLD Rr, b” αντιγράφει τη σημαία Τ στο bit b του καταχωρητή Rr. Για παράδειγμα το ακόλουθο πρόγραμμα αντιγράφει το bit3 από τον R17 στο bit5 του καταχωρητή R19
BST R17, 3 ; αποθηκεύει το bit3 από τον R17 στη σημαία Τ
BLD R19, 5 ; αντιγράφει τη σημαία Τ στο bit5 του R19
Στον παρακάτω πίνακα φαίνονται οι εντολές που μπορούν να γίνουν σε επίπεδο bit πάνω στους καταχωρητές GPR αλλά και στους Ι/Ο καταχωρητές:
Παράδειγμα: Ένας διακόπτης είναι συνδεμένος στο pin PB4. Γράψε ένα πρόγραμμα που να παίρνει την κατάσταση του διακόπτη και να την καταχωρεί στο D0 της εσωτερικής μνήμης RAM και στη θέση 0x200.
Λύση
.EQU MYREG = 0x200 ; ορισμός σταθερής τιμής
CBI DDRB, 0 ; κάνε το pin PB0 είσοδο
IN R17, PINB ; R17 = PINB
BST R17, 4 ; T = PINB.4
LDI R16, 0x00 ; R16 = 0x00
BLD R16, 0 ; R16.0 = T
STS MYREG, R16 ; αντέγραψε τον R16 στη θέση $200 της μνήμης δεδομένων
HERE: JMP HERE
Ελέγχοντας ένα bit
Για να δούμε εάν ένα bit ενός καταχωρητή γενικού σκοπού είναι 1 ή 0 χρησιμοποιούμε την εντολή SBRS (Skip next instruction if Bit in register is Set) ή την SBRC (Skip next instruction if Bit in register is Cleared).
Η εντολή SBRS ελέγχει ένα bit ενός καταχωρητή και παραλείπει την αμέσως επόμενη εντολή εάν αυτό το bit είναι 1 (HIGH). Η σύνταξη της εντολής SBRS είναι η ακόλουθη:
SBRS Rd, b ; skip next instruction if Bit b in Rd is HIGH
Για παράδειγμα στο ακόλουθο πρόγραμμα η εντολή LDI R20, 0x55 δεν θα εκτελεστεί επειδή το bit3 είναι HIGH
LDI R17, 0b00001010
SBRS R17, 3
LDI R20, 0x55
LDI R30, 0x33
Η εντολή SBRC παραλείπει την επόμενη εντολή εάν το συγκεκριμένο bit ενός GPR είναι 0 (LOW). Η εντολή αυτή έχει την ακόλουθη σύνταξη:
SBRC Rd, b ; skip next instruction if Bit b in Rd is 0
Στο ακόλουθο παράδειγμα η εντολή “LDI R20, 0x55” δεν θα εκτελεστεί διότι το bit2 τουR16 είναι LOW.
LDI R16, 0b00001010
SBRC R16, 2 ; skip next instruction if Bit 2 in R16 is cleared
LDI R20, 0x55
LDI R30, 0x33
Παράδειγμα: Ένας διακόπτης είναι συνδεμένος στο pin PC7. Χρησιμοποιώντας την εντολή SBRS γράψε ένα πρόγραμμα που να ελέγχει την κατάσταση του διακόπτη και να εκτελεί τα ακόλουθα:
(α) Εάν switch = 0 να στέλνει τον χαρακτήρα ‘Ν’ στη PortD
(b) Εάν switch = 1 να στέλνει τον χαρακτήρα ‘Υ’ στη PortD
Λύση
CBI DDRC, 7 ; κάνει το pin PC7 σαν είσοδο
LDI R16, 0xFF
OUT DDRD, R16
AGAIN: IN R20, PINC ; R20 = PINC
SBRS R20, 7 ; παράκαμψε την επόμενη εντολή εάν το bit PC7 είναι HIGH
RJMP OVER ; εάν είναι LOW
LDI R16, ‘Y’ ; R16 = ‘Y’ ASCII γράμμα Υ
OUT PORTD, R16
RJMP AGAIN
OVER: LDI R16, 'Ν' ; R16 = ‘N’ ASCII γράμμα Ν
OUT PORTD, R16 ; Αντιγραφή του R16 στη PortD
RJMP AGAIN
Διαχειρισμός των bits των Ι/Ο καταχωρητών
Όπως είπαμε σε προηγούμενη ενότητα, μπορούμε να θέσουμε σε 1 ή 0 τους χαμηλότερους 32 Ι/Ο καταχωρητές (διευθύνσεις 0 έως 31) χρησιμοποιώντας τις εντολές SBI (Set bit in I/O register) και CBI (Clear bit in I/O register). Για παράδειγμα, οι επόμενες δυο εντολές θέτουν σε 1 το PORTD.1 και θέτουν σε 0 το PORTB.4 αντίστοιχα.
SBI PORTD, 1 ; set Bit 1 in PORTD
CBI PORTB, 4 ; clear Bit 4 in PORTB
Παράδειγμα: Γράψε ένα πρόγραμμα που να εναλλάσσει το pin RB2 200 φορές
Λύση
LDI R16, 200 ; φόρτωσε τον μετρητή στον R16
SBI DDR2, 2 ; DDRB.1 = 1 κάνε το RB1 σαν έξοδο
AGAIN: SBI PORTB, 2 ; θέσε σε 1 το bit PB2
CBI PORTB, 2 ; θέσε σε 0 το bit PB2
DEC R16 ; μείωσε τον R16
BRNE AGAIN ; συνέχισε μέχρι ο μετρητής γίνει 0
Όπως είπαμε σε προηγούμενη ενότητα μπορούμε να ελέγχουμε ένα bit στους χαμηλότερους 32 Ι/Ο registers χρησιμοποιώντας τις εντολές SBIS (skip if Bit in I/O register is cleared) και SBIC (skip if Bit in I/O register is cleared)
Παράδειγμα: Γράψτε το πρόγραμμα του παραπάνω παραδείγματος χρησιμοποιώντας την εντολή SBIC. : Ένας διακόπτης είναι συνδεμένος στο pin PC7. Χρησιμοποιώντας την εντολή SBRS γράψε ένα πρόγραμμα που να ελέγχει την κατάσταση του διακόπτη και να εκτελεί τα ακόλουθα:
(α) Εάν switch = 0 να στέλνει τον χαρακτήρα ‘Ν’ στη PortD
(b) Εάν switch = 1 να στέλνει τον χαρακτήρα ‘Υ’ στη PortD
Λύση
CBI DDRC, 7 ; κάνει το pin PC7 σαν είσοδο
LDI R16, 0xFF
OUT DDRD, R16
AGAIN:
SBIC PINC, 7 ; παράκαμψε την επόμενη εντολή εάν το Bit PC7 είναι 0
RJMP OVER
LDI R16, 'N' ; R16 = ‘N’ ASCII γράμμα Ν
OUT PORTD, R16
RJMP AGAIN
OVER: LDI R16, ‘Y’ ; R16 = ‘Y’ ASCII γράμμα Υ
OUT PORTD, R16
RJMP AGAIN
Παράδειγμα: Γράψε το προηγούμενο πρόγραμμα χρησιμοποιώντας την εντολή SBIS
Λύση
CBI DDRC, 7 ; κάνε το pin PC7 σαν είσοδο
LDI R16, 0xFF
OUT DDRD, R16 ; κάνε την PortD σαν έξοδο
AGAIN: SBIS PINC, 7 ; παράκαμψε την επόμενη εντολή εάν το Bit PC7 είναι 1
RJMP OVER
LDI R16, ‘Y’ ; R16 = ‘Y’ ASCI γράμμα Υ
OUT PORTD, R16
RJMP AGAIN
OVER: LDI R16, ‘N’ ; R16 = ‘N’ ASCII γράμμα Ν
OUT PORTD, R16
RJMP AGAIN
Ελέγχοντας ένα bit σημαίας
Υπάρχουν μερικές εντολές για τον έλεγχο των bits στον καταχωρητή κατάστασης, όπως φαίνονται στον (ακόλουθο πίνακα). Όλες οι εντολές χωρίζονται σε δυο τύπους: BRBS (Branch if status flag is set) και BRBC (Branch if status flag is Cleared).
BRBS s, k ; branch if status flag bit is set
BRBC s, k ; branch if status flag bit is cleared
Όπου s είναι ένας αριθμός μεταξύ 0 και 7 ο οποίος αντιπροσωπεύει το bit του καταχωρητή κατάστασης και k είναι η διεύθυνση της θέσης στην οποία θα πάει η ροή της εκτέλεσης όταν η συνθήκη είναι αληθής.
Για παράδειγμα στο επόμενο πρόγραμμα η εντολή LDI δεν εκτελείται όταν η σημαία κρατουμένου είναι 1
BRBS 0, L1 ; branch if status flag bit 0 is set
LDI R20, 3
L1:
Μπορούμε να γράψουμε το ίδιο απόσπασμα προγράμματος χρησιμοποιώντας την εντολή “BRCS L1” όπως ακολούθως:
BRCS L1 ; branch if carry flag is set
LDI R20, 3
L1:
Επειδή είναι δύσκολο να θυμόμαστε τα bits του καταχωρητή κατάστασης και να χρησιμοποιούμε τις εντολές BRBC και BRBS μπορούμε να χρησιμοποιούμε τις εντολές του πίνακα για να απλοποιήσουμε τη χρήση των bits του καταχωρητή κατάστασης.
Διαμόρφωση bit σημαίας του SREG
Για να θέσουμε σε 1 μια σημαία χρησιμοποιούμε την εντολή BSET:
BSET s ; flag bit set
Όπου s είναι ένας αριθμός μεταξύ 0 και 7 και παριστάνει το bit που πρόκειται να γίνει 1 στον καταχωρητή κατάστασης. Για παράδειγμα η επόμενη εντολή θέτει σε 1 τη σημαία κρατουμένου:
BSET 0 ; set bit 0 (carry flag)
Ένα άλλο παράδειγμα, η εντολή “BSET 2” θέτει σε 1 τη σημαία Ν (Negative)
Για να κάνουμε 0 μια σημαία χρησιμοποιούμε την εντολή BCLR (flag bit clear)
BCLR s ; set bit 0 (carry flag)
Όπου s είναι ένας αριθμός μεταξύ 0 και 7 ο οποίος αντιπροσωπεύει το bit που πρόκειται να γίνει 0 στον καταχωρητή κατάστασης. Για παράδειγμα, η επόμενη εντολή θέτει σε 0 τη σημαία κρατουμένου στον SREG:
BCLR 0 ; clear bit 0 (carry flag)
Ένα άλλο παράδειγμα, η εντολή “BCLR 1” θέτει σε 0 τη σημαία Z (Zero).
Ένας πιο προσιτός τρόπος είναι να χρησιμοποιήσουμε την εντολή CLZ όπως φαίνεται στον πίνακα.
Διαχειρισμός bit της εσωτερικής μνήμης δεδομένων RAM
Η εσωτερική μνήμη δεδομένων RAM δεν είναι bit προσβάσιμη. Έτσι για να διαχειριστούμε ένα bit μιας θέσης της εσωτερικής RAM θα πρέπει να το φορτώσουμε σε ένα καταχωρητή γενικού σκοπού και μετά να το διαχειριστούμε όπως φαίνεται στα ακόλουθα παραδείγματα.
Παράδειγμα: Γράψε ένα πρόγραμμα για να δεις εάν η εσωτερική μνήμη RAM στη θέση $195 περιέχει άρτια τιμή. Εάν ναι στείλτε τη στη PortB. Εάν όχι κάντε τη άρτια και μετα στείλτε τη στη PortB
Λύση 1
.EQU MYREG = 0x195
LDI R16, 0xFF
OUT DDRB, R16 ; κάνε την PortB έξοδο
AGAIN: LDS R16, MYREG
SBRS R16, 0 ; παράκαμψε την επόμενη εντολή εάν το bit D0 είναι 1
RJUMP OVER
CBR R16, 0b00000001 ; κάνε 0 το D0
OVER: OUT PORTB, R16 ; αντιγραφή στη PortB
JMP AGAIN
Λύση 2
.EQU MYREG = 0x195
LDI R16, 0xFF
OUT DDRB, R16 ; κάνε την PortB έξοδο
AGAIN: LDS R16, MYREG
CBR R16, 0b00000001 ; κάνε 0 το D0
OVER: OUT PORTB, R16 ; αντιγραφή στη PortB
JMP AGAIN
Παράδειγμα: Γράψε ένα πρόγραμμα για να δεις εάν στη θέση $137 της εσωτερικής RAM υπάρχει άρτια τιμή. Εάν ναι γράψε την τιμή 0x55 στη θέση $200. Εάν όχι γράψε την τιμή 0x63 στη θέση $200
Λύση
.EQU MYREG = 0x137
.EQU RESULT = 0x200
LDS R16, MYREG
SBRC R16, 0
RJMP OVER
LDI R16, 0x55
STS RESULT, R16
RJUMP HERE
OVER: LDI R16, 0x63
STS RESULT, R16
HERE: RJUMP HERE