Το σύνολο των εντολών που χρησιμοποιούνται στο Atmel Studio 7.0 για σύνταξη
κώδικα σε γλώσσα C περιέχει, εκτός από τις εντολές της ANSI C και μια σειρά εντολών Embedded C for AVR MCUs, οι οποίες
αναφέρονται σε λειτουργίες και καταχωρητές των μικροελεγκτών. Οι εντολές αυτές
ενδέχεται να διαφοροποιούνται ανάλογα με τον μικροελεγκτή και τις δυνατότητές
του. Για παράδειγμα, δεν είναι δυνατό να χρησιμοποιήσουμε εντολές που αφορούν
καταχωρητές της USART σε
μικροελεγκτές που δεν έχουν ενσωματωμένη θύρα, ο compiler θα βγάλει σφάλμα κατά τη μεταγλώττιση. Στα data sheet των
μικροελεγκτών παρουσιάζονται οι εντολές που τους υποστηρίζουν καθώς και
παραδείγματα σύνταξης. Επίσης υπάρχουν συναρτήσεις και ρουτίνες που καλούνται
από βιβλιοθήκες που υπάρχουν ενσωματωμένες στο Atmel Studio 7.0 εφόσον
συμπεριλάβουμε το κατάλληλο header file στον κώδικα. Στη συνέχεια
παρουσιάζονται παραδείγματα σύνταξης των εντολών που θα χρησιμοποιήσουμε στον
κώδικα για τα πρώτα προγράμματα που θα συνθέσουμε.
DDRA = 0b10110110; //
port A 7, 5, 4, 2, 1 outputs, 6, 3, 0 inputs
Η εντολή DDRx Data Direction Register x (όπου
x η αντίστοιχη θύρα [port] του μικροελεγκτή A, B, C, ….) μας δίνει πρόσβαση στον
αντίστοιχο καταχωρητή του μικροελεγκτή, ο οποίος είναι ανάγνωσης/εγγραφής (R/W) και καθορίζει τη χρήση των
ακροδεκτών (pin) του port ως είσοδο ή έξοδο. Κάθε pin προγραμματίζεται ξεχωριστά από τα υπόλοιπα έτσι ώστε να
είναι δυνατό στο ίδιο port να
έχουμε pin εισόδων και pin εξόδων. Με 1 προγραμματίζεται το pin ως έξοδος, ενώ με 0 ως είσοδος. Η αρχική
κατάσταση, αμέσως μετά την επαναφορά από RESET, είναι όλα 0, δηλαδή είσοδοι. Στο
παράδειγμα γίνεται εγγραφή στον καταχωρητή και προγραμματίζονται τα pin 7, 5, 4, 2,
1 του port A ως έξοδοι και
τα 6, 3, 0 ως είσοδοι.
PORTΑ = 0b11111111; //enable
pull up resistors to inputs, set 1 to outputs
Η εντολή PORTx (όπου x το αντίστοιχο port του
μικροελεγκτή A, B, C, ….) μας δίνει πρόσβαση στον αντίστοιχο καταχωρητή του
μικροελεγκτή, ο οποίος είναι ανάγνωσης/εγγραφής (R/W) και προσδίδει τιμή στο port αν είναι προγραμματισμένο ως έξοδος ή ενεργοποιεί την
εσωτερική αντίσταση πρόσδεσης (pull up) αν είναι προγραμματισμένο ως είσοδος. Η αντίσταση
πρόσδεσης μπορεί να είναι μόνο pull up και είναι της τάξης των 40kΩ. Αν δεν ενεργοποιηθεί η pull up τότε η
είσοδος εμφανίζει υψηλή σύνθετη αντίσταση. Η αρχική
κατάσταση, αμέσως μετά την επαναφορά από RESET, είναι όλα 0. Στο παράδειγμα παραπάνω γίνεται εγγραφή στον καταχωρητή.
Είναι δυνατόν να κάνουμε εγγραφή σε καθορισμένα bit του καταχωρητή με τη σύνταξη PORTxy (όπου
x το αντίστοιχο port του μικροελεγκτή A, B, C, …. και
y το αντίστοιχο bit, αρχίζοντας από 0
για το LSB έως το 7
για το MSB):
PORTA = (1<<PORTA2); /* Initially PORTA=0b00000000,
then i1 will be PORTA=0b00000100*/
PORTA = (3<<PORTA2); /*
Initially PORTA=0b00000000, then i1 will be PORTA=0b00001100*/
Στο πρώτο από
τα παραπάνω παραδείγματα εγγράφουμε 1 στο bit 2 του PORTA,
ενώ στο δεύτερο παράδειγμα εγγράφουμε 3 (0b11) στο ίδιο bit με αποτέλεσμα να επηρεάζεται και το αμέσως σημαντικότερο.
while(PINA == 0b11111110) { /* Your
code here */
}
Ο PINx
είναι ο καταχωρητής κατάστασης του port x (όπου x το αντίστοιχο port του μικροελεγκτή A, B, C, ….). Είναι καταχωρητής μόνο
ανάγνωσης (R) και δηλώνει την κατάσταση των pin του port είτε αυτά είναι προγραμματισμένα ως είσοδοι είτε ως έξοδοι.
Δεν μπορεί να γίνει απόδοση τιμής στον καταχωρητή και για αυτό το λόγο
συναντάμε τον συμβολισμό του μέσα σε εντολές όπως η while ή η if, όπως στο
παράδειγμα, όπου γίνεται ανάγνωση του καταχωρητή.
_delay_ms(10); //Delay 10ms
Η εντολές _delay_ms() και _delay_us() χρησιμοποιούνται για καθυστέρηση στη ροή του προγράμματος
σε ms ή μs αντίστοιχα ανάλογα με τον αριθμό της παρένθεσης. Στην
πραγματικότητα πρόκειται για μια εξωτερική ρουτίνα η οποία καλείται ως
συνάρτηση και προκειμένου να εκτελεστεί σωστά, πρέπει να έχει δηλωθεί η
συχνότητα λειτουργίας του επεξεργαστή και να έχει οριστεί βελτιστοποίηση κώδικα (όπως αναφέρεται στο κεφάλαιο Περιβάλλον εργασίας – παραδείγματα σύνταξης). Για τη χρήση της χρειάζεται να συμπεριληφθεί το header file delay.h (#include <util/delay.h>).
if (bit_is_set(PINΑ,0)) { /* Your code here */ }
Η εντολή bit_is_set()
χρησιμοποιείται προκειμένου να ανιχνεύσουμε αν κάποιο bit ενός καταχωρητή ή μιας μεταβλητής είναι 1.
Μέσα στην παρένθεση της εντολής βάζουμε το όνομα του καταχωρητή ή της
μεταβλητής και μετά το κόμμα τον αριθμό του bit, αρχίζοντας
από 0 για το LSB έως το 7 για το MSB. Σε μεταβλητές
μεγαλύτερες των 8bit η εντολή
μπορεί να λειτουργήσει μόνο για τα 8 LSB. Σε περίπτωση
που το bit είναι 1 μας
επιστρέφει αληθές στη συνθήκη της εντολής που είναι ενσωματωμένη η bit_is_set() και στο
παράδειγμα που προηγείται θα εκτελεστεί ο κώδικας που βρίσκεται μέσα στις αγκύλες.
Κατά τη σύνταξη του κώδικα το Atmel Studio 7.0 θα μας υπογραμμίσει την εντολή ως συντακτικό
λάθος, όμως ο compiler θα τη
μεταγλωττίσει κανονικά χωρίς error, warning ή message.
Εκτός από τις εντολές για τους καταχωρητές και τις συναρτήσεις που εξετάσαμε
στα προηγούμενα παραδείγματα, υπάρχουν αντίστοιχες εντολές για όλους τους
καταχωρητές και τις λειτουργίες των μικροελεγκτών, τις οποίες θα αναφέρουμε με
παραδείγματα καθώς θα συνθέτουμε προγράμματα που τις υποστηρίζουν.
©2016 Πορλιδάς Δημήτριος
|