PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Analogeingänge abfragen..aber wie ???



Goliath
23.01.2008, 16:41
Hi Leute

Ich programiere seit ca. 4 Wochen in C den ATMega 16 und 32...meist kleine Versuchsprogramme..
Inzwischen sind auch 2 Projekte fertig..

Nun meine Frage.
ich möchte die Anlalogeingänge mit einem Poti beschalten und diese Werte dann im Programm abfragen und auch auf einem LCD ausgeben.

ich programmiere in Codevision..Wäre coll wenn dort jemand evtl. schon was gemacht hat.
Natürlich sind auch alle anderen Vorschläge willkommen..

coll wäre viel. ein beispiel progrmam mit etwas erklärung.

wäre echt dankbar für euro hilfe

Goliath

sloti
23.01.2008, 17:36
Hi,

ich hab hier eine kleine Funktion mit der du den A/D Wandler an Port C0 auslesen kannst. Du musst vorher natürlich noch Port C 0 als eingang konfigurieren. Kucks die mal an, wenn du noch fragen hast frag :).


unsigned int Poti1 (void)
{
ADMUX = 0x00; //Eingang konfigurieren
ADCSRA |= (1 << ADSC); // Wandlung starten
while (!(ADCSRA & (1 << ADIF))); //Warten bis Wandlung fertig
ADCSRA |= (1 << ADIF); //Interrupt flag zurücksetzen
return ADCL + (ADCH << 8); //Wert zurückgeben
}

mfg
Erik

Goliath
23.01.2008, 19:38
Hallo

leider kann ich damit nicht wirklich viel anfangen
wieso port C ??? nur port a kann analogeingänge abfragen

hast du evtl. noch eine andere lösung???

Goliath

oberallgeier
23.01.2008, 20:57
Hi, Goliath,


kann ich damit nicht wirklich viel anfangen
wieso port C ??? nur port a kann analogeingänge abfragenGanz einfach, sloti hat (vermutlich, sicher) den Eingang ADC0 gemeinte, der ist am gleichen Pin wie der PA0, also am PIN40 !

Sieh mal her, vielleicht hilft das besser:

/* ================================================== ============================ */
/* === Initialisierung fuer ADC mega168 ========================================
ADC3/PC3 auf 8 Bit, Wandlung "auf Abruf", es wird kein Interrupt ausgelöst */
void ADC3_8_init(void) //
{
ADMUX |= (1<<ADLAR); // 8bit-left-adjusted (doc S256)
ADMUX |= (1<<MUX1)|(1<<MUX0); // Wandlung für Port ADC3
ADCSRA |= (1<<ADEN); // AD Enable
ADCSRA |= (1<<ADSC); // starte erste Wandlung
}
/* ================================================== ============================ */
Der Code ist zwar für den mega168, aber diese Sequenz wird am m16/m32 auch laufen (hab ich aber in der Eile nicht ausprobiert). Achtung: Das ist eine 8-Bit-Wandlung - für 10 bit guck halt ins doc2503. "Abgehört" wird hier der analoge Eingang auf Port ADC3 - das ist der Pin 37 bzw. Port-Pin PA3.

JETZT kannst Du irgendwo im main oder in einer Subroutine schreiben:


char wortadc[10];

ADC3_8_init(); // Initialisiere ADC3, 8 Bit, auf Abruf

ADCSRA |= (1<<ADSC); // starte Wandlung
waitms(500); //
adc3_dat = ADCH; // Hole ADCHighByte (ADLAR !)
utoa(adc3_dat, wortadc, 10);
sendUSART(" Momentaner ADC-Wert ");
sendUSART(wortadc);sendUSART("\r\n");
und dann kann sowas Ähnliches rauskommen (am Terminal):

Momentaner ADC-Wert 1
Momentaner ADC-Wert 0
Momentaner ADC-Wert 1
Momentaner ADC-Wert 62
Momentaner ADC-Wert 24
Momentaner ADC-Wert 60
Momentaner ADC-Wert 49
Momentaner ADC-Wert 63
Momentaner ADC-Wert 76
Momentaner ADC-Wert 88
Momentaner ADC-Wert 96

sloti
24.01.2008, 13:13
Ich hätte vielleicht dazu sagen sollen, dass ich nen Atmega 8 benutzt habe. Sry.

Grandalf
16.06.2008, 12:41
hier meine lösung bei nem ATmega16 auf dem evaluation-board plus addon-board und rfm12 von pollin

zu der ich aber noch fragen hab ^^



#include <avr/io.h>
#include <avr/iom16.h>
#include <inttypes.h>

uint16_t ReadChannel(uint8_t mux)
{
uint8_t i;
uint16_t result;
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS0); // Frequenzvorteiler
// setzen auf 8 (1) und ADC aktivieren (1)
ADMUX = mux; // Kanal waehlen
ADMUX |= (1<<REFS1) | (1<<REFS0); // interne Referenzspannung nutzen

/* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
while ( ADCSRA & (1<<ADSC) )
{
; // auf Abschluss der Konvertierung warten
}
result = ADCW; // ADCW muss einmal gelesen werden,
// sonst wird Ergebnis der nächsten Wandlung
// nicht übernommen.

/* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */
result = 0;
for( i=0; i<4; i++ )
{
ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
while ( ADCSRA & (1<<ADSC) )
{
; // auf Abschluss der Konvertierung warten
}
result += ADCW; // Wandlungsergebnisse aufaddieren
}
ADCSRA &= ~(1<<ADEN); // ADC deaktivieren (2)
result /= 4; // Summe durch vier teilen = arithm. Mittelwert
return result;
}

void ShowByte(uint16_t wert)
{
PORTC = wert;
}

int main (void)
{
DDRC = 0;
PORTC = 0;
uint16_t adcval = 0;

while(1)
{
adcval = ReadChannel(0); /* MUX-Bits auf 0b0000 -> Channel 0 */
ShowByte(adcval);
}
return 0;
}




meine frage dazu

also am portC hab ich 8 leds dran und so wie ich das verstehe müssten die ja dann in der richtigen bitkombination leuchten wie der wert vom ADC zurückkommt oder?

spricht: (X=aus; O=an)
XXXX XXXX = 0
XXXX XXXO = 1
XXXX XXOX = 2
XXXX XXOO = 3

XXXX XOXX = 4
....
....
....
OOOO OXOO = 251

OOOO OOXX = 252
OOOO OOXO = 253
OOOO OOOX = 254
OOOO OOOO = 255

bei mir siehts aber komischerweise so aus das LED 3, 5 und 6 immer leuchten und wenn ich von 0V bis 5V hochdrehe dann flackern LED 7 und 8 rasend schnell abwechselnd auf und LED 1 und 2 zählen 4 mal durch

also 4mal
XX
XO
OX
OO

kann es sein das ich meinen ADC teiler nicht auf 8bit sondern auf 4 bits beschränkt habe? und kann mir einer erklären warum LED 3, 5 und 6 dauerhaft an sind?

danke

Grandalf