- Τι είναι το πρωτόκολλο επικοινωνίας I2C;
- Πώς λειτουργεί η επικοινωνία I2C;
- Πού να χρησιμοποιήσετε την επικοινωνία I2C;
- I2C με PIC16F877a χρησιμοποιώντας XC8 Compiler
- Προγραμματισμός με χρήση των αρχείων κεφαλίδας I2C:
- Προσομοίωση πρωτεϊνών:
Οι μικροελεγκτές PIC είναι μια ισχυρή πλατφόρμα που παρέχεται από το μικροτσίπ για ενσωματωμένα έργα, η ευέλικτη φύση του το έχει κάνει να βρει τρόπους σε πολλές εφαρμογές και η φάση συνεχίζει. Εάν ακολουθήσατε τα σεμινάρια PIC μας, τότε θα έχετε παρατηρήσει ότι έχουμε ήδη καλύψει ένα ευρύ φάσμα μαθημάτων για τον μικροελεγκτή PIC ξεκινώντας από τα βασικά. Από τώρα, έχουμε καλύψει τα βασικά που μπορούμε να πάρουμε σε πιο ενδιαφέροντα πράγματα όπως η πύλη επικοινωνίας.
Στο τεράστιο σύστημα ενσωματωμένων εφαρμογών, κανένας μικροελεγκτής δεν μπορεί να εκτελέσει όλες τις δραστηριότητες από μόνη της. Σε κάποιο στάδιο του χρόνου πρέπει να επικοινωνήσει με άλλες συσκευές για να μοιραστεί πληροφορίες, υπάρχουν πολλοί διαφορετικοί τύποι πρωτοκόλλων επικοινωνίας για να μοιραστούν αυτές τις πληροφορίες, αλλά τα πιο χρησιμοποιημένα είναι USART, IIC, SPI και CAN. Κάθε πρωτόκολλο επικοινωνίας έχει το δικό του πλεονέκτημα και μειονέκτημα. Ας επικεντρωθούμε στο τμήμα IIC για τώρα, καθώς αυτό θα μάθουμε σε αυτό το σεμινάριο.
Τι είναι το πρωτόκολλο επικοινωνίας I2C;
Ο όρος IIC σημαίνει " Inter Integrated Circuits ". Κανονικά δηλώνεται ως I2C ή I τετράγωνο C ή ακόμα και ως πρωτόκολλο διασύνδεσης 2 καλωδίων (TWI) σε ορισμένα σημεία, αλλά όλα σημαίνει το ίδιο. Το I2C είναι ένα σύγχρονο πρωτόκολλο επικοινωνίας που σημαίνει, και οι δύο συσκευές που μοιράζονται τις πληροφορίες πρέπει να μοιράζονται ένα κοινό σήμα ρολογιού. Έχει μόνο δύο καλώδια για την κοινή χρήση πληροφοριών από τις οποίες το ένα χρησιμοποιείται για το σήμα κόκορας και το άλλο χρησιμοποιείται για την αποστολή και λήψη δεδομένων.
Πώς λειτουργεί η επικοινωνία I2C;
Η επικοινωνία I2C παρουσιάστηκε για πρώτη φορά από τον Phillips. Όπως ειπώθηκε νωρίτερα, έχει δύο καλώδια, αυτά τα δύο καλώδια θα συνδεθούν σε δύο συσκευές. Εδώ μια συσκευή ονομάζεται κύριος και η άλλη συσκευή ονομάζεται σκλάβος. Η επικοινωνία πρέπει και θα συμβαίνει πάντα μεταξύ δύο Δασκάλων και Σκλάβων. Το πλεονέκτημα της επικοινωνίας I2C είναι ότι περισσότεροι από ένας σκλάβοι μπορούν να συνδεθούν με έναν Master.
Η πλήρης επικοινωνία πραγματοποιείται μέσω αυτών των δύο καλωδίων, δηλαδή Serial Clock (SCL) και Serial Data (SDA).
Serial Clock (SCL): Μοιράζεται το σήμα ρολογιού που δημιουργείται από τον κύριο με το slave
Σειριακά δεδομένα (SDA): Στέλνει τα δεδομένα από και προς το Master και το slave.
Ανά πάσα στιγμή μόνο ο πλοίαρχος θα μπορεί να ξεκινήσει την επικοινωνία. Δεδομένου ότι υπάρχουν περισσότεροι από ένας σκλάβοι στο λεωφορείο, ο πλοίαρχος πρέπει να αναφέρεται σε κάθε σκλάβος χρησιμοποιώντας διαφορετική διεύθυνση. Όταν απευθύνεται μόνο το salve με τη συγκεκριμένη διεύθυνση θα απαντήσει πίσω με τις πληροφορίες, ενώ οι άλλοι θα σταματήσουν. Με αυτόν τον τρόπο μπορούμε να χρησιμοποιήσουμε το ίδιο λεωφορείο για επικοινωνία με πολλές συσκευές.
Πού να χρησιμοποιήσετε την επικοινωνία I2C;
Η επικοινωνία I2C χρησιμοποιείται μόνο για επικοινωνία μικρής απόστασης. Είναι σίγουρα αξιόπιστο σε ένα βαθμό, δεδομένου ότι διαθέτει συγχρονισμένο παλμό ρολογιού για να το κάνει έξυπνο. Αυτό το πρωτόκολλο χρησιμοποιείται κυρίως για επικοινωνία με αισθητήρα ή άλλες συσκευές που πρέπει να στέλνουν πληροφορίες σε έναν κύριο. Είναι πολύ βολικό όταν ένας μικροελεγκτής πρέπει να επικοινωνεί με πολλές άλλες υπομονάδες χρησιμοποιώντας τουλάχιστον μόνο καλώδια. Αν ψάχνετε για επικοινωνία μεγάλης εμβέλειας, πρέπει να δοκιμάσετε το RS232 και αν ψάχνετε για πιο αξιόπιστη επικοινωνία, θα πρέπει να δοκιμάσετε το πρωτόκολλο SPI.
I2C με PIC16F877a χρησιμοποιώντας XC8 Compiler
Αρκετές εισαγωγές, ας μπείτε σε αυτό και να μάθουμε πώς μπορούμε να χρησιμοποιήσουμε έναν μικροελεγκτή για την εκτέλεση της επικοινωνίας I2C. Πριν ξεκινήσουμε να καταστήσουμε σαφές ότι αυτό το σεμινάριο μιλάει μόνο για το I2C στο PIC16F877a χρησιμοποιώντας μεταγλωττιστή XC8, η διαδικασία θα είναι η ίδια για άλλους μικροελεγκτές αλλά ενδέχεται να απαιτηθούν μικρές αλλαγές. Επίσης, θυμηθείτε ότι για προχωρημένους μικροελεγκτές όπως η σειρά PIC18F, ο ίδιος ο μεταγλωττιστής μπορεί να έχει κάποια ενσωματωμένη βιβλιοθήκη για να χρησιμοποιεί τις λειτουργίες I2C, αλλά για PIC16F877A τίποτα τέτοιο δεν υπάρχει, ας φτιάξουμε μόνοι μας. Η βιβλιοθήκη που εξηγείται εδώ θα δοθεί ως αρχείο κεφαλίδας για λήψη στο κάτω μέρος, το οποίο μπορεί να χρησιμοποιηθεί για την επικοινωνία του PIC16F877A με άλλες συσκευές I2C.
Όπως πάντα, το καλύτερο μέρος για να ξεκινήσετε τα πάντα είναι το δελτίο δεδομένων μας. Αναζητήστε λεπτομέρειες σχετικά με το I2C στο φύλλο δεδομένων και ελέγξτε ποιοι καταχωρητές πρέπει να διαμορφωθούν. Δεν πρόκειται να εξηγήσω λεπτομερώς, αφού το δελτίο δεδομένων το έχει ήδη κάνει για εσάς. Παρακάτω θα εξηγήσω τις διάφορες λειτουργίες που υπάρχουν στο αρχείο κεφαλίδας και την ευθύνη τους στο πρόγραμμα.
άκυρο I2C_ Αρχικοποίηση ()
Η συνάρτηση αρχικοποίησης χρησιμοποιείται για να πει στον μικροελεγκτή ότι πρόκειται να χρησιμοποιήσουμε το πρωτόκολλο I2C. Αυτό μπορεί να γίνει ρυθμίζοντας τα απαιτούμενα bits στο μητρώο SSPCON και SSPCON2. Το πρώτο βήμα θα ήταν να δηλώσετε τους ακροδέκτες IIC ως ακροδέκτες εισόδου, εδώ οι ακίδες RC3 και RC4 πρέπει να χρησιμοποιούνται για επικοινωνία I2C, επομένως τις δηλώνουμε ως ακίδες εισόδου. Στη συνέχεια θα πρέπει να ρυθμίσουμε τα SSPCON και SSPCON2 που είναι καταχωρητές ελέγχου MSSP. Λειτουργούμε το PIC σε κύρια λειτουργία IIC με συχνότητα ρολογιού FOSC / (4 * (SSPADD + 1)). Ανατρέξτε στους αριθμούς σελίδων του φύλλου δεδομένων που αναφέρονται στις παρακάτω γραμμές σχολίων για να κατανοήσετε γιατί ο συγκεκριμένος καταχωρητής ρυθμίζεται έτσι.
Έτσι στη συνέχεια πρέπει να ορίσουμε τη συχνότητα ρολογιού, η συχνότητα ρολογιού για διαφορετικές εφαρμογές μπορεί να διαφέρει, επομένως παίρνουμε την επιλογή από τον χρήστη μέσω της μεταβλητής feq_k και τη χρησιμοποιούμε στους τύπους μας για να ορίσουμε τον καταχωρητή SSPADD.
void I2C_Initialize (const unsigned long feq_K) // Ξεκινήστε το IIC ως κύριο { TRISC3 = 1; TRISC4 = 1; // Ορίστε τις καρφίτσες SDA και SCL ως ακίδες SSPCON = 0b00101000 // pg84 / 234 SSPCON2 = 0b00000000; // pg85 / 234 SSPADD = (_XTAL_FREQ / (4 * feq_K * 100)) - 1; // Ρύθμιση ταχύτητας ρολογιού pg99 / 234 SSPSTAT = 0b00000000; // σελ83 / 234 }
Άκυρο I2C_Hold ()
Η επόμενη σημαντική συνάρτηση είναι η συνάρτηση I2C_hold που χρησιμοποιείται για την αναστολή της εκτέλεσης της συσκευής έως ότου ολοκληρωθεί η τρέχουσα λειτουργία I2C. Θα πρέπει να ελέγξουμε εάν πρέπει να πραγματοποιηθούν οι λειτουργίες I2C πριν ξεκινήσουμε οποιαδήποτε νέα λειτουργία. Αυτό μπορεί να γίνει με τον έλεγχο των καταχωρητών SSPSTAT και SSPCON2. Το SSPSTAT περιέχει τις πληροφορίες σχετικά με την κατάσταση του διαύλου I2C.
Το πρόγραμμα μπορεί να φαίνεται να είναι λίγο περίπλοκο, δεδομένου ότι περιλαμβάνει χειριστή "και" και "ή". Όταν το σπάτε ως
SSPSTAT & 0b00000100 SSPCON2 & 0b00011111
Αυτό σημαίνει ότι διασφαλίζουμε ότι το 2 ο bit στο SSPSTAT είναι μηδέν και ομοίως τα bit από 0 έως 4 είναι μηδέν στο SSPCON2. Στη συνέχεια συνδυάζουμε όλα αυτά για να ελέγξουμε ότι το αποτέλεσμα είναι μηδέν. Εάν το αποτέλεσμα είναι μηδέν, το πρόγραμμα θα προχωρήσει, αν όχι, θα παραμείνει εκεί μέχρι να μηδενιστεί, δεδομένου ότι χρησιμοποιείται σε βρόχο λίγο .
άκυρο I2C_Hold () { ενώ ((SSPCON2 & 0b00011111) - (SSPSTAT & 0b00000100)); // ελέγξτε το σε μητρώα για να βεβαιωθείτε ότι το IIC δεν βρίσκεται σε εξέλιξη }
Άκυρο I2C_Begin () και άκυρο I2C_End ()
Κάθε φορά που γράφουμε ή διαβάζουμε δεδομένα χρησιμοποιώντας το δίαυλο I2C πρέπει να ξεκινήσουμε και να τερματίσουμε τη σύνδεση I2C. Για να ξεκινήσουμε μια επικοινωνία I2C πρέπει να ορίσουμε το bit SEN και να τερματίσουμε την επικοινωνία πρέπει να ορίσουμε το bit κατάστασης PEN. Πριν από την εναλλαγή οποιουδήποτε από αυτά τα bits, θα πρέπει επίσης να ελέγξουμε εάν ο δίαυλος I2C είναι απασχολημένος χρησιμοποιώντας τη λειτουργία I2C_Hold όπως συζητήθηκε παραπάνω.
άκυρο I2C_Begin () { I2C_Hold (); // Κρατήστε το πρόγραμμα είναι I2C είναι απασχολημένο SEN = 1; // Ξεκινήστε το IIC pg85 / 234 } άκυρο I2C_End () { I2C_Hold (); // Κρατήστε το πρόγραμμα είναι I2C είναι απασχολημένο PEN = 1; // Τέλος IIC σελ. 85/234 }
Άκυρο I2C_Write ()
Η συνάρτηση εγγραφής χρησιμοποιείται για την αποστολή δεδομένων από την κύρια μονάδα στην ενότητα salve. Αυτή η λειτουργία χρησιμοποιείται συνήθως μετά από μια λειτουργία έναρξης I2C και ακολουθείται από μια συνάρτηση I2C End. Τα δεδομένα που πρέπει να γραφτούν στο δίαυλο IIC διαβιβάζονται μέσω των μεταβλητών δεδομένων. Αυτά τα δεδομένα στη συνέχεια φορτώνονται στον καταχωρητή buffer SSPBUF για να τα στείλουν μέσω του διαύλου I2C.
Κανονικά πριν από τη σύνταξη δεδομένων θα γραφτεί μια διεύθυνση, οπότε θα πρέπει να χρησιμοποιήσετε τη λειτουργία εγγραφής δύο φορές, μία φορά για τον καθορισμό της διεύθυνσης και την άλλη στιγμή για την αποστολή των πραγματικών δεδομένων.
άκυρο I2C_Write (δεδομένα χωρίς υπογραφή) { I2C_Hold (); // Κρατήστε το πρόγραμμα είναι I2C είναι απασχολημένο SSPBUF = δεδομένα; // σελ82 / 234 }
χωρίς υπογραφή σύντομο I2C_Read ()
Η τελική συνάρτηση που πρέπει να γνωρίζουμε είναι η συνάρτηση I2C_Read . Αυτή η λειτουργία χρησιμοποιείται για την ανάγνωση των δεδομένων που βρίσκονται επί του παρόντος στο δίαυλο I2C. Χρησιμοποιείται όταν ζητάτε από έναν σκλάβο να γράψει κάποια αξία στο λεωφορείο. Η τιμή που λαμβάνεται θα είναι στο SSPBUF που μπορούμε να μεταφέρουμε αυτήν την τιμή σε οποιαδήποτε μεταβλητή για τη λειτουργία μας.
Κατά τη διάρκεια μιας επικοινωνίας I2C, ο σκλάβος μετά την αποστολή των δεδομένων που ζητούνται από το Master θα στείλει ένα άλλο bit που είναι το bit επιβεβαίωσης, αυτό το bit θα πρέπει επίσης να ελεγχθεί από τον κύριο για να βεβαιωθεί ότι η επικοινωνία ήταν επιτυχής. Αφού ελέγξετε το bit ACKDT για επιβεβαίωση, θα πρέπει να είναι ενεργοποιημένο ρυθμίζοντας το bit ACKEN.
σύντομο I2C_Read (χωρίς υπογραφή σύντομο ack) { unsigned short incoming; I2C_Hold (); RCEN = 1; I2C_Hold (); εισερχόμενα = SSPBUF; // λάβετε τα δεδομένα που έχουν αποθηκευτεί στο SSPBUF I2C_Hold (); ACKDT = (ack); 0: 1; // ελέγξτε αν το bit ack έλαβε ACKEN = 1; // σελ 85/234 εισερχόμενη επιστροφή; }
Δηλαδή, αυτές οι λειτουργίες πρέπει να είναι αρκετές για να ρυθμίσουν μια επικοινωνία I2C και να γράφουν ή να διαβάζουν δεδομένα από μια συσκευή. Σημειώστε επίσης ότι υπάρχουν πολλές άλλες λειτουργίες που μπορεί να εκτελέσει η επικοινωνία I2C, αλλά για λόγους απλότητας δεν τις συζητάμε εδώ. Μπορείτε πάντα να παραπέμψετε το φύλλο δεδομένων για να γνωρίζετε την πλήρη λειτουργία του
Μπορείτε να κατεβάσετε τον πλήρη κώδικα με το αρχείο κεφαλίδας για την επικοινωνία PIC16F877A I2C από τον σύνδεσμο.
Προγραμματισμός με χρήση των αρχείων κεφαλίδας I2C:
Τώρα που έχουμε μάθει πώς λειτουργεί μια επικοινωνία I2C και πώς μπορούμε να χρησιμοποιήσουμε το αρχείο κεφαλίδας που δημιουργήθηκε για αυτό, ας κάνουμε ένα απλό πρόγραμμα στο οποίο θα χρησιμοποιήσουμε το αρχείο κεφαλίδας και θα γράψουμε ορισμένες τιμές στις γραμμές I2C. Στη συνέχεια, θα προσομοιώσουμε αυτό το πρόγραμμα και θα ελέγξουμε εάν αυτές οι τιμές γράφονται στο λεωφορείο.
Όπως πάντα, το πρόγραμμα ξεκινά με τη ρύθμιση των ρυθμίσεων bit και τη ρύθμιση της συχνότητας ρολογιού στα 20 MHz όπως φαίνεται παρακάτω
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT απενεργοποιημένο) #pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled) # pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled) #pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (το RB3 είναι ψηφιακό I / O, HV on Το MCLR πρέπει να χρησιμοποιηθεί για προγραμματισμό) #pragma config CPD = OFF // Δεδομένα 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) #define _XTAL_FREQ 20000000
Το επόμενο βήμα θα ήταν να προσθέσετε το αρχείο κεφαλίδας για το οποίο μόλις συζητήσαμε. Το αρχείο κεφαλίδας ονομάζεται PIC16F877a_I2C.h και μπορεί να ληφθεί από τον σύνδεσμο που συζητήσαμε παραπάνω. Βεβαιωθείτε ότι το αρχείο κεφαλίδας έχει προστεθεί στο αρχείο κεφαλίδας της λίστας έργων σας, η δομή του αρχείου έργου σας θα πρέπει να έχει την εξής μορφή
Αφού βεβαιωθείτε ότι το αρχείο κεφαλίδας έχει προστεθεί στο αρχείο έργου σας συμπεριλάβετε το αρχείο κεφαλίδας στο κύριο αρχείο Γ
#περιλαμβάνω
Στο εσωτερικό του , ενώ βρόχου που θα αρχίσει με την ανακοίνωση της I2C εγγραφής λίγα τυχαίες τιμές στο δίαυλο I2C και στη συνέχεια Τερματισμός της επικοινωνίας I2C. Οι τυχαίες τιμές που έχω επιλέξει είναι D0, 88 και FF. Μπορείτε να εισαγάγετε τις τιμές που θέλετε. Αλλά θυμηθείτε αυτές τις τιμές καθώς θα τις επαληθεύσουμε στην προσομοίωσή μας.
ενώ (1) { I2C_Begin (); I2C_Write (0xD0); I2C_Write (0x88); I2C_Write (0xFF); I2C_End (); __delay_ms (1000); }
Το πλήρες πρόγραμμα βρίσκεται στο κάτω μέρος της σελίδας, μπορείτε να το χρησιμοποιήσετε ή να κατεβάσετε το πλήρες αρχείο zip του προγράμματος από εδώ. Αφού λάβετε το πρόγραμμα, μεταγλωττίστε το και ετοιμαστείτε για προσομοίωση.
Προσομοίωση πρωτεϊνών:
Το Proteus διαθέτει ένα ωραίο όργανο που ονομάζεται I2C debugger το οποίο μπορεί να χρησιμοποιηθεί για την ανάγνωση των δεδομένων σε ένα δίαυλο I2C, οπότε ας φτιάξουμε ένα κύκλωμα χρησιμοποιώντας το και ελέγξτε αν τα δεδομένα γράφονται με επιτυχία. Το πλήρες διάγραμμα κυκλώματος φαίνεται παρακάτω
Φορτώστε το αρχείο hex που δημιουργήθηκε από το πρόγραμμά μας κάνοντας διπλό κλικ στον Μικροελεγκτή. Στη συνέχεια προσομοιώστε το πρόγραμμα. Θα παρατηρήσετε ένα παράθυρο που θα εμφανίζει όλες τις πληροφορίες σχετικά με το I2C bus. Το παράθυρο για το πρόγραμμά μας εμφανίζεται παρακάτω.
Εάν ρίξετε μια προσεκτική ματιά στα δεδομένα που γράφονται, μπορείτε να παρατηρήσετε ότι είναι τα ίδια με αυτά που γράψαμε στο πρόγραμμά μας. Οι τιμές είναι D0, 88 και FF. Οι τιμές γράφονται για κάθε 1 δευτερόλεπτο, έτσι ο χρόνος ενημερώνεται επίσης όπως φαίνεται παρακάτω. Το μπλε βέλος υποδεικνύει ότι είναι γραμμένο από τον κύριο στον σκλάβο, θα ήταν αντίθετο προς την αντίθετη κατεύθυνση, εάν διαφορετικά. Μια πιο προσεκτική ματιά των δεδομένων που αποστέλλονται φαίνεται παρακάτω.
Αυτό είναι μόνο μια ματιά στο τι μπορεί να κάνει το I2C, μπορεί επίσης να διαβάσει και να γράψει δεδομένα σε πολλές συσκευές. Θα καλύψουμε περισσότερα για το I2C στα επερχόμενα σεμινάρια μας με τη διασύνδεση διαφόρων ενοτήτων που λειτουργούν με το πρωτόκολλο I2C.
Ελπίζω να καταλάβατε το έργο και να μάθετε κάτι χρήσιμο από αυτό. Εάν έχετε αμφιβολίες, δημοσιεύστε τα στην παρακάτω ενότητα σχολίων ή χρησιμοποιήστε τα φόρουμ για τεχνική βοήθεια.
Ο πλήρης κωδικός έχει δοθεί παρακάτω. Μπορείτε να κατεβάσετε αρχεία κεφαλίδας με όλο τον κώδικα από εδώ.