Σε αυτό το πρότζεκτ θα σας πω για τα ολοκληρωμένα κυκλώματα ΜΑΧ7221 και ΜΑΧ7219, τα οποία είναι οδηγοί ντισπλέϊ επτά τμημάτων LED και μέχρι οκτώ ψηφία, θα σας πώ το πώς επικοινωνούν με ένα μικροελεγκτή και τις εντολές που δέχονται απ’ αυτόν.
Συγκεκριμένα θα κατασκευάσουμε μια αναπτυξιακή πλακέτα οκτώ ψηφίων LED κοινής καθόδου που οδηγούνται από τον οδηγό ντισπλέϊ ΜΑΧ7221 ή ΜΑΧ7219. Η πλακέτα μπορεί να συνδεθεί σειριακά με ένα AVR μικροελεγκτή ή την πλατφόρμα Arduino χρησιμοποιώντας το σειριακό πρωτόκολλο SPI αν χρησιμοποιήσουμε τον οδηγό ΜΑΧ7221 ή ένα παρόμοιο πρωτόκολλο υλοποιημένο από το λογισμικό αν χρησιμοποιήσουμε τον οδηγό ΜΑΧ7219.
Οι οδηγοί ντισπλέϊ ΜΑΧ7221 και ΜΑΧ7219 ελέγχονται από ένα σύνολο καταχωρητών ψηφίων ή ελέγχου, που κάθε καταχωρητής προσπελαύνεται με την δικιά του διεύθυνση και περικλείει τα δικά του 8-bit δεδομένα που ορίζουν την λειτουργία για την οποία προορίζεται ο καταχωρητής. Κάθε καταχωρητής προσπελαύνεται με ένα πακέτο 16-bit D15-D0 που στέλνει σειριακά ο μικροελεγκτής στον οδηγό ντισπλέϊ ΜΑΧ7221 ή ΜΑΧ7219. Ο οδηγός ΜΑΧ7219 δέχεται δεδομένα ανεξάρτητα από την κατάσταση του ακροδέκτη LOAD ενώ για τον οδηγό ΜΑΧ7221 ο ακροδέκτης CS πρέπει να είναι σε low κατάσταση. Τα σήματα LOAD/CS πρέπει να τεθούν high ταυτόχρονα με ή μετά τη θετική ακμή του 16ου παλμού ρολογιού και πριν την θετική ακμή του επόμενου παλμού ρολογιού.
Στο πακέτων δεκαέξι bits, τα bits στο διάστημα D8-D11 περιέχουν την διεύθυνση του καταχωρητή που θέλουμε να προσπελάσουμε, τα bits στο διάστημα D0-D7 περιέχουν τα δεδομένα του καταχωρητή ενώ τα bit στο διάστημα D12-D15 δεν έχουν σημασία. Οι διευθύνσεις των καταχωρητών ψηφίων και ελέγχου φαίνονται στον πίνακα 2.
Για να γράψουμε δεδομένα σε ένα ψηφίο, στέλνουμε τα δεδομένα στον καταχωρητή του ψηφίου, με ένα από τους δύο τρόπους: είτε κωδικοποιημένα BCD code B είτε οχι. Ο καταχωρητής αποκωδικοποίησης (διεύθυνση = Χ9) όπου κάθε bit της τιμής του ορίζει αν έχουμε κωδικοποίηση στη θέση ψηφίου που αντιστοιχεί σε αυτό το bit (Για περισσότερες πληροφορίες ανατρέξτε στο αντίστοιχο άρθρο αυτού του ιστοτόπου).
Οι οδηγοί ντισπλέϊ ΜΑΧ7221 και ΜΑΧ7219 έχουν την δυνατότητα να οδηγούν από ένα μέχρι οκτώ ψηφία. Ορίζοντας τον αριθμό σάρωσης ψηφίων στον καταχωρητή Scan-Limit μπορεί ο οδηγός να σαρώνει λιγότερα από οκτώ ψηφία. Έτσι για παράδειγμα αν στείλουμε στον καταχωρητή Scan-Limit (Διεύθυνση =ΧΒ) την τιμή Χ3 στο ντισπλέϊ θα σαρώνονται τα ψηφία 0,1,2,3.
Χρησιμοποιώντας τον καταχωρητή display-test (διεύθυνση=ΧF) μπορούμε να ελέγξουμε όλο το ντισπλέϊ στέλνοντας την τιμή 1 ανάβουν όλα τα LED και με την τιμή 0 επανέρχεται στην κανονική λειτουργία. Η λειτουργία του καταχωρητή display-test αφήνει ανεπηρέαστους τους υπόλοιπους καταχωρητές.
Μπορούμε να ελέγξουμε την φωτεινότητα του ντισπλέϊ αναλογικά ή ψηφιακά. Αναλογικά ρυθμίζεται με την κατάλληλη επιλογή της αντίστασης RSET μεταξύ της τροφοδοσίας V+ και του ακροδέκτη ISET. Ψηφιακά ρυθμίζεται από τον καταχωρητή φωτεινότητας (διεύθυνση ΧΑ) με την κατάλληλη τιμή.
Έχουμε σχεδιάσει μια PCB αναπτυξιακή πλακέτα, διπλής όψης, διαστάσεων 17cmΧ6cm η οποία έχει βάση για τον οδηγό ΜΑΧ7219 ή τον ΜΑΧ7221 (είναι η ίδια πλακέτα και για τους δύο οδηγούς) όπου πάνω της καλούνται οχτώ ψηφία 0,56 inches κοινής καθόδου, ένα τροφοδοτικό 5V βασισμένο στο ολοκληρωμένο κύκλωμα LT1076-5 και μερικά ακόμη παθητικά εξαρτήματα και συγκεκριμένα την δίοδο schottky, την αυτεπαγωγή τους πυκνωτές τις αντιστάσεις και τον DC κονέκτορα.
Το PCB της κατασκευής μας δείχνεται παρακάτω:
Το σχηματικό της πλακέτας δείχνεται παρακάτω:
Τα εξαρτήματα που χρησιμοποιούνται είναι τα εξής:
R1…………1,5K 1/4W
R2………….10K 1/4W
C1………….1000μF/25V
C2………….220nF
C3………….33nF
C4………….220nF
C5………….2200μF/16V
D1………….1N5818 schottky
L1………….100μH
IC1…………MAX7221
IC2…………LT1076-5
DIS0…DIS7 7segment 0,56in led display
J1………….DC connector
Πως το ΜΑΧ7221 δέχεται εντολές από ένα AVR μικροελεγκτή
Μετά που έχουμε μοντάρει την αναπτυξιακή πλακέτα τοποθετούμε τον οδηγό ΜΑΧ7221 και διασυνδέουμε τα πινς της αναπτυξιακής πλακέτας GND, CS, CLK, DIN με τα πινς του AVR μικροελεγκτή τύπου ΑΤμεγα328Ρ τα GND, SS, SCK, MOSI αντίστοιχα. Έπειτα τροφοδοτούμε την πλακέτα με τάση DC 8-15V.
Προτού τροφοδοτήσουμε με τάση την κατασκευή ανεβάζουμε τον παρακάτω κώδικα στον AVR μικροελεγκτή:
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#define MOSI 3
#define SCK 5
#define SS 2
void max7221avrtransfer(uint8_t address, uint8_t value){
PORTB &= ~(1<<SS);
SPDR = address;
while(!(SPSR & (1<<SPIF)));
SPDR = value;
while(!(SPSR & (1<<SPIF)));
PORTB |= (1<<SS);
}
int main(void)
{
DDRB = (1<<MOSI)|(1<<SCK)|(1<<SS);
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
PORTB |= (1<<SS);
max7221avrtransfer(0x0F, 0x01); //Display – Test Register Format: Display test Mode
_delay_ms(500);
max7221avrtransfer(0x0F, 0x00);
max7221avrtransfer(0x0C, 0x01);//Shutdown Register Format: Normal Operation
max7221avrtransfer(0x0A, 0x0A);//Intensity Register
max7221avrtransfer(0x09, 0xFF);//Decode – Mode Register Format: Decode for digits 7-0
max7221avrtransfer(0x0B, 0x07);//Scan–Limit Register Format: Display digits 01234567
for(uint8_t j=0; j<=9; j++){
for(uint8_t i=1; i<=8; i++) max7221avrtransfer(i,j);
_delay_ms(500);
}
max7221avrtransfer(0x09, 0x0F);//Decode – Mode Register Format: Decode for digits 3-0
max7221avrtransfer(0x01, 0x09); //Digit 0 as number 9
max7221avrtransfer(0x02, 0x01); //Digit 1 as number 1
max7221avrtransfer(0x03, 0x00); //Digit 2 as number 0
max7221avrtransfer(0x04, 0x02); //Digit 3 as number 2
max7221avrtransfer(0x05, 0B01001110); //Digit 4 as letter C
max7221avrtransfer(0x0B, 0x04); //Scan – Limit Register Format: Display digits 01234
while (1)
{
}
}
Ο μικροελεγκτής AVR χρησιμοποιεί το SPI πρωτόκολλο για να επικοινωνήσει με τον οδηγό ντισπλέϊ ΜΑΧ7221 και βασίζεται στην συνάρτηση max7221avrtransfer( διεύθυνση, δεδομένα). Αυτή η συνάρτηση στέλνει στον οδηγό δυο bytes την διεύθυνση του καταχωρητή που θέλουμε να προσπελάσουμε και τα δεδομένα που θέλουμε να έχει.
Στην συνάρτηση main() του κώδικα μπορούμε να δούμε παραδείγματα πως ο μικροελεγκτής επικοινωνεί με το ΜΑΧ7221 στέλνοντας εντολές: π.χ. max7221avrtransfer(0x0F, 0x01); για να ελέγξουμε φωτίζοντας όλο το ντισπλέϊ. Εδώ ο καταχωρητής display – test ο οποίος έχει διεύθυνση 0x0F φορτώνεται με την τιμή 0x01 και έχει σαν αποτέλεσμα να φωτιστεί ολόκληρο το ντισπλέϊ. Επίσης για να εμφανίσουμε στο ψηφίο 3 τον αριθμό 2 στέλνουμε την εντολή max7221avrtransfer(0x04, 0x02); αφού πρώτα ορίσουμε κωδικωποίηση BCD σε αυτό το ψηφίο με την εντολή: max7221avrtransfer(0x09, 0x0F); (καθώς και για τα υπόλοιπα ψηφία).
Το πώς το ΜΑΧ7219 δέχεται εντολές από ένα AVR μικροελεγκτή
Ο οδηγός ντισπλέϊ ΜΑΧ7219 επικοινωνεί σειριακά με ένα μικροελεγκτή με σειριακό πρωτόκολλο που μοιάζει με το SPI πρωτόκολλο. Εδώ ο μικροελεγκτής χρησιμοποιεί κώδικα για να παράγει τα απαραίτητα σήματα.
Συνδέουμε τα πινς της αναπτυξιακής πλακέτας CS, CLK, DIN με οποιαδήποτε Ι/Ο πινς του ΑΤmega328P μικροελεγκτή, τα οποία και θα δηλώσουμε στον κώδικα μας (δεν ξεχνάμε να συνδέσουμε τη γείωση GND).
Πριν τροφοδοτήσουμε με τάση την κατασκευή ανεβάζουμε στον μικροελεγκτή τον ακόλουθο κώδικα.
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#define DIN 3
#define CLK 5
#define LOAD 2
void max7219avrtransfer(uint8_t address, uint8_t value){
PORTB &= ~(1<<CLK);
PORTB &= ~(1<<LOAD);
PORTB &= ~(1<<CLK);
uint16_t reg = (address<<8) | value;
for(uint8_t i=0; i<16; i++){
PORTB &= ~(1<<CLK);
if(reg & 0x8000) PORTB |= (1<<DIN); else PORTB &= ~(1<<DIN);
PORTB |= (1<<CLK);
reg <<= 1;
}
PORTB |= (1<<LOAD);
PORTB &= ~(1<<CLK);
}
int main(void)
{
DDRB = (1<<DIN)|(1<<CLK)|(1<<LOAD);
PORTB |= (1<<LOAD);
max7219avrtransfer(0x0F, 0x01); //Display – Test Register Format: Display test Mode
_delay_ms(500);
max7219avrtransfer(0x0F, 0x00);
max7219avrtransfer(0x0C, 0x01); //Shutdown Register Format: Normal Operation
max7219avrtransfer(0x0A, 0x0A); //Intensity Register
max7219avrtransfer(0x09, 0xFF); //Decode – Mode Register Format: Decode for digits 7-0
max7219avrtransfer(0x0B, 0x07); // Scan – Limit Register Format: Display digits 01234567
for(uint8_t j=0; j<=9; j++){
for(uint8_t i=1; i<=8; i++) max7219avrtransfer(i,j);
_delay_ms(500);
}
max7219avrtransfer(0x09, 0x0F); //Decode – Mode Register Format: Decode for digits 3-0
max7219avrtransfer(0x01, 0x09); //Digit 0 as number 9
max7219avrtransfer(0x02, 0x01); //Digit 1 as number 1
max7219avrtransfer(0x03, 0x00); //Digit 2 as number 0
max7219avrtransfer(0x04, 0x02); //Digit 3 as number 2
max7219avrtransfer(0x05, 0B01001110); //Digit 4 as letter C
max7219avrtransfer(0x0B, 0x04); // Scan – Limit Register Format: Display digits 01234
while (1)
{
}
}
Η επικοινωνία επιτυγχάνεται με την συνάρτηση max7219avrtransfer(διεύθυνση , δεδομένα) η οποία παράγει αναλυτικά τα σήματα που απαιτούνται για την σειριακή επικοινωνία. Η συνάρτηση main() είναι όπως στον προηγούμενο κώδικα και παράγει την ίδια έξοδο.
Πως το ΜΑΧ7221 δέχεται εντολές από το Arduino board
Σε αυτό το παράδειγμα συνδέουμε την πλακέτα Arduino board με την αναπτυξιακή πλακέτα με το ΜΑΧ7221 που παρουσιάσαμε νωρίτερα. Συνδέουμε τα πινς της αναπτυξιακής πλακέτας GND, CS, CLK, DIN με τα αντίστοιχα πινς GND, SS, SCK, MOSI της πλακέτας Arduino board.
Πριν τροφοδοτήσουμε με τάση τις πλακέτες ανεβάζουμε τον ακόλουθο κώδικα στο Arduino Uno.
#include <SPI.h>
#define SS 10
void max7221transfer(byte address, byte value){
digitalWrite(SS, LOW);
SPI.transfer(address);
SPI.transfer(value);
digitalWrite(SS, HIGH);
delay(1);
}
void setup() {
SPI.begin();
pinMode(SS, OUTPUT);
digitalWrite(SS, HIGH);
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
max7221transfer(0x0F, 0x01); //Display – Test Register Format: Display test Mode
delay(500);
max7221transfer(0x0F, 0x00);
max7221transfer(0x0C, 0x01); //Shutdown Register Format: Normal Operation
max7221transfer(0x0A, 0x0A); //Intensity Register
max7221transfer(0x09, 0xFF); //Decode – Mode Register Format: Decode for digits 7-0
max7221transfer(0x0B, 0x07); // Scan – Limit Register Format: Display digits 01234567
for(byte j=0; j<=9; j++){
for(byte i=1; i<=8; i++) max7221transfer(i,j);
delay(500);
}
max7221transfer(0x09, 0x0F); //Decode – Mode Register Format: Decode for digits 3-0
max7221transfer(0x01, 0x09); //Digit 0 as number 9
max7221transfer(0x02, 0x01); //Digit 1 as number 1
max7221transfer(0x03, 0x00); //Digit 2 as number 0
max7221transfer(0x04, 0x02); //Digit 3 as number 2
max7221transfer(0x05, 0B01001110); //Digit 4 as letter C
max7221transfer(0x0B, 0x04); // Scan – Limit Register Format: Display digits 01234
}
void loop() {
}
Σε αυτό τον κώδικα εισάγουμε στην αρχή την SPI βιβλιοθήκη και αρχικοποιούμε την SPI επικοινωνία με την εντολή SPI.begin() μέσα στη συνάρτηση setup(). Μπορούμε να στείλουμε την διεύθυνση και τα δεδομένα οποιοδήποτε καταχωρητή του ΜΑΧ7221 με τη συνάρτηση max7221transfer(διεύθυνση, δεδομένα) η οποία περιλαμβάνει δυο κλήσεις της συνάρτησης SPI.transfer( ). Στην συνάρτηση loop( ) μπορούμε να δούμε παραδείγματα πως το Arduino board στέλνει εντολές στο ΜΑΧ7221.
Πως το ΜΑΧ7219 δέχεται εντολές από το Arduino board
Αυτό το παράδειγμα είναι παρόμοιο με το προηγούμενο, με τη διαφορά ότι εδώ έχουμε τον οδηγό ΜΑΧ7219 ο οποίος χρησιμοποιεί το δικό του σειριακό πρωτόκολλο για να επικοινωνεί με το Arduino board. Αυτό το πρωτόκολλο είναι αρκετά όμοιο με το SPI πρωτόκολλο.
Συνδέουμε τα πινς της αναπτυξιακής πλακέτας CS, CLK, DIN με οποιαδήποτε Ι/Ο πινς του Arduino board τα οποία και θα δηλώσουμε στον κώδικα. (Δεν πρέπει να ξεχάσουμε να συνδέσουμε και το GND πιν).
Πρώτα ανεβάζουμε στο Arduino board τον ακόλουθο κώδικα και ύστερα τροφοδοτούμε με τάση τις πλακέτες.
#define DIN 11
#define LOAD 7
#define CLK 13
void max7219transfer(byte address, byte value){
digitalWrite(LOAD, LOW);
shiftOut(DIN, CLK, MSBFIRST, address);
shiftOut(DIN, CLK, MSBFIRST, value);
digitalWrite(LOAD, HIGH);
delay(1);
}
void setup() {
pinMode(DIN, OUTPUT);
pinMode(CLK, OUTPUT);
pinMode(LOAD, OUTPUT);
digitalWrite(LOAD, HIGH);
digitalWrite(DIN, LOW);
digitalWrite(CLK, LOW);
max7219Transfer(0x0F, 0x01); //Display – Test Register Format: Display test Mode
delay(500);
max7219transfer(0x0F, 0x00);
max7219transfer(0x0C, 0x01); //Shutdown Register Format: Normal Operation
max7219transfer(0x0A, 0x0A); //Intensity Register
max7219transfer(0x09, 0xFF); //Decode – Mode Register Format: Decode for digits 7-0
max7219transfer(0x0B, 0x07); // Scan – Limit Register Format: Display digits 01234567
for(byte j=0; j<=9; j++){
for(byte i=1; i<=8; i++) max7219transfer(i,j);
delay(500);
}
max7219transfer(0x09, 0x0F); //Decode – Mode Register Format: Decode for digits 3-0
max7219transfer(0x01, 0x09); //Digit 0 as number 9
max7219transfer(0x02, 0x01); //Digit 1 as number 1
max7219transfer(0x03, 0x00); //Digit 2 as number 0
max7219transfer(0x04, 0x02); //Digit 3 as number 2
max7219transfer(0x05, 0B01001110); //Digit 4 as letter C
max7219transfer(0x0B, 0x04); // Scan – Limit Register Format: Display digits 01234
}
void loop() {
}
Η επικοινωνία της αναπτυξιακής πλακέτας με το Arduino board βασίζεται στη συνάρτηση max7219transfer(διεύθυνση, δεδομένα). Οι μεταβλητές της συνάρτησης είναι η διεύθυνση και τα δεδομένα του καταχωρητή του ΜΑΧ7219 που θέλουμε να προσπελάσουμε. Όπως βλέπουμε στον κώδικα αυτή η συνάρτηση βασίζεται σε δυο κλήσεις της συνάρτησης του Arduino: shiftOut(dataPin, clockPin, bitOrder, value).
Χρήσιμα αρχεία για κατέβασμα
Μπορείτε να κατεβάσετε τα αρχεία eagle της κατασκευής και να τα χρησιμοποιείται ελεύθερα κάνοντας κλικ στον σύνδεσμο:
Αρχεία eagle για την κατασκευή Κ120 αναπτυξιακή πλακέτα για τον ΜΑΧ7221 ή ΜΑΧ7219