- Τι είναι το σήμα PWM;
- Προγραμματισμός PIC για δημιουργία PWM σε καρφίτσες GPIO
- Διάγραμμα κυκλώματος
- Προσομοίωση
- Ρύθμιση υλικού για τον έλεγχο του Servo Motor χρησιμοποιώντας PIC Microcontroller
Η παραγωγή σήματος PWM είναι ένα ζωτικό εργαλείο σε κάθε ενσωματωμένο οπλοστάσιο μηχανικών, έρχονται σε πολύ βολικό για πολλές εφαρμογές όπως ο έλεγχος της θέσης του σερβο κινητήρα, η εναλλαγή λίγων ηλεκτρονικών IC ισχύος σε μετατροπείς / μετατροπείς και ακόμη και για έναν απλό έλεγχο φωτεινότητας LED. Στους μικροελεγκτές PIC μπορούν να δημιουργηθούν σήματα PWM χρησιμοποιώντας τις μονάδες Σύγκριση, Σύλληψη και PWM (CCP) ρυθμίζοντας τα απαιτούμενα Μητρώα, έχουμε ήδη μάθει πώς να το κάνουμε αυτό στο σεμινάριο PIC PWM. Υπάρχει όμως ένα σημαντικό μειονέκτημα με αυτήν τη μέθοδο.
Το PIC16F877A μπορεί να δημιουργήσει σήματα PWM μόνο στις ακίδες RC1 και RC2, εάν χρησιμοποιούμε τις μονάδες CCP. Ωστόσο, ενδέχεται να συναντήσουμε καταστάσεις, όπου χρειαζόμαστε περισσότερες ακίδες για να έχουμε λειτουργικότητα PWM. Για παράδειγμα, στην περίπτωσή μου, θέλω να ελέγξω 6 σερβοκινητήρες RC για το έργο ρομποτικού βραχίονα για το οποίο η μονάδα CCP είναι απελπιστική. Σε αυτά τα σενάρια μπορούμε να προγραμματίσουμε τους ακροδέκτες GPIO για την παραγωγή σημάτων PWM χρησιμοποιώντας χρονοδιακόπτες. Με αυτόν τον τρόπο μπορούμε να δημιουργήσουμε τόσα σήματα PWM με οποιοδήποτε απαιτούμενο pin. Υπάρχουν επίσης και άλλες παραβιάσεις υλικού όπως η χρήση πολυπλέκτη IC, αλλά γιατί να επενδύσετε σε υλικό όταν το ίδιο μπορεί να επιτευχθεί μέσω προγραμματισμού. Έτσι, σε αυτό το σεμινάριο θα μάθουμε πώς να μετατρέπουμε έναν ακροδέκτη PIC GPIO σε έναν ακροδέκτη PWM και να τον δοκιμάσουμε θα τον προσομοιώσουμε σε πρωτεό με ψηφιακό παλμογράφο και επίσηςελέγξτε τη θέση του σερβο κινητήρα χρησιμοποιώντας το σήμα PWM και μεταβάλλετε τον κύκλο λειτουργίας του μεταβάλλοντας ένα ποτενσιόμετρο.
Τι είναι το σήμα PWM;
Προτού αναφερθούμε στις λεπτομέρειες, ας δούμε λίγο τι είναι τα σήματα PWM. Το Pulse Width Modulation (PWM) είναι ένα ψηφιακό σήμα που χρησιμοποιείται συχνότερα στα κυκλώματα ελέγχου. Αυτό το σήμα ρυθμίζεται υψηλό (5v) και χαμηλό (0v) σε προκαθορισμένο χρόνο και ταχύτητα. Ο χρόνος κατά τον οποίο το σήμα παραμένει υψηλό ονομάζεται "on time" και ο χρόνος κατά τον οποίο το σήμα παραμένει χαμηλό ονομάζεται "off time". Υπάρχουν δύο σημαντικές παράμετροι για ένα PWM όπως συζητείται παρακάτω:
Κύκλος λειτουργίας του PWM
Το ποσοστό χρόνου στο οποίο το σήμα PWM παραμένει ΥΨΗΛΟ (στην ώρα) ονομάζεται κύκλος λειτουργίας. Εάν το σήμα είναι πάντα ΕΝΕΡΓΟ, βρίσκεται σε κύκλο λειτουργίας 100% και εάν είναι πάντα σβηστό, είναι κύκλος λειτουργίας 0%.
Κύκλος λειτουργίας = Χρόνος ενεργοποίησης / (Χρόνος ενεργοποίησης + χρόνος απενεργοποίησης)
Μεταβλητό όνομα |
Αναφέρεται σε |
PWM_Συχνότητα |
Συχνότητα του σήματος PWM |
T_TOTAL |
Συνολικός χρόνος που απαιτείται για έναν πλήρη κύκλο PWM |
ΤΟΝΟΣ |
Την ώρα του σήματος PWM |
T_OFF |
Απενεργοποίηση του σήματος PWM |
Κύκλος καθηκόντων |
Κύκλος λειτουργίας του σήματος PWM |
Λοιπόν, ας κάνουμε τα μαθηματικά.
Αυτοί είναι οι τυπικοί τύποι όπου η συχνότητα είναι απλά η αμοιβαιότητα του χρόνου. Η τιμή της συχνότητας πρέπει να αποφασιστεί και να οριστεί από τον χρήστη με βάση την απαίτησή του / της.
T_TOTAL = (1 / PWM_Frequency)
Όταν ο χρήστης αλλάζει την τιμή Duty cycle, το πρόγραμμά μας θα προσαρμόζει αυτόματα την ώρα T_ON και την ώρα T_OFF ανάλογα με αυτήν. Έτσι, οι παραπάνω τύποι μπορούν να χρησιμοποιηθούν για τον υπολογισμό του T_ON με βάση την τιμή του Duty_Cycle και του T_TOTAL.
T_ON = (Duty_Cycle * T_TOTAL) / 100
Δεδομένου ότι ο συνολικός χρόνος του σήματος PWM για έναν πλήρη κύκλο θα είναι το άθροισμα του χρόνου και του χρόνου εκτός λειτουργίας. Μπορούμε να υπολογίσουμε τον χρόνο εκτός λειτουργίας T_OFF όπως φαίνεται παραπάνω.
T_OFF = T_TOTAL - T_ON
Με αυτούς τους τύπους κατά νου μπορούμε να αρχίσουμε τον προγραμματισμό του μικροελεγκτή PIC. Το πρόγραμμα περιλαμβάνει το PIC Timer Module και PIC ADC Module για τη δημιουργία ενός σήματος PWM με διαφορετικό κύκλο Duty σύμφωνα με την τιμή ADC από το POT. Εάν είστε νέοι στη χρήση αυτών των ενοτήτων, συνιστάται να διαβάσετε το κατάλληλο σεμινάριο κάνοντας κλικ στους υπερσυνδέσμους.
Προγραμματισμός PIC για δημιουργία PWM σε καρφίτσες GPIO
Το πλήρες πρόγραμμα για αυτό το σεμινάριο βρίσκεται στο κάτω μέρος του ιστότοπου όπως πάντα. Σε αυτήν την ενότητα ας καταλάβουμε πώς γράφεται το πρόγραμμα. Όπως όλα τα προγράμματα, ξεκινάμε ρυθμίζοντας τα bits διαμόρφωσης. Έχω χρησιμοποιήσει την επιλογή προβολών μνήμης για να την ορίσω.
// CONFIG #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT απενεργοποιημένο) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT απενεργοποιημένη) #pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled) #pragma config LVP = OFF // Χαμηλής τάσης (μονής τροφοδοσίας) In-Circuit Serial Programming Enable bit (RB3 is digital I / O, HV σε MCLR πρέπει να χρησιμοποιείται για προγραμματισμό) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bit (Απενεργοποίηση προστασίας; όλη η μνήμη προγράμματος μπορεί να γραφτεί από τον έλεγχο EECON) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) // Οι δηλώσεις διαμόρφωσης #pragma πρέπει να προηγούνται του αρχείου έργου. // Χρησιμοποιήστε τα αθροίσματα του έργου αντί του #define για ON και OFF. #περιλαμβάνω
Στη συνέχεια, αναφέρουμε τη συχνότητα ρολογιού που χρησιμοποιείται στο υλικό, εδώ το υλικό μου χρησιμοποιεί κρύσταλλα 20MHz, μπορείτε να εισαγάγετε την τιμή με βάση το υλικό σας. Ακολουθεί η τιμή συχνότητας του σήματος PWM. Εφόσον ο στόχος μου εδώ είναι ο έλεγχος ενός σερβο κινητήρα RC χόμπι που απαιτεί συχνότητα PWM 50Hz έχω ορίσει 0,05KHz ως τιμή συχνότητας, μπορείτε επίσης να το αλλάξετε με βάση τις απαιτήσεις της εφαρμογής σας.
#define _XTAL_FREQ 20000000 #define PWM_Frequency 0,05 // σε KHz (50Hz)
Τώρα, που έχουμε την τιμή Συχνότητας, μπορούμε να υπολογίσουμε το T_TOTAL χρησιμοποιώντας τους παραπάνω αναφερόμενους τύπους. Το αποτέλεσμα βυθίζεται κατά 10 για να πάρει την αξία του χρόνου σε χιλιοστά δευτερολέπτων. Στην περίπτωσή μου η τιμή του T_TOTAL θα είναι 2 milli seconds.
int T_TOTAL = (1 / PWM_Frequency) / 10; // υπολογισμός Συνολικού χρόνου από τη συχνότητα (σε χιλιοστά του δευτερολέπτου)) // 2msec
Μετά από αυτό, αρχικοποιούμε τις ενότητες ADC για την ανάγνωση της θέσης του Ποτενσιόμετρου όπως συζητήθηκε στο μάθημα ADC PIC. Έπειτα έχουμε τη ρουτίνα υπηρεσίας διακοπής που θα καλείται κάθε φορά, ο χρονοδιακόπτης ξεχειλίζει θα επανέλθουμε σε αυτό αργότερα, για τώρα ας δούμε την κύρια λειτουργία
Μέσα στην κύρια λειτουργία διαμορφώνουμε τη μονάδα χρονοδιακόπτη. Εδώ έχω ρυθμίσει τη μονάδα Timer να υπερχειλίζει για κάθε 0.1ms. Η τιμή για το χρόνο μπορεί να υπολογιστεί χρησιμοποιώντας τους παρακάτω τύπους
RegValue = 256 - ((Καθυστέρηση * Fosc) / (Prescalar * 4)) καθυστέρηση σε δευτερόλεπτο και Fosc σε hz
Στην περίπτωσή μου για καθυστέρηση 0,0001 δευτερολέπτων (0,1 ms) με prescalar 64 και Fosc 20MHz η τιμή του μητρώου μου (TMR0) θα πρέπει να είναι 248. Έτσι, η διαμόρφωση μοιάζει με αυτό
/ ***** Διαμόρφωση θύρας για χρονοδιακόπτη ****** / OPTION_REG = 0b00000101; // Timer0 με εξωτερικό freq και 64 ως prescalar // Ενεργοποιεί επίσης PULL UPs TMR0 = 248; // Φορτώστε την τιμή χρόνου για 0,0001s. delayValue μπορεί να είναι μεταξύ 0-256 μόνο TMR0IE = 1; // Ενεργοποίηση bit διακοπής χρονοδιακόπτη στο μητρώο PIE1 GIE = 1; // Ενεργοποίηση καθολικής διακοπής PEIE = 1; // Ενεργοποίηση της περιφερειακής διακοπής / *********** ______ *********** /
Στη συνέχεια, θα πρέπει να ρυθμίσετε τη διαμόρφωση εισόδου και εξόδου. Εδώ χρησιμοποιούμε τον ακροδέκτη AN0 για την ανάγνωση της τιμής ADC και των PORTD για την έξοδο των σημάτων PWM. Ξεκινήστε λοιπόν ως καρφίτσες εξόδου και χαμηλώστε τις χρησιμοποιώντας τις παρακάτω γραμμές κώδικα.
/ ***** Διαμόρφωση θύρας για I / O ****** / TRISD = 0x00; // Διδάξτε στο MCU ότι όλες οι ακίδες στο PORT D έχουν έξοδο PORTD = 0x00; // Αρχικοποιήστε όλες τις καρφίτσες στο 0 / *********** ______ *********** /
Μέσα στο άπειρο , ενώ βρόχο, θα πρέπει να υπολογίσει την αξία του στο χρόνο (T_ON) από τον κύκλο εργασίας. Ο εγκαίρως και καθήκον του κύκλου ποικίλει ανάλογα με τη θέση της γλάστρας και έτσι το κάνουμε επανειλημμένα στο εσωτερικό του , ενώ βρόχου, όπως φαίνεται παρακάτω. 0,0976 είναι η τιμή που πρέπει να πολλαπλασιαστεί με 1024 για να πάρει 100 και για να υπολογίσουμε το T_ON το έχουμε πολλαπλασιάσει με 10 για να πάρουμε την τιμή σε χιλιοστά δευτερολέπτων.
ενώ (1) { POT_val = (ADC_Read (0)); // Διαβάστε την τιμή του POT χρησιμοποιώντας ADC Duty_cycle = (POT_val * 0,0976). // Χάρτης 0 έως 1024 έως 0 έως 100 T_ON = ((Duty_cycle * T_TOTAL) * 10/100); // Υπολογίστε την ώρα χρησιμοποιώντας τη μονάδα τύπων σε milli seconds __delay_ms (100); }
Δεδομένου ότι ο χρονοδιακόπτης έχει ρυθμιστεί να υπερβαίνει τη ροή για κάθε 0,1 ms, ο ISR ρουτίνας διακοπής του χρονοδιακόπτη θα καλείται για κάθε 0.1 ms. Μέσα στη ρουτίνα της υπηρεσίας χρησιμοποιούμε μια μεταβλητή που ονομάζεται μέτρηση και την αυξάνουμε για κάθε 0,1ms. Με αυτόν τον τρόπο μπορούμε να παρακολουθούμε το χρόνο. Για να μάθετε περισσότερα σχετικά με τις Διακοπές στο μικροελεγκτή PIC, ακολουθήστε τους συνδέσμους
if (TMR0IF == 1) // Η σημαία χρονοδιακόπτη ενεργοποιήθηκε λόγω υπερχείλισης χρονοδιακόπτη -> ρυθμίστηκε σε υπερχείλιση για κάθε 0,1 ms { TMR0 = 248; // Φορτώστε το χρονόμετρο Τιμή TMR0IF = 0; // Εκκαθάριση πλήθους σημαίας διακοπής χρονοδιακόπτη ++; // Αύξηση μέτρησης για κάθε 0.1ms -> count / 10 θα δώσει τιμή μέτρησης σε ms }
Τέλος, ήρθε η ώρα να αλλάξετε τον ακροδέκτη GPIO με βάση την τιμή T_ON και T_OFF. Έχουμε τη μεταβλητή μέτρησης που παρακολουθεί τον χρόνο σε χιλιοστά δευτερολέπτων. Χρησιμοποιούμε λοιπόν αυτήν τη μεταβλητή για να ελέγξουμε αν ο χρόνος είναι μικρότερος από τον χρόνο , αν ναι τότε διατηρούμε τον ακροδέκτη GPIO αλλιώς τον απενεργοποιούμε και τον απενεργοποιούμε μέχρι να ξεκινήσει ο νέος κύκλος. Αυτό μπορεί να γίνει συγκρίνοντάς το με το συνολικό χρόνο ενός κύκλου PWM. Ο κώδικας για να κάνετε το ίδιο φαίνεται παρακάτω
if (count <= (T_ON)) // Εάν ο χρόνος είναι μικρότερος από τον χρόνο RD1 = 1; // Ενεργοποιήστε το GPIO αλλιώς RD1 = 0; // Διαφορετικά, απενεργοποιήστε το GPIO εάν (count> = (T_TOTAL * 10)) // Κρατήστε το απενεργοποιημένο έως ότου ξεκινήσει ένας νέος κύκλος = 0;
Διάγραμμα κυκλώματος
Το διάγραμμα κυκλώματος για τη δημιουργία PWM με ακροδέκτη GPIO του μικροελεγκτή PIC είναι πραγματικά απλό, απλώς τροφοδοτήστε το PIC με ταλαντωτή και συνδέστε το ποτενσιόμετρο με τον ακροδέκτη AN0 και το Servo Motor στην ακίδα RD1, μπορούμε να χρησιμοποιήσουμε τον ακροδέκτη GPIO για να λάβουμε το σήμα PWM, έχω επιλέξει RD1 μόλις τυχαία Τόσο το ποτενσιόμετρο όσο και ο κινητήρας Servo τροφοδοτούνται από 5V που ρυθμίζεται από το 7805 όπως φαίνεται παρακάτω στο διάγραμμα κυκλώματος.
Προσομοίωση
Για την προσομοίωση του έργου, χρησιμοποίησα το λογισμικό μου. Δημιουργήστε το κύκλωμα που φαίνεται παρακάτω και συνδέστε τον κωδικό με την προσομοίωσή σας και εκτελέστε τον. Θα πρέπει να λάβετε ένα σήμα PWM στον ακροδέκτη RD1 GPIO σύμφωνα με το πρόγραμμά μας και ο κύκλος λειτουργίας του PWM θα πρέπει να ελέγχεται με βάση τη θέση του ποτενσιόμετρου. Το παρακάτω GIF δείχνει πώς το σήμα PWM και ο σερβοκινητήρας αποκρίνονται όταν η τιμή ADC αλλάζει μέσω του ποτενσιόμετρου.
Ρύθμιση υλικού για τον έλεγχο του Servo Motor χρησιμοποιώντας PIC Microcontroller
Η πλήρης ρύθμιση του υλικού μου φαίνεται παρακάτω, για άτομα που ακολουθούν τα μαθήματά μου, αυτός ο πίνακας πρέπει να φαίνεται οικείος, είναι ο ίδιος πίνακας που έχω χρησιμοποιήσει σε όλα τα σεμινάριά μου μέχρι στιγμής. Μπορείτε να ανατρέξετε στο φροντιστήριο LED που αναβοσβήνει εάν ενδιαφέρεστε να μάθετε πώς το δημιουργώ. Διαφορετικά, απλώς ακολουθήστε το παραπάνω διάγραμμα κυκλώματος και όλα πρέπει να λειτουργούν καλά.
Ανεβάστε το πρόγραμμα και τροποποιήστε το ποτενσιόμετρο και θα πρέπει να δείτε το σερβο να αλλάζει τη θέση με βάση τη θέση του ποτενσιόμετρου. Η πλήρης εργασία του έργου εμφανίζεται στο βίντεο που δίνεται στο τέλος αυτής της σελίδας. Ελπίζω ότι καταλάβατε το έργο και σας άρεσε να χτίσετε, αν έχετε ερωτήσεις, μη διστάσετε να τα δημοσιεύσετε στο φόρουμ και θα προσπαθήσω το καλύτερο για να απαντήσω.
Σκοπεύω να προωθήσω αυτό το έργο προσθέτοντας επιλογές για τον έλεγχο πολλαπλών σερβοκινητήρων και έτσι δημιουργώ ένα ρομποτικό βραχίονα από αυτό, παρόμοιο με το Arduino Robotic Arm που έχουμε ήδη κατασκευάσει. Λοιπόν, μέχρι τότε να δεις !!