Bitte um Hilfe beim Xmega a1

Status
Für weitere Antworten geschlossen.
ja habe ich. Auch der gewünschte wert wird ausgegeben. wenn ich ihm einen fixwert gebe gibt er das richtig aus.
die USART Übertragen hat bestimmt keinen Fehler.
Der fehler liegt beim aufnehmen der Werte vom Signal, den da bekomm ich immer nur "0".

schöne grüße
 
Im Moment finde ich den Fehler nicht, habe auch nich so richtig Zeit.

Ich schaue mir deinen Code am Wochenende nocheinmal genauer an, compiliere diesen auch mal und teste ihn auf meinem Modul aus.

Grüße,
Dirk
 
Hallo fenomaen,

durch die Forumumstellung bin ich noch nicht dazu gekommen. Lass mir noch etwas Zeit, ich werde dein Code bestimmt zum Laufen bekommen.

Grüße,
Dirk
 
Hallo fenomaen,

ich habe deinen Code compiliert und ausgestestet. Bei mir funktioniert er.

Hier siehst du die Ausgabe mit HTerm.


adc_test.png

Ab der rot umrahmten Ausgabe ziehe ich PIN0 von PORTA gegen GND (GND liegt bei der Stiftleiste direkt neben PIN0), ab hier siehst du den Offset, der wurde in deinem Code ja noch nicht berücksichtigt.

Ich habe in der while(1) Schleife ein _delay_ms(500) eingebaut, damit man die Ausgabe auch lesen kann.

Direkt nach main() hast du einen mehrzeiligen Comment, "/*" ist hierfür in deinem Code nicht vorhanden, es gibt dann natürlich einen Error. Hast du hier noch irgendwelchen Code, den du nicht gepostet hast, also entfernt hast, möglich dass hier der Fehler liegt?!

Warum bei dir immer "0" angezeigt wird? Hmmm. Werden noch irgendwelche Warnings angezeigt?

Grüße,
Dirk
 
Hallo Dirk, das sind tolle Nachrichten.

Könntest du mir vll ein Bild schicken wie du es gesteckt hast ?
Und könntest du mir sagen was du unter Configurations in AVR Studio eingestellt hast?
Ich lese ja vom PortA Pin0 meine Werte? ist das richtig so?

D.h. wenn ich den Pin0 gegen Ground gehen lasse bekomme ich den Offset oder wie ?
Wie kann ich das dann in mein Programm einbauen ?

Nein der Kommentar war unötig habe vergesen "/*" wegzulöschen ..
Bei mir zeigt er auch keine Warnings an.

Schöne Grüße
Feno
 
Hallo Feno,

der ADC-Eingang von CH0 ist dort, wo der rote Pfeil ist. Ein GND ist direkt daneben, wenn du PIN0 von PORTA mit GND kontaktierst, misst du den Offset vom ADC Modul.


adc_pin.png


Ich habe gerade sehr wenig Zeit, weiter auf die Offsetmessung einzugehen, ich mache das eventuell heute Abend mal.

AVR Studio
Device: Xmega128A1
Frequency: 32000000Hz
Optimization: -Os

Grüße,
Dirk
 
Also ich schicke ca. 3,3V auf Pin7 (AVCCA) rein als GND nehme ich den Pin48 und mein CH0 messe ich von Pin6 (PA0), beim roten Pfeil hald.
In meinen Configurations habe ich die Frequency auf 32000000 eingestellt.
Und bei mir schickt er dauernd den wert 0.
Wenn ich eine Konstante definier, sprich temp=3000 gibt er mir es richtig aus ..

Ich versteh nicht was ich falsch mache.
Bei mir wird die Zeit auch schon knapp :-/

Naja jetzt heißts herumprobieren und warten

Hoffe auf baldige anwort.
Schöne Grüße
 
Hallo Feno,

du kannst AVCC einfach mit VCC verbinden.

Mir gehen jetzt aber auch langsam die Ideen aus. Irgendwas müsstest du messen, erst recht, wenn du den Offset noch nicht berücksichtigt hast, eine Null als Messergebnis ist ja sehr unwahrscheinlich.

Ich denke, im Moment hat es auch sicherlich keinen Sinn, sich weiter mit der Offsetkalibrierung zu beschäftigen, zuerst müsste man das Problem lösen :hmmmm:

Ich hänge dir mal ein Zip-File mit dem AVR Studio C Projekt an, vielleicht probierst du es bei dir mal aus.

Grüße,
Dirk

Anhang anzeigen Forum_Xmega_Test.zip
 
Hallo Dirk

Das Programm funktioniert nun Gott sei Dank..
Der Fehler war bzw. was ich geändert habe ist nur das ich die Versorgung 3.3V an den Pin47 (VCC) statt Pin7(AVVC) gelegt habe. Erklären kann ich mir das nicht, aber wenigstens funktioniert es.

Jetzt wäre es toll wenn du mir das mit dem Offset erklären könntest?

Danke im vorhinein

Schöne Grüße
Feno
 
Hallo,

Der Fehler war bzw. was ich geändert habe ist nur das ich die Versorgung 3.3V an den Pin47 (VCC) statt Pin7(AVVC) gelegt habe. Erklären kann ich mir das nicht, aber wenigstens funktioniert es.
Also beim XMega hab ich mir das noch nicht so angesehen. Bei den normalen muß man
auf jeden Fall Vcc und AVcc mit der Versorgungsspannung verbinden. Das ist vor
allem darum wichtig weil der ADC sonst keinen Saft zum Leben hat und außerdem ein paar
Portpins auch keine Spannung rausgeben können. Wo nix ist, kann man nichts schalten.
Bei dir leuchtet die Taschenlampe ja auch nicht wenn du ihr die Batterie klaust :aetsch:

Gruß
Dino
 
auf jeden Fall Vcc und AVcc mit der Versorgungsspannung verbinden.

Hallo Dino!

Ich kann deiner Ausssage zwar zustimmen jedoch glaub ich nicht, dass Feno einen "nackten" XMega vor sich hat.
Wenn ich die Zeichnung von Dirk richtig gedeutet habe, dann geht es um das XMega-Board aus dem Shop.... und dort sind diese Pins dann schon "serienmäßig" verbunden. ;)

Grüße,
Cassio
 
Hallo Feno,

an VCC brauchst du natürlich auch Betriebsspannung. Egal, es geht und ich erkläre dir nun mal die Kalibrierung und Offsetberechnung.

Zuerst mal zur Kalibrierung:
Die beiden ADC Module des Mikrocontrollers sind von Werk aus kalibriert, hierfür sind im NonVolatileMemory (NVM) Kalibrierungswerte hinterlegt. Diese muss man in seinem Programm selber in die Kalibrierungsregister CALL und CALH kopieren. Das geht folgendermaßen:

Code:
// Folgendes einbinden
#include <stddef.h>
#include "avr_compiler.h"
#include <avr/pgmspace.h>
Code:
  // Kalibrierungsbytes lesen und in CAL Register kopieren
  NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc;
  ADCA.CALL = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, ADCACAL0));
  ADCA.CALH = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, ADCACAL1));
  NVM_CMD = NVM_CMD_NO_OPERATION_gc;
Jetzt haben wir die Kalibrierungsbytes in die CAL Register des ADCA kopiert.

Nun folgt die Offsetermittlung:
Der Xmega ist sehr flexibel bezüglich der Kanalwahl. Im Prinzip funktioniert die Offsetermittlung so: Du nimmst dir einen Channel, hier zum Beispiel CH1, stellst diesen auf Differentialmessung ein, die Verstärkung auf x1. Bei der Differentialmessung hast du ja normalerweise einen positiven und einen negativen Pin, du wählst hier den gleichen Pin aus, im Beispiel PIN1. Danach stellst du Prescaler, Referenz ein und aktivierst das ADCA Modul. Danach einen Moment warten, sonst sind die ersten Messungen schlecht.

Im Beispiel mache ich 8 Single Conversions, summiere das Ergebnis, teile danach durch 8, habe also einen Mittelwert, der ist int (int16_t). ADCA_Offset habe ich mal global definiert.

Im Idealfall sollte für den Offset 0 herauskommen, das wird aber nicht der Fall sein. Den ADCA deaktiviere ich nach der Offsetermittlung wieder.

Wenn du nun Messungen machst musst du ADCA_Offset von deinem Ergebnis abziehen, der Offset gilt für das ganze ADCA Modul, es ist also egal welche Pins du welchen Channeln zuordnest.

Mal eine Frage, ist es ein Projekt für eine Abschlußarbeit, Diplomarbeit o.ä., weil du unter Zeitdruckt bist?

Hier nochmal alles zusammen (Alle Angaben natürlich wie immer ohne Gewähr ;)):

Ich hoffe ich konnte dir weiterhelfen.

Grüße,
Dirk

Code:
void ADC_Init(void)
{

  uint8_t i;
  int16_t offset;

  // Kalibrierungsbytes lesen
  NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc;
  ADCA.CALL = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, ADCACAL0));
  ADCA.CALH = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, ADCACAL1));
  NVM_CMD = NVM_CMD_NO_OPERATION_gc;

  // Offset von dem ADCA Module ermitteln
  ADCA.CH1.CTRL = ADC_CH_INPUTMODE_DIFF_gc | ADC_CH_GAIN_1X_gc;
  ADCA.CH1.MUXCTRL = ADC_CH_MUXPOS_PIN1_gc | ADC_CH_MUXNEG_PIN1_gc;
  ADCA.PRESCALER = 0b010;  // DIV16 -> 32MHz/16 = 2MHz
  ADCA.REFCTRL =  (ADCA.REFCTRL & ~(ADC_REFSEL_gm)) | ADC_REFSEL_VCC_gc;
  ADCA.CTRLA = 0b00000001;  // ENABLE=1
  _delay_ms(10);

  ADCA.CTRLA |= 0b00001000;  // Dummy single conversion
  while(!ADCA.CH1.INTFLAGS) { }; // warte auf virtual channel1 complete
  ADCA.CH1.INTFLAGS |= 1;
  offset = 0;
  for (i=0; i<8; i++)
  {
    ADCA.CTRLA |= 0b00001000;  // CHSTART1=1 single conversion
    while(!ADCA.CH1.INTFLAGS) { }; // warte auf virtual channel1 complete
    offset += ADCA.CH1RES;
    ADCA.CH1.INTFLAGS |= 1;
  }
  ADCA_Offset = (int8_t)(offset >> 3);

  ADCA.CTRLA = 0b00000000;  // ENABLE=0

}
 
Hallo Dirk

Hast du vll irgendein Beispielprogramm wo der Timer verwendet wird ?

Wir haben unsere Kommunikation doch geändert .. nähmlich schickt mir der Benutzer 4 ASCII Zeichen diese wandle ich in einen dezimal Wert um dieser ist dann die Messzeit.. dies alles funktioniert. nur den timer muss ich einbinden

Schöne Grüße
Feno
 
Hallo Feno,

du mögchtest also den ADC durch einen Timer triggern?

Ich habe jetzt keinen fertigen Beispiel-Sourcecode, du gehst hier folgendermaßen vor:

  • du initalisiertst hierfür einen Timer zum Beispiel mit Compare-Event, der Compare-Event muss keinen Interrupt auslösen. Jedesmal wenn der Timer den Comparewert erreicht, wird ein Event ausgelöst. Die Intervallzeit des Events wählst du durch den Wert im CompareRegister.
  • Im EventManager (siehe Datenblatt) wählst du in einem EventChannel (zb CH0) den EventSource CompareEvent deines Timers (EVSYS.CH0MUX)
  • In der ADC Initialisierung stellst du Triggersource EventChannel0 ein (ADCA.EVCTRL)

Wenn ihr das Projekt fertig habt, dann aber nicht die Quellenangaben vergessen :)

Grüße,
Dirk
 
Hallo Fenomaen,

mein letzter Beitrag ist nun schon zwei Wochen her.

Seid ihr mit eurem Projekt nun klar gekommen?

Gruß,
Dirk
 
Status
Für weitere Antworten geschlossen.

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)