- Προετοιμασία του υλικού
- Κατανόηση των GPIO Pinouts στο STM8S103F
- Περιγραφή Pinout και συμβουλές για την επιλογή STM8S103F GPIO
- Προγραμματισμός STM8S για είσοδο και έξοδο GPIO με χρήση SPL
- Μεταφόρτωση και δοκιμή του προγράμματος
Για μικροελεγκτές, ένα πρόγραμμα LED που αναβοσβήνει ισοδυναμεί με το πρόγραμμα «γειά σου κόσμος». Στο προηγούμενο σεμινάριό μας, μάθαμε πώς να ξεκινήσουμε με το STM8S103F3 Development Board και πώς να ρυθμίσουμε το IDE και το μεταγλωττιστή για τον προγραμματισμό των ελεγκτών STM8S. Έχουμε επίσης μάθει πώς να χρησιμοποιούμε τις τυπικές περιφερειακές βιβλιοθήκες και πώς να μεταγλωττίζουμε και να ανεβάζουμε τον κώδικα στον μικροελεγκτή μας. Με όλα τα βασικά καλυμμένα, ας αρχίσουμε να γράφουμε κώδικα. Σε αυτό το σεμινάριο, θα μάθουμε πώς να εκτελούμε γενικές λειτουργίες GPIO σε ελεγκτές STM8S. Η πλακέτα έχει ήδη ενσωματωμένο LED συνδεδεμένο στον ακροδέκτη 5 της θύρας Β, θα μάθουμε πώς να αναβοσβήνει αυτό το LED και επίσης να προσθέτουμε ένα εξωτερικό LED και να το ελέγχουμε με ένα μπουτόν. Εάν είστε εντελώς νέος, συνιστάται να διαβάσετε το προηγούμενο σεμινάριο προτού προχωρήσετε περαιτέρω.
Προετοιμασία του υλικού
Πριν βυθίσουμε στο πρόγραμμα, ας προετοιμάσουμε τις συνδέσεις υλικού. Όπως αναφέρθηκε νωρίτερα, θα χρησιμοποιήσουμε δύο LED εδώ, το ένα είναι ένα ενσωματωμένο LED που θα αναβοσβήνει συνεχώς και το άλλο είναι ένα εξωτερικό LED που θα εναλλάσσεται με ένα κουμπί. Η ιδέα είναι να μάθετε όλες τις λειτουργίες του GPIO σε μια απλή ρύθμιση. Το ενσωματωμένο Led είναι ήδη συνδεδεμένο στο PB5 (pin5 του PORTB), οπότε μόλις έχω συνδέσει ένα LED στο PA3 και ένα μπουτόν στο PA2, όπως μπορείτε να δείτε στο παρακάτω διάγραμμα.
Όμως, από όλες τις καρφίτσες εξόδου που διατίθενται στον ελεγχόμενο μας γιατί επέλεξα το PA3 για έξοδο και το PA2 για είσοδο; Οι ερωτήσεις είναι έγκυρες και θα το εξηγήσω αργότερα σε αυτό το άρθρο. Η ρύθμιση του υλικού μου για αυτό το σεμινάριο εμφανίζεται παρακάτω. Όπως μπορείτε να δείτε, έχω συνδέσει επίσης τον προγραμματιστή ST-link με καρφίτσες προγραμματισμού που όχι μόνο θα προγραμματίσουν τον πίνακα μας αλλά θα λειτουργήσουν επίσης ως πηγή ενέργειας.
Κατανόηση των GPIO Pinouts στο STM8S103F
Τώρα επιστρέφουμε στην ερώτηση, γιατί το PA2 για είσοδο και γιατί το PA3 για έξοδο; Για να το καταλάβουμε, ας ρίξουμε μια πιο προσεκτική ματιά στο pinout του μικροελεγκτή που φαίνεται παρακάτω.
Σύμφωνα με το διάγραμμα pinout, έχουμε τέσσερις θύρες στον μικροελεγκτή μας, δηλαδή, PORT A, B, C και D που υποδηλώνονται από PA, PB, PC και PD αντίστοιχα. Κάθε καρφίτσα GPIO είναι επίσης κλαμπ με κάποια άλλη ειδική λειτουργικότητα. Για παράδειγμα, το PB5 (pin 5 του PORT B) δεν μπορεί να λειτουργήσει μόνο ως ακροδέκτης GPIO αλλά και ως καρφίτσα SDA για επικοινωνία I2C και ως ακροδέκτης εξόδου Timer 1. Επομένως, εάν χρησιμοποιούμε αυτόν τον πείρο για απλούς σκοπούς GPIO όπως τη σύνδεση ενός LED, τότε δεν θα είμαστε σε θέση να χρησιμοποιήσουμε ταυτόχρονα το I2C και το LED. Δυστυχώς, το ενσωματωμένο LED είναι συνδεδεμένο σε αυτόν τον πείρο, οπότε δεν έχουμε μεγάλη επιλογή εδώ, και σε αυτό το πρόγραμμα, δεν πρόκειται να χρησιμοποιήσουμε το I2C, οπότε δεν είναι μεγάλο πρόβλημα.
Περιγραφή Pinout και συμβουλές για την επιλογή STM8S103F GPIO
Πραγματικά, δεν θα ήταν κακό να χρησιμοποιήσετε το PA1 ένα pin εισόδου και θα λειτουργούσε απλώς το pin. Αλλά το έθεσα σκόπιμα για να μου δώσω την ευκαιρία να σας δείξω μερικές κοινές παγίδες στις οποίες μπορεί να πέσετε όταν επιλέγετε καρφίτσες GPIO σε έναν νέο μικροελεγκτή. Το καλύτερο για να αποφύγετε τις παγίδες είναι να διαβάσετε τις λεπτομέρειες και την περιγραφή των ακίδων που παρέχονται στο δελτίο δεδομένων STM8S103F3P6. Για τις λεπτομέρειες περιγραφής ακίδων STM8S103F3P6 μικροελεγκτή που αναφέρονται στο φύλλο δεδομένων εμφανίζονται παρακάτω εικόνες.
Οι ακίδες εισόδου στο μικροελεγκτή μας μπορεί να είναι κυμαινόμενες ή αδύναμες pull-up και οι ακίδες εξόδου μπορεί να είναι Open Drain ή Push-pull. Η διαφορά μεταξύ των ακίδων Open Drain και Push-Pull Output έχει ήδη συζητηθεί, επομένως δεν θα αναφερθούμε σε λεπτομέρειες. Για να το θέσω απλό, ένας πείρος εξόδου Open Drain μπορεί να κάνει την έξοδο τόσο χαμηλή όσο όχι τόσο υψηλή, ενώ ένας πείρος εξόδου push-pull μπορεί να κάνει την έξοδο τόσο υψηλή όσο και υψηλή.
Εκτός από αυτόν από τον παραπάνω πίνακα, μπορείτε επίσης να παρατηρήσετε ότι ένας πείρος εξόδου μπορεί να είναι γρήγορη έξοδος (10 Mhz) ή Αργή έξοδος (2 MHz). Αυτό καθορίζει την ταχύτητα GPIO, εάν θέλετε να αλλάξετε τις ακίδες GPIO μεταξύ υψηλής και χαμηλής ταχύτητας, τότε μπορούμε να επιλέξουμε γρήγορη έξοδο.
Ορισμένες ακίδες GPIO στον ελεγκτή μας υποστηρίζουν True Open Drain (T) και High Sink Current (HS), όπως αναφέρεται στην παραπάνω εικόνα. Μια σημαντική διαφορά μεταξύ του Open Drain και του True Open Drain είναι ότι η έξοδος που συνδέεται με το ανοιχτό σύστημα αποστράγγισης δεν μπορεί να τραβηχτεί υψηλότερη από την τάση λειτουργίας του μικροελεγκτή (Vdd), ενώ ένας πραγματικός ακροδέκτης εξόδου αποστράγγισης μπορεί να τραβηχτεί υψηλότερος από το Vdd. Καρφίτσες με υψηλή ικανότητα νεροχύτη σημαίνει ότι μπορεί να βυθιστεί περισσότερο ρεύμα. Το ρεύμα πηγής και νεροχύτη οποιουδήποτε ακροδέκτη GPIO HS είναι 20mA, ενώ το καλώδιο τροφοδοσίας μπορεί να καταναλώσει έως και 100 mA.
Ρίνοντας μια πιο προσεκτική ματιά στην παραπάνω εικόνα, θα παρατηρήσετε ότι σχεδόν όλες οι ακίδες GPIO είναι τύπου High Sink Current (HS) εκτός από τα PB4 και PB5 που είναι True Open Drain Type (T). Αυτό σημαίνει ότι αυτοί οι πείροι δεν μπορούν να κατασκευαστούν ψηλά, δεν θα μπορούν να παρέχουν 3.3V ακόμη και όταν ο πείρος είναι ψηλός. Γι 'αυτό το ενσωματωμένο καλώδιο συνδέεται σε 3.3V και γειωθεί μέσω PB5 αντί να το τροφοδοτεί απευθείας από τον πείρο GPIO.
Ανατρέξτε στη σελίδα 28 στο φύλλο δεδομένων για τη λεπτομερή περιγραφή του pin. Όπως αναφέρθηκε στην παραπάνω εικόνα, το PA1 διαμορφώνεται αυτόματα ως ασθενές pull-up και δεν συνιστάται να χρησιμοποιείται ως pin εξόδου. Εν πάση περιπτώσει μπορεί να χρησιμοποιηθεί ως πινέζα εισόδου μαζί με ένα μπουτόν, αλλά αποφάσισα να χρησιμοποιήσω το PA2 απλώς για να προσπαθήσω να ενεργοποιήσω το pull up από το πρόγραμμα. Αυτά είναι μόνο μερικά βασικά πράγματα που θα είναι χρήσιμα όταν γράφουμε πολύ πιο περίπλοκα προγράμματα. Προς το παρόν, είναι εντάξει αν πολλά πράγματα αναπηδούν από το κεφάλι σας, θα το βάλουμε σε άλλα σεμινάρια.
Προγραμματισμός STM8S για είσοδο και έξοδο GPIO με χρήση SPL
Δημιουργήστε ένα χώρο εργασίας και ένα νέο έργο όπως συζητήσαμε στο πρώτο μας σεμινάριο. Μπορείτε είτε να προσθέσετε όλα τα αρχεία κεφαλίδας και προέλευσης είτε να προσθέσετε μόνο τα αρχεία gpio, config και stm8s. Ανοίξτε το αρχείο main.c και ξεκινήστε να γράφετε το πρόγραμμά σας.
Βεβαιωθείτε ότι έχετε συμπεριλάβει τα αρχεία κεφαλίδας όπως φαίνεται στην παραπάνω εικόνα. Ανοίξτε το αρχείο main.c και ξεκινήστε τον κωδικό. Ο πλήρης κωδικός main.c βρίσκεται στο κάτω μέρος αυτής της σελίδας και θα μπορείτε επίσης να κατεβάσετε το αρχείο έργου από εκεί. Η εξήγηση του κώδικα έχει ως εξής, μπορείτε επίσης να ανατρέξετε στο εγχειρίδιο χρήσης του SPL ή στο βίντεο που είναι συνδεδεμένο στο κάτω μέρος αυτής της σελίδας εάν έχετε σύγχυση σχετικά με το τμήμα κωδικοποίησης.
Απενεργοποίηση της απαιτούμενης θύρας
Ξεκινάμε το πρόγραμμά μας με την απενεργοποίηση των απαιτούμενων λιμένων Όπως συζητήσαμε νωρίτερα, κάθε καρφίτσα GPIO θα έχει πολλές άλλες λειτουργίες που σχετίζονται με αυτό εκτός από το να λειτουργεί σαν κανονική είσοδος και έξοδος. Εάν αυτές οι καρφίτσες έχουν χρησιμοποιηθεί προηγουμένως για κάποιες άλλες εφαρμογές, τότε θα πρέπει να είναι De-Initialized προτού τις χρησιμοποιήσουμε. Δεν είναι υποχρεωτικό, ωστόσο, είναι μια καλή πρακτική. Οι ακόλουθες δύο γραμμές κώδικα χρησιμοποιούνται για την απενεργοποίηση της θύρας A και της θύρας B. Απλώς χρησιμοποιήστε τη σύνταξη GPIO_DeInit (GPIOx). και αναφέρατε το όνομα της θύρας στη θέση του x.
GPIO_DeInit (GPIOA); // προετοιμασία της θύρας A για εργασία GPIO_DeInit (GPIOB). // προετοιμάστε το Port B για εργασία
Δήλωση GPIO εισόδου και εξόδου
Στη συνέχεια, πρέπει να δηλώσουμε ποιες ακίδες θα χρησιμοποιηθούν ως είσοδος και ποιες ως έξοδο. Στην περίπτωσή μας, ο πείρος PA2 θα χρησιμοποιηθεί ως είσοδος, θα δηλώσουμε επίσης αυτόν τον πείρο με εσωτερικό Pull-up έτσι ώστε να μην χρειάζεται να τον χρησιμοποιήσουμε εξωτερικά. Η σύνταξη είναι GPIO_Init (GPIOx, GPIO_PIN_y, GPIO_PIN_MODE_z). . Όπου x είναι το όνομα της θύρας, το y είναι ο αριθμός pin και το z είναι η λειτουργία PinIO GPIO.
// Δηλώστε το PA2 ως pin pull up pin GPIO_Init (GPIOA, GPIO_PIN_2, GPIO_MODE_IN_PU_IT).
Στη συνέχεια, πρέπει να δηλώσουμε τους ακροδέκτες PA3 και PB5 ως έξοδο. Και πάλι είναι δυνατοί πολλοί τύποι δήλωσης εξόδου, αλλά θα χρησιμοποιούμε το "GPIO_MODE_OUT_PP_LOW_SLOW" που σημαίνει ότι θα το δηλώσουμε ως πείρο εξόδου τύπου push-pull με αργή ταχύτητα. Και από προεπιλογή, η τιμή θα είναι χαμηλή. Η σύνταξη θα είναι η ίδια.
GPIO_Init (GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_LOW_SLOW); // Δηλώστε το PB5 ως push pull Pin pin GPIO_Init (GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_SLOW);
Το παρακάτω στιγμιότυπο από το εγχειρίδιο χρήστη SPL αναφέρει όλες τις πιθανές λειτουργίες GPIO (z).
Άπειρο βρόχο
Μετά τη δήλωση ακίδων, πρέπει να δημιουργήσουμε έναν άπειρο βρόχο μέσα στον οποίο θα συνεχίσουμε να αναβοσβήνουμε για πάντα τη λυχνία LED και να παρακολουθούμε την κατάσταση του μπουτόν για εναλλαγή του LED. Ο άπειρος βρόχος μπορεί είτε να δημιουργηθεί με λίγο (1) είτε με ένα για (;;) . Εδώ έχω χρησιμοποιήσει ενώ (1).
ενώ (1) {}
Έλεγχος της κατάστασης του πείρου εισόδου
Πρέπει να ελέγξουμε την κατάσταση του πείρου εισόδου, η σύνταξη που πρέπει να κάνουμε είναι GPIO_ReadInputPin (GPIOx, GPIO_PIN_y). όπου x είναι το όνομα της θύρας και y είναι ο αριθμός pin. Εάν ο πείρος είναι υψηλός, θα πάρουμε το «1» και εάν ο πείρος είναι χαμηλός, θα λάβουμε ένα «0». Έχουμε συνηθίσει μέσα σε έναν βρόχο if για να ελέγξουμε εάν ο πείρος είναι υψηλός ή χαμηλός.
if (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // εάν πατηθεί το κουμπί
Κάνοντας έναν ακροδέκτη GPIO υψηλό ή χαμηλό
Για να φτιάξουμε έναν ακροδέκτη GPIO Υψηλό ή Χαμηλό, μπορούμε να χρησιμοποιήσουμε το GPIO_WriteHigh (GPIOx, GPIO_PIN_y). και GPIO_WriteLow (GPIOx, GPIO_PIN_y); αντίστοιχα. Εδώ έχουμε κάνει το LED να ανάβει αν πατηθεί το κουμπί και να σβήσει αν δεν πατηθεί το κουμπί.
if (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // εάν πατηθεί το κουμπί GPIO_WriteLow (GPIOA, GPIO_PIN_3); // LED ON άλλο GPIO_WriteHigh (GPIOA, GPIO_PIN_3); // LED OFF
Εναλλαγή καρφίτσας GPIO
Για εναλλαγή ενός ακροδέκτη GPIO, έχουμε GPIO_WriteReverse (GPIOx, GPIO_PIN_y). Η κλήση αυτής της λειτουργίας θα αλλάξει την κατάσταση του πείρου εξόδου. Εάν ο πείρος είναι υψηλός, θα αλλάξει σε χαμηλός και αν είναι χαμηλός, θα αλλάξει σε υψηλό. Χρησιμοποιούμε αυτήν τη λειτουργία για να αναβοσβήσουμε το ενσωματωμένο LED στο PB5.
GPIO_WriteReverse (GPIOB, GPIO_PIN_5);
Λειτουργία καθυστέρησης
Σε αντίθεση με το Arduino, ο κοσμικός μεταγλωττιστής δεν έχει προκαθορισμένη λειτουργία καθυστέρησης. Πρέπει λοιπόν να δημιουργήσουμε μόνοι μας. Η λειτουργία καθυστέρησης μου δίνεται παρακάτω. Η τιμή για την καθυστέρηση θα ληφθεί στη μεταβλητή ms και θα χρησιμοποιήσουμε δύο για βρόχο για αναμονή ή εκτέλεση προγράμματος. Όπως το _asm ("nop") είναι μια εντολή συναρμολόγησης που δεν σημαίνει καμία λειτουργία. Αυτό σημαίνει ότι ο ελεγκτής θα κάνει βρόχο στο βρόχο χωρίς να κάνει καμία λειτουργία, δημιουργώντας έτσι καθυστέρηση
κενή καθυστέρηση (int ms) // Ορισμός συνάρτησης {int i = 0; int j = 0; για (i = 0; i <= ms; i ++) {για (j = 0; j <120; j ++) // Nop = Fosc / 4 _asm ("nop"); // Εκτελέστε καμία λειτουργία // κωδικός συναρμολόγησης}}
Μεταφόρτωση και δοκιμή του προγράμματος
Τώρα που το πρόγραμμά μας είναι έτοιμο, μπορούμε να το ανεβάσουμε και να το δοκιμάσουμε. Μετά τη μεταφόρτωση, το υλικό μου λειτούργησε όπως αναμενόταν. Το κόκκινο LED του οχήματος αναβοσβήνει για κάθε 500 χιλιοστά του δευτερολέπτου και το εξωτερικό πράσινο LED ανάβει κάθε φορά που πατάω το διακόπτη.
Η πλήρης εργασία βρίσκεται στο παρακάτω βίντεο. Μόλις φτάσετε σε αυτό το σημείο, μπορείτε να προσπαθήσετε να συνδέσετε το διακόπτη και το LED σε διαφορετικές ακίδες και να ξαναγράψετε τον κωδικό για να κατανοήσετε την έννοια. Μπορείτε επίσης να παίξετε με το χρονοδιάγραμμα καθυστέρησης για να ελέγξετε αν έχετε κατανοήσει σαφώς τις έννοιες.
Εάν έχετε οποιεσδήποτε ερωτήσεις, αφήστε τις στην παρακάτω ενότητα σχολίων και για άλλες τεχνικές ερωτήσεις, μπορείτε να χρησιμοποιήσετε τα φόρουμ μας. Σας ευχαριστούμε που ακολουθήσατε, θα τα πούμε στο επόμενο σεμινάριο.