Hallo,
ich versuche zwei ADC-Kanäle vom ATxmega8E5 Microcontroller von Atmel
auszulesen. Leider scheint die Auswertung nicht zu klappen am ADC PIN.2
liegen 1,07V an und bei der if-Abfrage müsste es die Variable
s_GLO.ucHardwareVersion = STD setzen es springt aber immer in den else
Zweig.
Hat jemand eine Idee was im Quellcode noch verkehrt ist bzw. wie ich es
noch testen könnten?
DEU schrieb:> Hat niemand einen Tipp? Ich habe mir schon gedacht das ich vllt das> umschalten zwischen den beiden Kanälen verzögern muss oder so?
Dein Quellcode ist nicht komplett. Es ist z.B. nirgends zu sehen wo
ui16TimerADC definiert ist geschweige denn wo es beschrieben wird.
Tipp: Reduziere deinen Code auf ein Minimum und schaue ob das Problem
dann immer noch besteht. Von da aus erweiterst du deinen Code immer
Schritt für Schritt bis zu deinem jetzigen Code. Somit solltest du recht
zügig die Stelle finden, an der es nicht mehr passt.
Hallo,
ich habe den Quellcode jetzt möglichst reduziert habe aber nun das
Problem wenn ich beide Pins vom ADC gleichzeitig auslese dann bekomme
ich zufällige Werte eingelesen.
Wenn ich nur einen Pin auslese funktionert es.
Was könnte das Problem sein?
1
#define F_CPU 8000000UL
2
#include<util/delay.h>
3
#include<avr/io.h>
4
#include<stdint.h>
5
#include"prototypen.h"
6
#include"defines.h"
7
8
/*######################## begin global variables ##########################*/
9
10
structglobal
11
{
12
/*ADC-read*/
13
uint16_tui16VoltageHwVer;// voltage for HW-Ver. detection
Hallo,
DEU schrieb:> Channel->MUXCTRL = (Pin << 3);
ist eine Schreibweise die ich nicht kenne.
Meine Zugriffe starte ich zum Beispiel mit:
ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN1_gc ;
ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN2_gc ;
usw.
Gruß G.G.
@ DEU (Gast)
>Hat jemand eine Idee was im Quellcode noch verkehrt ist bzw. wie ich es>noch testen könnten?>void ADC_init (void)>{> ADCA.CTRLB = ADC_RESOLUTION1_bm; // set ADC-Resolution to 8Bit> ADCA.REFCTRL = ADC_REFSEL2_bm; // select Referenz Vcc/2 @3,19V = 1,595V =
1,514V (Offset = 13 = 81mV) @3,55V = 1,775V = 1,685V (Offset = 13 = 90mV)
> ADCA.PRESCALER = ADC_PRESCALER2_bm; // select Prescaler 64 = 125kHz> ADCA.CH0.CTRL = ADC_CH_INPUTMODE0_bm; // select Single-ended mode> //ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS1_bm;//ADC_CH_MUXPOS0_bm; // select ADC-Pin1
Das sieh soweit OK aus.
> ADCA.CTRLA = ADC_ENABLE_bm | ADC_START_bm; //set ADC enable and start
ADC-conversion
Warum startest du den ADC hier? Einschalten (enable) reich vollkommen.
> uint8_t ADCA_Selection(ADC_CH_t *Channel, uint8_t Pin)
Der Name dieser Funktion ist irreführend! Es wird nicht nur der
ADC-Kanal ausgewählt, es wird auch gemessen! Also sollte diese Funktion
irgendwie eas mit read heißen!
https://www.mikrocontroller.net/articles/Strukturierte_Programmierung_auf_Mikrocontrollern#Benennung_von_Variablen.2C_Makros.2C_Nutzung_von_Anweisungen> {> (*Channel).MUXCTRL = (Pin << 3); //selection of ADC-Pin
Falscher Fehler. Beim ATXmega arbeitet man mit den vordefinerten
Bitmasken, NICHT den Bitnummern!
Siehe Bitmanipulation. Hier muss du per switch() die Pinnummer in
das passende Bitmuster umrechnen. Im einfachsten Fall geht es mit einem
direkten Reinschreiben, das muss man aber prüfen, ob das so im
Datenblatt steht (das hah ich nicht)
(*Channel).MUXCTRL = Pin;
>void ADC_read (void)
Auch der Name ist falsch, denn sie macht deutlich mehr als den ADC
auslesen.
>{> static uint8_t ucADC_Buffer_HW_Ver[ADC_BUFFER_SIZE],
ucADC_Buffer_Bat_Volt[ADC_BUFFER_SIZE];
> static uint8_t ucADC_Buffer_Pointer;> uint8_t uci;> if( (e_Zustand != DC_LADEN) )> {> ADC_init();
Das hier ist falsch! Du willst den ADC nicht bei jedem Auslesen
initialisieren! Das macht man nur einmal beim Programmstart.
DEU schrieb:> Channel->MUXCTRL = (Pin << 3);
Damit setzt du für MUX beim ersten Aufruf '10000' und beim zweiten
'1000'
Folgich wählst du als Eingänge ADC0 und ADC8, das sicher nicht die
Kanäle sind, die an deinen Pins anliegen.
Dominik B. schrieb:> Damit setzt du für MUX beim ersten Aufruf '10000' und beim zweiten> '1000'
das ist genau das was ich machen will denn laut Datenblatt ist Bitnummer
4 Pin 1 und Bitnummer 3 Pin2.
An PortA Pin 1 und Pin 2 liegen genau meine Spannungen an die ich
einlese.
Falk B. schrieb:>> (*Channel).MUXCTRL = (Pin << 3); //selection of ADC-Pin>> Falscher Fehler. Beim ATXmega arbeitet man mit den vordefinerten> Bitmasken, NICHT den Bitnummern!> Siehe Bitmanipulation. Hier muss du per switch() die Pinnummer in> das passende Bitmuster umrechnen. Im einfachsten Fall geht es mit einem> direkten Reinschreiben, das muss man aber prüfen, ob das so im> Datenblatt steht (das hah ich nicht)>> (*Channel).MUXCTRL = Pin;
ich habe es im Simulator durchgespielt und die Richtigen Bits werden im
Register MUXCTRL gesetzt
ich habe auch schon versucht zwischen den Kanalwechsel zu warten, hat
aber keinen Effekt. Das Problem ist das ein Channel für sich
funktioniert nehme ich aber den zweiten dazu werden falsche werte
eingelesen.
Was könnte noch das Problem im Quellcode sein?
DEU schrieb:> Dominik B. schrieb:>> Damit setzt du für MUX beim ersten Aufruf '10000' und beim zweiten>> '1000'>> das ist genau das was ich machen will denn laut Datenblatt ist Bitnummer> 4 Pin 1 und Bitnummer 3 Pin2.
Mein Fehler. Habe mich auf ein falsches Datenblatt bezogen bei dem
MUXPOS die Bits 0 bis 3 sind.
DEU schrieb:> ich habe auch schon versucht zwischen den Kanalwechsel zu warten, hat> aber keinen Effekt
Du wartest nach dem Start einer Wandlung auf das Interrupt-Flag
DEU schrieb:> while(!Channel->INTFLAGS)
Laut Datenblatt wird dieses Flag entweder zurückgesetzt, wenn der
Interrupt Vector aufgerufen wird oder das Bit manuell mit einer '1'
beschrieben wird.
Vermutlich wird das Flag also nach der ersten Wandlung nie zurückgesetzt
und beim Start der zweiten Wandlung nicht mehr gewartet bis diese fertig
ist.