Forum: Compiler & IDEs Analog Digitalwandler ATmega8535


von Micha (Gast)


Lesenswert?

Hallo, ich es kann mir jemand helfen.
Ich würde gerne bei meine ATmega8535 den Analogeingang verwenden.
Ich hab einen WiederstandsSchalter, welcher auf PA0 die Spannungen 3,7, 
2,5 , 1,2 und 0 V gibt. Leider kann ich diese Spannungen mit 
eigesteckten AVR nicht messen. Ich messe ständig 5V. Hat vieleicht 
jemand ein Beispielprogramm, oder funktion, welche den AD Wandler 
acktiviert, ausliest, und mir eine Variable zurückgibt, die sagt in 
welcher stellung der Schalter steht.Ach ja , die schalterstellung 0 V 
verursacht bei eingestecken AVR einen Kurzschluss, warscheinlich mache 
ich schon bei der Portzuweisung was falsch.

Hier mein Progrtamm auszug.
#include <avr/io.h>

#include <stdint.h>

#include <avr/interrupt.h>

#include <avr/signal.h>

#include <avr/delay.h>

#ifndef F_CPU

#define F_CPU 4000000UL

#endif



int Port_a;

int Port_c;

int Port_d;

int temp;

int x;/*x = Wartezeit in ms*/

int y;

int m;

int s;

int zeit;

int blasen;

int blas_zeit;

int result;

// Beginn Hauptprogramm

int main(void)

{

blasen = 0;

m = 0;

//Parameter:

zeit = 10; // Überwachungszeit in Minuten

blas_zeit = 1;//nach dieser Zeit wird gereinigt. In Minuten

/*Analogwandler einstellen.*/

ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS0);//ADC acktivieren 
Frequnzteiler setzen

ADMUX &= ~(1<<MUX0); //AD Kanal an PA0

ADMUX &= ~(1<<MUX1); //AD Kanal an PA0

ADMUX &= ~(1<<MUX2); //AD Kanal an PA0

ADMUX &= ~(1<<MUX3); //AD Kanal an PA0

ADMUX &= ~(1<<MUX4); //AD Kanal an PA0
ADCSRA |= (1<<ADSC);

while(!(ADCSRA & (1<<ADIF)));

ADCSRA = (1<<ADIF);

for(i=0;i<4;i++)

{

ADCSRA |= (1<<ADSC);

while(!(ADCSRA & (1<<ADIF)));

result += ADCW;

ADCSRA = (1<<ADIF);

result /= 4;

}



  if (result == 0)

  {

  for (;;)

  {

  set_Portc(PC1);//Lampe ein

  wait(2000);

  reset_Portc(PC1);//Lampe aus

  wait(2000);

  }

  }



}

Bin für jede Hilfe Dankbar.

Gruß Micha

von unsichtbarer WM-Rahul (Gast)


Lesenswert?

Was möchtest du damit bewirken? Was sollen die Kommentare bedeuten?

ADMUX &= ~(1<<MUX0); //AD Kanal an PA0

ADMUX &= ~(1<<MUX1); //AD Kanal an PA0

ADMUX &= ~(1<<MUX2); //AD Kanal an PA0

ADMUX &= ~(1<<MUX3); //AD Kanal an PA0

ADMUX &= ~(1<<MUX4); //AD Kanal an PA0
ADCSRA |= (1<<ADSC);

Im Datenblatt ist i.d.R. ein Beispiel angegeben...

von johnny.m (Gast)


Lesenswert?

@Rahul:
Ich denke, er will damit lediglich die MUX-Bits alle auf Null setzen, um 
PA0 als ADC-Eingang auszuwählen. Ist so direkt nix gegen einzuwenden, 
nur ein bisschen arg unübersichtlich geschrieben. Geht auch in einer 
Zeile...

@Micha:
PORTC.1, an dem anscheinend eine Lampe hängt, wird nirgends als Ausgang 
konfiguriert. Das kann so nix werden.

von johnny.m (Gast)


Lesenswert?

Ach ja, wenn Du eine Mittelwertbildung über 4 Messungen machen willst, 
dann darfst Du die Division durch 4 erst nach der letzten (vierten) 
Messung machen. So wie es da steht, kommt sicher Müll raus.

von johnny.m (Gast)


Lesenswert?

Und noch was: Du löschst beim Löschen des ADIF schon nach der ersten 
Messung alle anderen Bits im ADCSRA und damit auch das ADEN. Danach 
läuft der ADC nicht mehr! Das Programm hängt dann in der for-Schleife 
und macht keinen Mucks mehr, weil ADIF nie wieder gesetzt wird. Wenn 
dann muss es heißen

ADCSRA |= 1 << ADIF;

Das mit dem Oder ist in diesem Fall unproblematisch, weil ADCSRA keine 
anderen Interrupt-Flags enthält, die dadurch gelöscht werden könnten.

von johnny.m (Gast)


Lesenswert?

BTW: Wenn Du nur mit vorzeichenlosen Werten arbeitest, dann solltest Du 
Deine Integer-Variablen auch als "unsigned int" deklarieren.

von Micha (Gast)


Lesenswert?

Danke für die Antworten.
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS0);//ADC acktivieren
ist diese Zeile so richtig ?
Denn Ausgang für die Lampe habe ich schon deffiniert, Habe das ganze 
blos vergessen in den Post zu kopieren.

von johnny.m (Gast)


Lesenswert?

Wenn der Prescaler mit den Einstellungen eine brauchbare Taktfrequenz 
liefert, dann sollte das so funktionieren. Zur Sicherheit kann es 
sinnvoll sein, das Interrupt-Flag vor dem Start der ersten Messung zu 
löschen, nur für den Fall, dass es aus irgendwelchen Gründen schon 
gesetzt sein sollte. Sonst kommt nämlich Mist raus.

von Micha (Gast)


Lesenswert?

Wenn ich PortA0 als eingang für den ADC verwenden will.
Ist dann richtig wenn ich schreibe:
ADMUX = ((1<<MUX0) | (1<<Mux1) | (1<<Mux2));

Weil aus irgend einen Grund ziet der Port0 die Spannung auf 5V.
Muß ich Port0 als Eingang deklarieren ?

von johnny.m (Gast)


Lesenswert?

Du musst ihn als Eingang konfigurieren und (ganz wichtig!) den Pull-Up 
ausschalten (PORTA.0 = 0)

von Micha (Gast)


Lesenswert?

Ok Danke, jetzt futzts. Danke

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.