Forum: Mikrocontroller und Digitale Elektronik 8051F330 Silabs Toolstick A/D Wandlung


von matwal (Gast)


Lesenswert?

Hallo,

ich habe mir folgenden µController zugelegt:
http://de.farnell.com/silicon-laboratories/toolsticksk/adaptor-kit-base-c8051f330/dp/1295418

Dieser besitzt für Testzwecke ein Poti an P1.6
Ich versuche nun, mit einem Beispielcode von der Fa.Keil-->

[c]#include <c8051f330.h>
#include <stdio.h>

#define VREF  5      /* Voltage Reference */

void main ( void )  {

unsigned int adval;

/* initialize the serial interface */
  SCON0  = 0x50;           /* SCON0: mode 1, 8-bit UART, enable rcvr 
*/
  TMOD  |= 0x20;           /* TMOD:  timer 1, mode 2, 8-bit reload 
*/
  TH1    = 221;            /* TH1:   reload value for 9600 baud @ 16MHz 
*/
  TR1    = 1;              /* TR1:   timer 1 run 
*/
  TI0    = 1;              /* TI0:   set TI to send first char of UART 
*/

/*  Configure P0.0 as Analog Input  */
  P1MDIN = 0xBF;           /*  P0.0 only 
*/
  P1SKIP = 0x40;           /*  Skip Crossbar decoding for this pin 
*/

/* Init MUX   */
  AMX0P = 0x00;             /*  Select Positive Input Port P0.0 
*/
  AMX0N = 0x11;             /*  GND Neg Inputs (Single-ended Mode) 
*/

/* Init ADC   */
  ADC0CF = 0xF8;           /*  SAR clock = 31, Right-justified result 
*/
  ADC0CN = 0x80;            /*  Enable ADC 0, Normal Tracking, 
*/
                           /*  Start Convert on AD0BUSY set 
*/

while (1){

  AD0BUSY = 1;             /*  Start ADC 0 conversion 
*/
  while (AD0BUSY);         /*  Wait for conversion 
*/

/* Read 0-511 value in ADC0 */
  adval = ADC0L + (ADC0H << 8);

/* Output 0-511 ADC0 value without using floating-point */
  printf ("ADC0 Count %4u = %01u.%04u Volts\r",
         (unsigned) adval,
         (unsigned) (adval * VREF) >> 9,                          /* 
Output Integer Portion */
         (unsigned) ((adval  VREF  10000UL) >> 9UL) % 10000);   /* 
Output Decimal Portion */

  }
}[/c)

Analog den Wert einzulesen und im Debug Modus (µVision3;FA.Keil)
im Serial Window auszugeben.
Leider klappt das nicht, weis jemand weiter??
Vielen Dank schonmal....

von Arc N. (arc)


Lesenswert?

Seite 35 Datenblatt
AMX0P = 0 ->  0 entspricht nicht P1.6
Seite 58 Datenblatt
REF0CN = ?
(Datenblatt von der Keil-Webseite)
VREF wird nicht 5V sein, sondern entweder, siehe oben, VDD (~3.3V) oder 
irgendwas zw. 2.38 V und 2.5 V (int. Referenz).
Je nach dem was als Referenz (bzw. Takt) verwendet werden soll, muss 
dann noch XBR0, P0MDIN, P0MDOUT etc. passend eingestellt werden. 
Einfacher wird's wenn man den Configuration-Wizard nimmt 
http://www.silabs.com/Support%20Documents/Software/ConfigAndConfig2Install.exe

von matwal (Gast)


Lesenswert?

Danke werde das gleich mal ausprobieren!

von matwal (Gast)


Lesenswert?

Arc Net schrieb:

> VREF wird nicht 5V sein, sondern entweder, siehe oben, VDD (~3.3V) oder
> irgendwas zw. 2.38 V und 2.5 V (int. Referenz).
> Je nach dem was als Referenz (bzw. Takt) verwendet werden soll, muss
> dann noch XBR0, P0MDIN, P0MDOUT etc. passend eingestellt werden.
> Einfacher wird's wenn man den Configuration-Wizard nimmt
> http://www.silabs.com/Support%20Documents/Software...

So, hab schon etwas mehr Erfolg gehabt...
Woher weist du das mit der VREF habe jetzt folgenden Code geschrieben, 
er zeigt mir jetzt im Serial window nicht mehr 0V an.
Der Tipp mit dem Config Wizard war auch sehr gut..
Hast du noch eine Idee warum der die Werte im Serial window nicht 
aktualisiert.
Das hier sind meine ersten Erfahrungen mit einem µController.
Bin da noch unerfahren, weis garbicht was das alles heißt.

Vielen Dank für die Hilfe..
Noch frohe Weihnachten

Gruß matwal

von matwal (Gast)


Lesenswert?

Der Code:

#include <c8051f330.h>
#include <stdio.h>

#define VREF  2,5    /* Voltage Reference */

void main ( void )  {

unsigned int adval;

/* initialize the serial interface */
  SCON0  = 0x50;           /* SCON0: mode 1, 8-bit UART, enable rcvr 
*/
  TMOD  |= 0x20;           /* TMOD:  timer 1, mode 2, 8-bit reload 
*/
  TH1    = 221;            /* TH1:   reload value for 9600 baud @ 16MHz 
*/
  TR1    = 1;              /* TR1:   timer 1 run 
*/
  TI0    = 1;              /* TI0:   set TI to send first char of UART 
*/

/*  Configure P0.0 as Analog Input  */
  P1MDIN = 0xBF;           /*  P1.6 only 
*/
  P1SKIP = 0x40;           /*  Skip Crossbar decoding for this pin 
*/

/* Init MUX   */
  AMX0P = 0x0E;             /*  Select Positive Input Port P1.6 
*/
  AMX0N = 0x11;             /*  GND Neg Inputs (Single-ended Mode) 
*/

/* Init ADC   */
  ADC0CF = 0xF8;           /*  SAR clock = 31, Right-justified result 
*/
  ADC0CN = 0x80;            /*  Enable ADC 0, Normal Tracking, 
*/
                           /*  Start Convert on AD0BUSY set 
*/

while (1){

  AD0BUSY = 1;             /*  Start ADC 0 conversion 
*/
  while (AD0BUSY);         /*  Wait for conversion 
*/

/* Read 0-511 value in ADC0 */
  adval = ADC0L + (ADC0H << 8);

/* Output 0-511 ADC0 value without using floating-point */
  printf ("ADC0 Count %4u = %01u.%04u Volts\r",
         (unsigned) adval,
         (unsigned) (adval * VREF) >> 9,                          /* 
Output Integer Portion */
         (unsigned) ((adval  VREF  10000UL) >> 9UL) % 10000);   /* 
Output Decimal Portion */

  }
}

von Arc N. (arc)


Lesenswert?

REF0CN wird noch nicht verwendet!
D.h. wenn die interne Referenz verwendet werden soll:
REF0CN = 3;
und
P0MDIN = 1; P0SKIP = 1; (P0.0 wird analoger Eingang und vom Crossbar 
ausgeschlossen, ext. Kondensatoren an P0.0 nicht vergessen bzw. 
nachbestücken)
Falls VDD als Referenz verwendet werden soll
REF0CN = 8; der Rest (P0...) sollte dann kann Rolle mehr spielen.

#define VREF  2,5
ergibt einen "schönen", hier defnitiv nicht gewünschten, Kommaoperator, 
wenn der Präprozessor VREF durch 2,5 statt 2.5 ersetzt.
Wenn keine Fließkommazahlen verwendet werden sollen, sollte die 
Konstante  auch keine sein...

von matwal (Gast)


Lesenswert?

Danke,

aber mein Pin ist doch P1.6.
Ich möchte wohl gerne mit der internen Referenz arbeiten, da ich ja nur 
diesen Toolstick verwende und keine externe Spannung anliegt...

Danke
Gruß Matwal

von Arc N. (arc)


Lesenswert?

matwal schrieb:
> Danke,
>
> aber mein Pin ist doch P1.6.
> Ich möchte wohl gerne mit der internen Referenz arbeiten, da ich ja nur
> diesen Toolstick verwende und keine externe Spannung anliegt...
>
> Danke
> Gruß Matwal

Ja, aber
"Important Note about the VREF Pin: Port pin P0.0 is used as the 
external VREF input and as an output for the internal VREF. When using 
either an external voltage reference or the internal reference 
circuitry, P0.0 should be configured as an analog pin, and skipped by 
the Digital Crossbar. To configure P0.0 as an analog pin, set to ‘0’ 
Bit0 in register P0MDIN. To configure the Crossbar to skip P0.0, set Bit 
0 in register P0SKIP to ‘1’."
von Seite 61 im Datenblatt
http://www.silabs.com/pages/DownloadDoc.aspx?FILEURL=Support%20Documents/TechnicalDocs/C8051F33x.pdf&src=DocumentationWebPart

von matwal (Gast)


Lesenswert?

Vielen Dank,
habe das mal geändert.
Aber mit dem

#define VREF  2,5    /* Voltage Reference */

komm ich nicht klar das wird doch hier:

/* Output 0-511 ADC0 value without using floating-point */
  printf ("ADC0 Count %4u = %01u.%04u Volts\r",
         (unsigned) adval,
         (unsigned) (adval * VREF) >> 9,                          /*
Output Integer Portion */
         (unsigned) ((adval  VREF  10000UL) >> 9UL) % 10000);   /*
Output Decimal Portion */

wieder gebraucht?!?

Habe dort jetz folgenden Code stehen:



#include <c8051f330.h>
#include <stdio.h>

#define VREF  3      /* Voltage Reference */

void main ( void )  {

unsigned int adval;

/* initialize the serial interface */
  SCON0  = 0x50;           /* SCON0: mode 1, 8-bit UART, enable rcvr 
*/
  TMOD  |= 0x20;           /* TMOD:  timer 1, mode 2, 8-bit reload 
*/
  TH1    = 221;            /* TH1:   reload value for 9600 baud @ 16MHz 
*/
  TR1    = 1;              /* TR1:   timer 1 run 
*/
  TI0    = 1;              /* TI0:   set TI to send first char of UART 
*/

/*  Configure P0.0 as Analog Input  */
    P1MDIN    = 0xBF;
    P1MDOUT   = 0x40;
    P1SKIP    = 0x40;
    XBR1      = 0xC0;
    P0MDIN    = 1;
    P0SKIP    = 1;

           /*  Skip Crossbar decoding for this pin          */
           /*  GND Neg Inputs (Single-ended Mode)           */

/* Init ADC   */
    AMX0P     = 0x0E;
    ADC0CF    = 0xFC;
    ADC0CN    = 0x80;
            /*  Enable ADC 0, Normal Tracking,               */
                           /*  Start Convert on AD0BUSY set 
*/

while (1){

  AD0BUSY = 1;             /*  Start ADC 0 conversion 
*/
  while (AD0BUSY);         /*  Wait for conversion 
*/

/* Read 0-511 value in ADC0 */
  adval = ADC0L + (ADC0H << 8);

/* Output 0-511 ADC0 value without using floating-point */
  printf ("ADC0 Count %4u = %01u.%04u Volts\r",
         (unsigned) adval,
         (unsigned) (adval * VREF) >> 9,                          /* 
Output Integer Portion */
         (unsigned) ((adval  VREF  10000UL) >> 9UL) % 10000);   /* 
Output Decimal Portion */

  }
}

Vielen Dank!!

von F33X (Gast)


Lesenswert?

Laut Datenblatt ist die Referenzspannung typisch bei 2.44V!
Für genaue Ergebnisse beachte auch, die MIN und MAX Werte und die 
Schwankung über Temperatur.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.