ADC Programmcode! Richtig?

Gast #2199656
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.
Moderator Persönliche Seite #2199765
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.
Gast #2199864
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
}
Gast #2199872
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.
Gast #2199885
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.
#2199928
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.
Moderator Persönliche Seite #2200437
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.
#2200480
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren