Analog-Digital-Wandlung

Ich verwende einen Atmega32-A-Mikrocontroller und einen externen AD7798- ADC. Ich kann die ADC-Register einstellen und ADC-Werte zurücklesen. Ich habe folgenden Code geschrieben:

  statusreg = AD7798_8(0x40, 0xFF);          // read STATUS register default value
  Id = AD7798_8(0x60, 0xFF);                 // read ID register  default value
  mode = AD7798_16(0x48, 0xFFFF);            // read MODE register default value
  conf = AD7798_16(0x50, 0xFFFF);            // read conf register default value

   AD7798_16(0x10, 0x0010);            // write Configuration reg = 0x0010.  2.5V range  
   value = AD7798_16(0x50, 0xFFFF);         // read Configration register 

   if (value != 0x0010) 
   printf("unexpected conf setting %04x\r\n", value);

   while ((statusreg & 0x80) != 0);                         // wait till ADC is ready 
   adc = AD7798_16(0x58, 0xFFFF);                           // read register 
   printf("ADC value is %04d\r\n", adc);    

Aus dem obigen Code lese ich die ADC-Werte. Gemäß dem AD7798-Datenblatt und gemäß meinem Konfigurationsregister-Setup muss ich die analoge Eingangsspannung mithilfe der folgenden Formel ermitteln:

Wenn der ADC für bipolaren Betrieb konfiguriert ist, wird der Ausgangscode binär versetzt, wobei eine negative Vollskalenspannung zu einem Code von 000...000 führt, eine differenzielle Eingangsspannung von Null zu einem Code von 100...000, und eine positive Vollskalen-Eingangsspannung, was zu einem Code von 111...111 führt. Der Ausgangscode für jede analoge Eingangsspannung kann dargestellt werden als

Code = 2 N – 1 × [( AIN × GAIN / VREF ) + 1]

wobei:
AIN die analoge Eingangsspannung ist.
N = 16 für den AD7798 und N = 24 für den AD7799.

Ich erhalte einen ADC-Wert von 1EF2(hex) für einen 0,6-V-Analogeingang. Ich habe mit einem Oszilloskop gemessen. Ich habe die analoge Eingangsspannung mit der obigen Formel berechnet und erhalte 0,15 V. Hier ist GAIN 1, VREF = 2,5 V. Was falsch ist, weil ich 0,6 V bekommen muss. Ich habe den resultierenden Hex-ADC-Wert in Dezimal- 7922und auch Binärwerte umgewandelt 0001111011110010. Meine analoge Eingangsspannung variiert von 0 V bis 0,6 V. Entsprechend meiner analogen Eingangsspannung ändert sich auch mein ADC-Ausgang von 0002zu 1EF2.

Wenn ich das Setup des Konfigurationsregisters auf ein anderes Setup wie bipolar zu unipolar (von 0x0010bis 0x1010) ändere, erhalte ich zu diesem Zeitpunkt einen ADC-Wert von 0000immer. Es gibt einen ADC-Wert 0000für jede andere Konfiguration als 0x0010im Konfigurationsregister an.

Außerdem kann ich den folgenden Satz nicht verstehen:

mit einer negativen Vollskalenspannung, die zu einem Code von 000...000 führt, einer Differenzeingangsspannung von Null, die zu einem Code von 100...000 führt, und einer positiven Vollskaleneingangsspannung, die zu einem Code von 111 führt. .111.

Wie wandle ich das resultierende digitale Signal richtig in eine analoge Spannung um?
Sind meine ADC-Messwerte richtig oder falsch?
Warum funktioniert mein Code bei keiner anderen Konfiguration?

Antworten (2)

Der AD7798 ist ein differenzieller ADC. Es hat einen negativen Eingang und einen positiven Eingang. Bei Konfiguration für bipolaren Betrieb:

  • Wenn die Spannung zwischen in+ und in- positiv ist (in+ > in-), ist der Ausgang bei Vollaussteuerung eins.

  • Wenn die Spannung zwischen in+ und in- 0 ist (in+ == in-), ist die Ausgabe 1000...0000.

  • Und wenn die Spannung zwischen in+ und in- negativ ist (in+ < in-) bei Vollausschlag ist der Ausgang ganz Null.

Ich habe meine AIN(+)=0.6(+) und AIN(-)=2.5(+) überprüft, was bedeutet AIN(+)<AIN(-) dann muss ich nur Nullen ausgegeben bekommen, aber ich bekomme Werte von „0000“ bis „1EF2“.
Jetzt verstehe ich klar. ADC ist ein Differenzialverstärker, so dass er eine Differenz von zwei Eingängen als Ausgang liefert, also ist hier AIN(-) 2,6 und AIN(+) 0,6. Ich bekomme also eine negative Spannung von -1,9 als Ausgang. mein ADC-Ergebnis gibt auch den gleichen Wert. hab ich recht.

Wie Blup1980 erwähnte, ist der AD7798 ein differenzieller ADC. Das bedeutet, dass es die Differenz der beiden Eingaben nimmt und diesen Wert umwandelt.

Du hast:

AIN(+) = +0,6V bezogen auf GND
AIN(-) = +2,5V bezogen auf GND

Aber der Unterschied zwischen den beiden ist:

A ICH N = 0,6 2.5 = 1.9

Wir haben also folgendes:

C Ö D e = 2 N 1 × [ ( A ICH N × G A ICH N / v R E F ) + 1 ]
7922 = 32768 × [ ( A ICH N × 1 / 2.5 ) + 1 ]
0,24176025390625 = ( A ICH N × 1 / 2.5 ) + 1
0,75823974609375 = A ICH N × 1 / 2.5
1.895599365234375 = A ICH N

Welches ist richtig.

Umgewandelt in C-Code haben wir:

int      code_dec;
float    code_flt;
float    ain_valu;

/* Initialize variables */
code_dec = 0U;
code_flt = 0.0F;
ain_valu = 0.0F;

code_dec = AD7798_16(0x58, 0xFFFF);                   /* Get Code from ADC */ 
code_flt = (float)code_dec;                           /* Cast Code into float */ 
ain_valu = ((code_flt / 32768.0F) - 1.0F) / 0.4F;     /* Perform calculation */

printf("Voltage is: %f\n", ain_valu);                 /* Print voltage value */

Es hat sich bewährt , den Codewert in einen umzuwandeln floatund dann floatin jedem Teil der Berechnung Werte zu verwenden. Dann benötigen Sie den %f Formatbezeichner, um sicherzustellen, dass der Wert als Fließkommazahl ausgegeben wird, die das negative Vorzeichen enthält, wenn der Wert negativ ist. Wenn Sie das positive Vorzeichen für positive Werte einbeziehen möchten, verwenden Sie %+fstattdessen .

Ich habe die obige Formel vereinfacht in c implementiert, Ain=((adc/32768)-1)/0.416 ; hier 0,416 = (1/2,5), adc bedeutet Codewert (7922). aber das Problem ist, dass ich den Ain-Wert nicht drucken kann. Ich möchte es als Float-Wert drucken. Es wird einen negativen Wert geben. Ich möchte einen negativen Wert drucken.
@verendra Siehe meine Bearbeitung zum Beispiel C-Code
:kyle Ich habe code_dec als unsigned int deklariert. aber ich kann immer noch nicht drucken. nichts wird gedruckt.
@verendra Nichts wird gedruckt? Vielleicht liegt das Problem nicht bei der Konvertierung, sondern bei der Verbindung zu dem von Ihnen verwendeten Bildschirm. Kannst du es versuchen printf("Hello World!\n");? Wird das ausgedruckt?
Ja, Hallo Welt druckt und der Code druckt auch wie "Spannung ist: ". Nichts wird gedruckt bedeutet, dass kein Wert gedruckt wird.
@verendra Seltsam. Wie wäre es mit einem expliziten Wert. Funktioniert das: printf("Float value: %f", 1.234);?
Nein, es funktioniert nicht. Drucken Sie einfach wie "Float-Wert: ".