ADC στον ATmega2560

 

Συγγραφέας: Πορλιδάς Δημήτριος

Βιογραφικό Σημείωμα

electronics@porlidas.gr

Facebook

Linkedin


 

 

Οι AVR διαθέτουν αναλογικές εισόδους για σύγκριση ή μετατροπή σε ψηφιακή τιμή. Ο ATmega2560 διαθέτει δύο εισόδους σύγκρισης, ΑΙΝ0ΑΙΝ1 (PE2PE3) και 16 εισόδους για μετατροπή ADC0ADC15 (PF7:0 και PK7:0). Η σύγκριση μπορεί να γίνει είτε μεταξύ των ΑΙΝ0ΑΙΝ1 είτε μεταξύ της ΑΙΝ0[1] και μιας από τις 16 αναλογικές εισόδους ADC0ADC15. Η θετική είσοδος του συγκριτή είναι είτε η ΑΙΝ0 είτε η τάση αναφοράς bandgap reference voltage 1.1V του μικροελεγκτή. Η αρνητική είσοδος μπορεί να είναι η ΑΙΝ1 ή μια από τις 16 αναλογικές. Για όσο η θετική είσοδος είναι μεγαλύτερη από την αρνητική, η έξοδος του συγκριτή είναι τοποθετημένη ενώ καθαρίζει όταν η αρνητική γίνει μεγαλύτερη. Κατά την αλλαγή η έξοδος μπορεί να προκαλέσει διακοπή[2] ή να ενεργοποιήσει τη λειτουργία Timer/Counter1 Input Capture. Οι ρυθμίσεις του συγκριτή γίνονται από τους καταχωρητές ADCSRB και ACSR ενώ πρέπει να απενεργοποιηθεί η ψηφιακή είσοδος στα PE2 και PE3 από τον καταχωρητή DIDR1.

Οι 16 αναλογικές είσοδοι μπορούν λειτουργήσουν ως μονές είσοδοι για θετικές τάσεις ως προς το 0 της τροφοδοσίας του συστήματος ή ανά δύο ως διαφορικοί είσοδοι[3] οι οποίες είναι ανεξάρτητες από την τροφοδοσία του συστήματος. Η λειτουργία τους καθορίζεται από τον αντίστοιχο καταχωρητή ADMUX (MUX5:0) και πρέπει επίσης να απενεργοποιηθεί η ψηφιακή είσοδος όταν χρησιμοποιούνται για αναλογική, τοποθετόντας τα αντίστοιχα bit των καταχωρητών DIDR0 και DIDR2. Η ψηφιακή έξοδος του μετατροπέα είναι 10bit και μετά τη μετατροπή, το αποτέλεσμα αποθηκεύεται στους καταχωρητές ADCL και ADCH. Όταν γίνεται χρήση μονών εισόδων το αποτέλεσμα των 10bit είναι μη προσημασμένος αριθμός[4] και συνεπώς μπορεί να πάρει τιμές 0–1023. Όταν γίνεται χρήση διαφορικών εισόδων είναι δυνατό να υπάρξουν αρνητικές τιμές και για αυτό το αποτέλεσμα των 10bit είναι προσημασμένος αριθμός[5] και μπορεί να πάρει τιμές (-512)–(511). Η μετατροπή γίνεται ως προς την τάση αναφοράς,[6] η οποία μπορεί να είναι η AVCC (τάση τροφοδοσίας του αναλογικού τμήματος του μικροελεγκτή) ή εσωτερική τάση αναφοράς VREF[7] ή μια εξωτερική τάση αναφοράς συνδεδεμένη στο pin AREF.[8]

Ο τρόπος που γίνεται η αποθήκευση των 10bit εξαρτάται από την αντίστοιχη σημαία ADLAR του καταχωρητή ADMUX και μπορεί να είναι με δεξιά στοίχιση ή αριστερή. Κατά τη δεξιά στοίχιση τα 8 LSB του αποτελέσματος καταχωρούνται στον ADCL και τα δύο MSB στα bit0 και bit1 του ADCH (με το MSB στο bit1) ενώ όλα τα υπόλοιπα bit του ADCH είναι 0. Κατά την αριστερή στοίχιση τα 8 MSB του αποτελέσματος καταχωρούνται στον ADCH και τα δύο LSB στα bit7 και bit6 του ADCL (με το LSB στο bit6) ενώ όλα τα υπόλοιπα bit του ADCL είναι 0. Στον Πίνακα Ι παρουσιάζεται ένα παράδειγμα με το περιεχόμενο των καταχωρητών για προσημασμένους και μη αριθμούς στους δύο τρόπους στοίχισης.

                  Πίνακας Ι. Παράδειγμα καταχωρητών ADCL και ADCH.

ADCH

ADCL

 

0000 0011

0100 1011

Δεξιά στοίχιση, μη προσημασμένος δεκ. αρ. 843

1101 0010

1100 0000

Αριστερή στοίχιση, μη προσημασμένος δεκ. αρ. 843

0000 0011

0100 1011

Δεξιά στοίχιση, προσημασμένος δεκ. αρ. -181

1101 0010

1100 0000

Αριστερή στοίχιση, προσημασμένος δεκ. αρ. -181

Η δυνατότητα των δύο τρόπων στοίχισης μας επιτρέπει να απορρίπτουμε τα δύο bit από τα δέκα και να κάνουμε χρήση των υπόλοιπων οκτώ, έτσι ώστε να γίνεται πιο εύκολα η διαχείριση του αποτελέσματος. Αν για παράδειγμα δεν μας ενδιαφέρει τόσο η ακρίβεια μπορούμε να επιλέξουμε αριστερή στοίχιση και να αγνοήσουμε τα 2 LSB διαβάζοντας μόνο τον ADCH. Πρέπει όμως να λάβουμε υπόψη ότι η μέγιστη τιμή[9] των 8bit αντιστοιχεί στην VREF. Στη συνέχεια παρουσιάζεται ένα παράδειγμα προετοιμασίας του ADC και μετατροπής, γραμμένο σε γλώσσα C.

uint8_t AdcOut1;

 

void InitADC (void)

{

ADCSRA = ((1<<ADEN) | (7<<ADPS0));   // ADC Enable, single conversion, 62.5kHz sample

ADMUX = ((1<<REFS0) | (1<<ADLAR));   // AVcc(REFS1:0 = 0->AREF, 1->AVCC, 2->VREF=1.1V, 3->VREF=2.56V),

                   // left adjust result, PF0 (MUX5:0=0 default value)

DIDR0 |= (1<<0);                     // Disable Digital Input PF0

}

 

void GetADC (void)

{

ADCSRA |= (1<<ADSC);                 // Start conversion

while (!(ADCSRA & (1<<ADIF)));       // Wait for conversion to complete

AdcOut1 = ADCH;                      // Write data to variable

}

Η πρώτη ρουτίνα είναι για την προετοιμασία του ADC. Mε την πρώτη εντολή γίνεται η ενεργοποίηση των κυκλωμάτων του μαζί με την επιλογή εκκίνησης μετατροπής[10]  (επιλέγεται απλή μετατροπή) και συχνότητας λειτουργίας του κυκλώματος διαδοχικής προσέγγισης[11] (επιλέγεται 62.5kHz). Με τη δεύτερη εντολή γίνεται η επιλογή της τάσης αναφοράς και αριστερής στοίχισης και με την τρίτη απενεργοποίηση ψηφιακής εισόδου.

Η δεύτερη ρουτίνα είναι για την αναλογική σε ψηφιακή μετατροπή. Με την πρώτη εντολή τοποθετείται η σημαία ADSC και αυτό σηματοδοτεί την εκκίνηση της μετατροπής. Η δεύτερη εντολή είναι για αναμονή του επεξεργαστή ώσπου να ολοκληρωθεί η μετατροπή και με την τελευταία γίνεται η ανάγνωση του αποτελέσματος από τον ADCH. Αν θέλουμε να χρησιμοποιήσουμε και τα 10bit του αποτελέσματος της μετατροπής θα πρέπει να γίνει ανάγνωση και του ADCL και μάλιστα η ανάγνωση του ADCL πρέπει να γίνεται πάντα πρώτα γιατί ο επεξεργαστής θεωρεί ότι μετά την ανάγνωση του ADCH ολοκληρώνονται οι διαδικασίες ανάγνωσης και απαγορεύει την πρόσβαση στους καταχωρητές. Στη συνέχεια παρουσιάζεται το παραπάνω παράδειγμα τροποποιημένο ώστε να γίνεται ανάγνωση και καταχώρηση του αποτελέσματος των 10bit σε μεταβλητή 16bit.       

uint8_t AdcOut1;

uint8_t AdcOut0;

int16_t AdcOut10;

//int16_t AdcOut10n;

 

void InitADC (void)

{

ADCSRA = ((1<<ADEN) | (7<<ADPS0));   // ADC Enable, single conversion, 62.5kHz sample

ADMUX = ((1<<REFS0) | (1<<MUX4));    // AVcc(REFS1:0 = 0->AREF, 1->AVCC, 2->VREF=1.1V, 3->VREF=2.56V),

                   // right adjust result (ADLAR=0 default value), PF0-PF1 

DIDR0 |= (3<<0);                     // Disable Digital Input PF0, PF1

}

 

void GetADC (void)

{

ADCSRA |= (1<<ADSC);                 // Start conversion

while (!(ADCSRA & (1<<ADIF)));       // Wait for conversion to complete

AdcOut0 = ADCL;                      // Write data to variable

AdcOut1 = ADCH;                      // Write data to variable

AdcOut10 = 0;

AdcOut10 = AdcOut1<<8;               // Write high byte to 16bit variable

AdcOut10 |= AdcOut0;                 // Write low byte to 16bit variable

if (bit_is_set(AdcOut1,1))           // Check 10bit result sign

AdcOut10 |= 0b1111110000000000;      // if negative do sign extension

//  AdcOut10n = AdcOut10 + 3;            // Reject CMV if necessary

}

 

©2019 Πορλιδάς Δημήτριος


[1] Το αναπτυξιακό ARDUINO mega2560 δεν διαθέτει αναμονή για σύνδεση στη θύρα AIN0 συνεπώς μπορούμε να χρησιμοποιήσουμε ως τάση σύγκρισης μόνο την bandgap reference voltage 1.1V του μικροελεγκτή

[2] Η διακοπή μπορεί να προκληθεί από το ανερχόμενο, το κατερχόμενο ή την αλλαγή λογικής στάθμης της εξόδου του συγκριτή.

[3] Τα ζευγάρια ADC1–ADC0, ADC3–ADC2, ADC9–ADC8 και ADC11–ADC10 μπορούν να προγραμματιστούν ώστε να έχουν απολαβή x10 ή x200.

[4] Δεν είναι δυνατό να συνδέσουμε τάση αρνητικότερη από τη γείωση (αρνητικό της τροφοδοσίας του συστήματος) και συνεπώς δε γίνεται να έχουμε αρνητικό αποτέλεσμα.

[5] Οι αρνητικές τιμές δίνονται με τη μορφή του συμπληρώματος ως προς 2.

[6] Η μέγιστη τιμή της μετατροπής αντιστοιχεί στην τάση αναφοράς που χρησιμοποιείται.

[7] Reference voltage (VREF) 2.56V ή 1.1V για τον ATmega2560.

[8] Όταν δε χρησιμοποιείται εξωτερική τάση αναφοράς το pin πρέπει να είναι συνδεδεμένο σε έναν πυκνωτή προς τη γείωση.

[9] Η μέγιστη τιμή για τα 8bit είναι -128 ή 127 ή 255 ανάλογα με το αν είναι αρνητικός ή θετικός προσημασμένος αριθμός ή μη προσημασμένος αντίστοιχα.

[10] Ο ADC μπορεί να κάνει αυτόματη μετατροπή (Auto Trigger mode) ή απλή -μετά από αίτημα- (Single Conversion mode), ανάλογα με την τιμή της σημαίας ADATE. Στην αυτόματη μετατροπή η εκκίνηση μπορεί να γίνει από τον αναλογικό συγκριτή, εξωτερική διακοπή στο ΙΝΤ0 ή από τον Timer/Counter1, ανάλογα με την τιμή του ADTS2:0 του καταχωρητή ADCSRB.

[11] Γίνεται με διαίρεση (prescaler) του ρολογιού συστήματος ανάλογα με την τιμή του  ADPS2:0 του καταχωρητή ADCSRA.

 

Σας ευχαριστώ για την υποστήριξή σας ώστε να γίνει η ιστοσελίδα μου καλύτερη.

© 2019 Πορλιδάς Δημήτριος