Forum: Mikrocontroller und Digitale Elektronik ADC Programmcode! Richtig?


von Sebastian (Gast)


Lesenswert?

1
#include <avr/io.h> 
2
3
4
/* ADC initialisieren */
5
void ADC_Init(void) {
6
 
7
  uint8_t i;
8
  uint16_t result;                
9
 
10
  ADMUX = (1<<REFS0);              // Referenzspannug= intern/Avcc
11
  ADMUX = (1<<REFS1) | (1<<REFS0);      // interne Referenzspannung nutzen
12
  ADCSRA = (1<<ADPS1) | (1<<ADPS0);     // Frequenzvorteiler = 32
13
  ADCSRA |= (1<<ADEN);                  // ADC wird aktiviert
14
 
15
  /* nach Aktivieren des ADC liest man einen Wert ein 
16
  und verwirft diesen, um den ADC "warmlaufen zu lassen" */
17
 
18
  ADCSRA |= (1<<ADSC);                  // eine ADC-Wandlung 
19
  while (ADCSRA & (1<<ADSC) ) {}        // auf Abschluss der Konvertierung warten
20
  
21
  result = ADCW;            //gemessenen Werte werden hier gespeichert 
22
23
//Eigentliches Programm startet
24
25
  uint16_t ADC_Read( uint8_t MUX4 )
26
27
  result = 0; 
28
  for( i=0; i<4; i++ )
29
  {
30
    ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
31
    while ( ADCSRA & (1<<ADSC) ) {
32
      ;   // auf Abschluss der Konvertierung warten
33
    }
34
    result += ADCW;        // Wandlungsergebnisse aufaddieren
35
  }
36
  ADCSRA &= ~(1<<ADEN);             // ADC deaktivieren (2)
37
 
38
  result /= 4;                     // Summe durch vier teilen = arithm. Mittelwert
39
 
40
  return result;
41
}




Ich möchte von ADC6 (PA6) den Wert meines Temperatur Sensors einlesen.
Mein Atmel läuft mit Externer ACC von +5V, mit 16 Mhz. Nun hab ich den 
Teilungsfaktor 32 Eingestellt, sowie auch die Referenzspannung auf ACC 
eingestellt, stimmt das in etwa?

Ist das mit dem " uint16_t ADC_Read( uint8_t MUX4 )" richtig oder muss 
das raus?

Danke im vorraus.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Sebastian schrieb:

>   ADMUX = (1<<REFS0);              // Referenzspannug= intern/Avcc
>   ADMUX = (1<<REFS1) | (1<<REFS0);      // interne Referenzspannung

Die zweite Zeile hebt die Zuweisung der vorherigen auf.

>   ADCSRA = (1<<ADPS1) | (1<<ADPS0);     // Frequenzvorteiler = 32
>   ADCSRA |= (1<<ADEN);                  // ADC wird aktiviert

Kann in eine einzige Zeile 'rein.

>   uint16_t ADC_Read( uint8_t MUX4 )

Sieht aus wie eine Funktionsdefinition (allerdings innerhalb einer
Funktion, könnte GCC theoretisch unterstützen, ist aber hier sicher
nicht sinnvoll), aber dann müsste danach eine öffnende geschweifte
Klammer mit dem Inhalt der Funktion kommen.

Compiliert der GCC dir das denn?

> Ich möchte von ADC6 (PA6) den Wert meines Temperatur Sensors einlesen.

Wo stellst du denn im ADMUX diesen Kanal ein?

> Nun hab ich den
> Teilungsfaktor 32 Eingestellt, sowie auch die Referenzspannung auf ACC
> eingestellt, stimmt das in etwa?

Kann sein, muss nicht.  Habe jetzt die REFSn-Bits nicht nachgelesen,
ob du damit AVcc wirklich ausgewählt hast, aber lesen wirst du ja
können. ;-)

Der ADC soll vorrangig mit 50 ... 200 kHz betrieben werden, bei einem
Teilerfaktor von 32 müsste dein CPU-Takt also irgendwo zwischen 1,6
und 6,4 MHz liegen.

von Lutz (Gast)


Lesenswert?

Sebastian schrieb:
> while (ADCSRA & (1<<ADSC) ) {}        // auf Abschluss der Konvertierung warten

Unabhängig vom dort fehlenden Semikolon: Wer soll zum unbekannten 
Prozessor was sagen können? Oder was macht uint16_t ADC_Read( uint8_t 
MUX4 ) wann und wie?

von Karl H. (kbuchegg)


Lesenswert?

Sebastian schrieb:

> Ich möchte von ADC6 (PA6) ....

Du möchtest dir vor allen Dingen als erstes einmal ein C Buch kaufen und 
da die ersten paar Kapitel durcharbeiten (nicht durchlesen ... 
durcharbeiten!)

von Sebastian (Gast)


Lesenswert?

Anfänger werden hier standardmäßig verarscht oder rausgemobbt!!!

Es ist noch kein Meister vom Himmel gefallen.

So ein neuer Code mit 20 Mhz:
1
#include <avr/io.h> 
2
3
4
/* ADC initialisieren */
5
uint16_t ADC_Init(void) {
6
 
7
  uint8_t i;
8
  uint16_t result;                
9
 
10
  ADMUX  = 0x06;               //Kanal 6 gewählt 
11
  ADMUX  = (1<<REFS1) | (1<<REFS0);        // interne Referenzspannung nutzen
12
  ADCSRA = (1<<ADPS1) | (1<<ADPS0)|(1<<ADPS2);       // Frequenzvorteiler = 128
13
  ADCSRA|= (1<<ADEN);                    // ADC wird aktiviert
14
 
15
  /* nach Aktivieren des ADC liest man einen Wert ein 
16
  und verwirft diesen, um den ADC "warmlaufen zu lassen" */
17
 
18
  ADCSRA |= (1<<ADSC);                  // eine ADC-Wandlung 
19
  while (ADCSRA & (1<<ADSC) ) {}        // auf Abschluss der Konvertierung warten
20
  
21
  result = ADCW;            //gemessene Werte werden hier gespeichert 
22
23
//Eigentliches Programm startet
24
25
  
26
  result = 0; 
27
  for( i=0; i<4; i++ )
28
  {
29
    ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
30
    while ( ADCSRA & (1<<ADSC) ) {
31
      ;   // auf Abschluss der Konvertierung warten
32
    }
33
    result += ADCW;        // Wandlungsergebnisse aufaddieren
34
  }
35
36
 
37
  result /= 4;                     // Summe durch vier teilen = Mittelwert
38
 
39
  return result;
40
}

von holger (Gast)


Lesenswert?

>  ADMUX  = 0x06;               //Kanal 6 gewählt
>  ADMUX  = (1<<REFS1) | (1<<REFS0);        // interne Referenzspannung nutzen

Tja, und damit ist Kanal 6 wieder tot.

>Anfänger werden hier standardmäßig verarscht oder rausgemobbt!!!

Dann geh doch woanders hin.

von Helfer (Gast)


Lesenswert?

Für die Anfänger wurde das AVR-GCC-Tutorial geschrieben und da sind die 
ADC Funktionen als getesteter Code inkl. Beispielanwendung enthalten. 
Wenn Anfänger ohne Anmerkungen oder Rücksicht auf das AVR-GCC-Tutorial 
hier eigenen Code präsentiert, muss er damit rechnen, dass der ohne 
Rücksicht auseinander genommen wird.

Bei deinem Code sieht man nicht, wie er aufgerufen wird, d.h. die 
Funktion ist per se unprüfbar. Und es macht C-typisch (1. Code) und 
programmlogisch (2. Code) keinen Sinn die Messfunktionalität in der 
Initialisierung zu implementieren. Der Hinweis auf "C-Lernen!" ist also 
nicht unberechtigt bzw. keine Verarsche oder Mobbing.

von Karl H. (kbuchegg)


Lesenswert?

Sebastian schrieb:
> Anfänger werden hier standardmäßig verarscht oder rausgemobbt!!!
>
> Es ist noch kein Meister vom Himmel gefallen.
>


Das hat mit Meister vom Himmel fallen nichts zu tun.
Schon eher mit der Überheblichkeit mancher Anfänger und der Denkweise, 
dass sie die Grundlagen nicht lernen müssten.

Wenn du in einem Physikforum nach der Relativitätstheorie fragst und 
beireits beim Hebelgesetz aussteigst, wird man dir auch erst mal ein 
Physikbuch auf Einsteigerniveau nahelegen.

Ein Programm zu schreiben ist schwieriger als alles andere, was du 
bisher in deinem Leben gemacht hast. Gott sei Dank wissen das auch viele 
Leute und haben all die großen und kleinen Details in Büchern 
geschrieben. Die haben im Falle von C nicht selten mehr als 200 Seiten, 
von denen du die ersten 50 bis 70 intus haben solltest, ehe du dann ins 
Lager der µC Programmierer wechseln kannst.

von Karl H. (kbuchegg)


Lesenswert?

Helfer schrieb:

> Bei deinem Code sieht man nicht, wie er aufgerufen wird,


Ich hege den Verdacht, dass Sebastian der Ansicht ist, dass wäre bereits 
alles was notwendig ist. Also: Das wäre das komplette vollständige 
Programm.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Lutz schrieb:
> Sebastian schrieb:
>> while (ADCSRA & (1<<ADSC) ) {}        // auf Abschluss der Konvertierung warten
>
> Unabhängig vom dort fehlenden Semikolon:

Nö, das fehlt nun gerade nicht, zwei geschweifte Klammern bilden sehr
wohl eine leere Anweisung.

Aber, paar Zeilen später:
1
    while ( ADCSRA & (1<<ADSC) ) {
2
      ;   // auf Abschluss der Konvertierung warten
3
    }

Sieht aus wie copy, paste'n die.  Wenn man sich für eine bestimmte
Ausdrucksweise entschieden hat, sollte man diese innerhalb eines
Werks auch konsistent durchziehen, statt dasselbe immer wieder anders
aufzuschreiben.

von Frank S. (franksanderdo)


Lesenswert?

Helfer schrieb:
> Wenn Anfänger ohne Anmerkungen oder Rücksicht auf das AVR-GCC-Tutorial
> hier eigenen Code präsentiert, muss er damit rechnen, dass der ohne
> Rücksicht auseinander genommen wird.

Auch wenn ich die Ansicht unterstütze das Tutorials gelesen werden 
sollen:

In keinem Umfeld sollte eine Person ohne Rücksicht auseinander genommen 
werden!!

Grüße
Frank

von Helfer (Gast)


Lesenswert?

Das der in dem Satz bezieht sich auf den Code und nicht auf die 
Person. Bzgl. der Person gebe ich dir Frank uneingeschränkt Recht.

von Frank S. (franksanderdo)


Lesenswert?

Hallo Helfer,

sorry dann habe ich das falsch verstanden.

Grüße
Frank

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.