Forum: Mikrocontroller und Digitale Elektronik Hilfe bei AD-Wandler!


von My T. (mytrasher)


Lesenswert?

Hallo,
wir müssen nächste Woche einen AD-Wandler Programmieren!#
Wir bekommen einen Stk-500 und dazu einen Poti welchen wir auf PortA 
Stecken...
Wir müssen halt das Ding drehen und uns wird halt auf der LED das 
Ergebnis angezeigt....So ziemlich einfach ausgedrückt ;D

Ich habe zuhause selber einen STK 500 und mir wurde von einem 
Laboringenier aus unserer FH ein Poti gegeben, welchen wir auch in 
Praktikum nutzen werden! So dache ich mir, ich konnte zuhause schon 
Fertig machen bzw. damit bissl experimentieren!
Das Problem ist, es kommen immer die gleichen Fehler!

Error  2  'ADMUX' undeclared
Error  4  'REFS1' undeclared
und so weiter !!


Das Progeamm sieht wie folgt aus!

Danke im Vorraus!

#include <avr/io.h>
#include <stdint.h>
#include <util/delay.h>

uint16_t adcWert = 0;


int main (void) {

  DDRB = 0xff;
  PORTB = 0xff;

  //definiere Input
  ADMUX = 0;
  ADMUX &= ~(1<<REFS1);
  ADMUX |= (1<<REFS0);

  int result = 0;
  int i = 0;
  int erg = 0;
  int messungen = 8;

  while (1) {

    //Status Register
    //       Enable
    //             Prescale Bits 111 = 128
    ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
    //        Start Conversion
    ADCSRA |= (1<<ADSC);

    while (i<messungen) {
      //warte bis AD Wandler fertig
      while (ADCSRA & (1<<ADSC));

      //     ADC-Word = 10 Bit Wert
      result = ADCW;
      //unterste 2 Bit entfernen (ok gibt bessre lösungen)
      result /= 4;
      erg += result;
      i++;
      _delay_ms (40);
    }

      //ADEN ausschalten
      ADCSRA &= ~(1<<ADEN);

      //Mittelwert bilden aus X Messungen
      erg = erg/messungen;
      PORTB =~(erg);

      //temp variablen zurücksetzen
      i=0;
      erg = 0;
  }

  return 0;
}

von Spess53 (Gast)


Lesenswert?

Hi

>Das Problem ist, es kommen immer die gleichen Fehler!

>Error  2  'ADMUX' undeclared
>Error  4  'REFS1' undeclared

Dann ist enweder der Falsche oder kein Controller eimgestellt. Womt 
programmierst du?

MfG Spess

von My T. (mytrasher)


Lesenswert?

Ups vergesen zu sagen mit AVR studio 5!

von Uwe (de0508)


Lesenswert?

Hallo,

hier ist meine kleine Bibliothek aus einem meiner Projekte mit einem 
atMega32 - DDS AD9834.

Es wird automatisch der richtige ADC-Prescaler berechnet, für meine 
Anwendung habe ich 4 Macros ADC_AN0:ADC_AN3 definiert, die den ADC 
Eingängen gleichgesetzt sind.

Vor der ersten Nutzung wird |adc_init( void )| aufgerufen und 
|adc_messung(...)| stellt ein Beispiel für die Anwendung der weiteren 
Funktionen dar.

ok?
1
// --------------------------------------------------------
2
// Systemlibs
3
// --------------------------------------------------------
4
5
#include <avr/io.h>
6
#include <avr/sfr_defs.h>
7
#include <avr/interrupt.h>
8
9
#include <stdint.h>
10
#include <stdlib.h>
11
#include <stdbool.h>
12
13
// --------------------------------------------------------
14
// Konstantendeklaration
15
// --------------------------------------------------------
16
17
// Festlegung der realen ADC Ports
18
// ist nur ein Test am atMega32
19
20
#define ADC_AN0    7
21
#define ADC_AN1    7
22
#define ADC_AN2    7
23
#define ADC_AN3    7
24
25
// --------------------------------------------------------
26
// ADC Prescale Value
27
// --------------------------------------------------------
28
29
#define ADC_ADPS2_0(b2,b1,b0)  ((b2)<<ADPS2 ^ (b1)<<ADPS1 ^ (b0)<<ADPS0)
30
31
#define ADC_PRESCALE_2    ADC_ADPS2_0(0,0,1)
32
#define ADC_PRESCALE_4    ADC_ADPS2_0(0,1,0)
33
#define ADC_PRESCALE_8    ADC_ADPS2_0(0,1,1)
34
#define ADC_PRESCALE_16    ADC_ADPS2_0(1,0,0)
35
#define ADC_PRESCALE_32    ADC_ADPS2_0(1,0,1)
36
#define ADC_PRESCALE_64    ADC_ADPS2_0(1,1,0)
37
#define ADC_PRESCALE_128  ADC_ADPS2_0(1,1,1)
38
39
// --------------------------------------------------------
40
// ADC Prescale
41
// --------------------------------------------------------
42
43
// max. ADC Taktfrequenz laut Datenblatt, 200.000kHz
44
#define ADC_SPEED    200000ul
45
46
#if (F_CPU / 2) <= ADC_SPEED
47
# define ADC_PRESCALE    ADC_PRESCALE_2
48
#elif (F_CPU / 4) <= ADC_SPEED
49
# define ADC_PRESCALE    ADC_PRESCALE_4
50
#elif (F_CPU / 8) <= ADC_SPEED
51
# define ADC_PRESCALE    ADC_PRESCALE_8
52
#elif (F_CPU / 16) <= ADC_SPEED
53
# define ADC_PRESCALE    ADC_PRESCALE_16
54
#elif (F_CPU / 32) <= ADC_SPEED
55
# define ADC_PRESCALE    ADC_PRESCALE_32
56
#elif (F_CPU / 64) <= ADC_SPEED
57
# define ADC_PRESCALE    ADC_PRESCALE_64
58
#else
59
# define ADC_PRESCALE    ADC_PRESCALE_128
60
#endif
61
62
// --------------------------------------
63
// Hilfsvariable der ADC ISR-Routine
64
// --------------------------------------
65
66
// Maximale Messung für einen Mittelwert
67
static uint8_t adc_avg_max = 1;
68
69
// Ergebnis der ADC Mittelwert-Messung
70
static volatile uint32_t adc_avg_channel = 0;
71
72
// Signal an das wartende Messprogramm
73
static volatile bool_t adc_avg_ready = false;
74
75
// --------------------------------------------------------
76
// ADC Hilfsmacros
77
// --------------------------------------------------------
78
79
#define ADC_DISABLE_INT()    ADCSRA &= (uint8_t)~_BV(ADIE)
80
#define ADC_ENABLE_INT()    ADCSRA |= _BV(ADIE)
81
#define ADC_START_NEW_MESSURED()  ADCSRA |= _BV(ADSC)
82
83
#define ADC_WAIT_CONVERT_READY()  do { } while ( ADCSRA & _BV(ADSC) )
84
85
#define ADC_DISABLE()      ADCSRA &= (uint8_t)~(1<<ADEN)
86
#define ADC_ENBALE()      ADCSRA |= (1<<ADEN)
87
88
#define ADC_SET_REF(ref)    do { \
89
 uint8_t admux = ADMUX; \
90
 admux &= (uint8_t)~(_BV(REFS1) | _BV(REFS0)); \
91
 admux |= (uint8_t)(ref); \
92
 ADMUX = admux; \
93
} while(0)
94
95
#define ADC_SET_CHANNEL(chn)    do { \
96
 uint8_t admux = ADMUX; \
97
 admux &= (uint8_t)~(0x07); \
98
 admux |= ((chn) & 0x07); \
99
 ADMUX = admux; \
100
} while(0)
101
102
#define ADC_SET_PRESCALE(ps)    do { \
103
 uint8_t adcsra = ADCSRA; \
104
 adcsra &= (uint8_t)~(ADC_ADPS2_0(1,1,1)); \
105
 adcsra |= (uint8_t)(ps); \
106
 ADCSRA = adcsra; \
107
} while(0)
108
109
// --------------------------------------------------------
110
// void adc_init( void );
111
// --------------------------------------------------------
112
113
void adc_init( void )
114
{
115
  // Analog Comparator Disable
116
  ACSR = _BV(ACD);
117
118
#ifdef DIDR0
119
  // Digital Input Disable Register 0
120
  // ADC7D:ADC0D
121
  DIDR0 = (_BV(ADC_AN3) ^ _BV(ADC_AN2) ^ _BV(ADC_AN1) ^ _BV(ADC_AN0));
122
#endif
123
124
  // Set ADC-pins to input
125
  // atMega32
126
  // pullup off
127
  PORTA &= (uint8_t)~(_BV(ADC_AN3) ^ _BV(ADC_AN2) ^ _BV(ADC_AN1) ^ _BV(ADC_AN0));
128
  // set bits to input
129
  DDRA &= (uint8_t)~(_BV(ADC_AN3) ^ _BV(ADC_AN2) ^ _BV(ADC_AN1) ^ _BV(ADC_AN0));
130
131
  // enable ADC
132
  ADC_ENBALE();
133
  ADC_SET_PRESCALE(ADC_PRESCALE);
134
135
  // AVCC with external capacitor at AREF pin
136
  // ADC_SET_REF( (0<<REFS1) ^ (1<<REFS0) );
137
138
  // Internal 2.56V Voltage Reference with external capacitor at AREF pin
139
  ADC_SET_REF( (1<<REFS1) ^ (1<<REFS0) );
140
141
  ADC_SET_CHANNEL( 0 );
142
143
  ADC_START_NEW_MESSURED();
144
145
 /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, 
146
    man liest also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" 
147
  */
148
  ADC_WAIT_CONVERT_READY();
149
  (void)ADCW;
150
}
151
152
// --------------------------------------------------------
153
// void adc_start_isr_measurement( 
154
//  uint8_t adc_id0, uint8_t adc_id1,
155
//  uint8_t adc_avg_cnt              );
156
// --------------------------------------------------------
157
158
static void adc_start_isr_measurement( uint8_t adc_id, uint8_t adc_avg_cnt )
159
{
160
  // ADC Kanal setzen
161
  ADC_SET_CHANNEL( adc_id );
162
163
  // Anzahl der Messungen für einen Mittelwert
164
  adc_avg_max = adc_avg_cnt;
165
166
  // Variable initialisieren
167
  adc_avg_ready = false;
168
169
  // enable ADC ISR
170
  ADC_ENABLE_INT();
171
172
  // Erste Messung anstossen
173
  ADC_START_NEW_MESSURED();
174
}
175
176
// --------------------------------------------------------
177
// void adc_stop_isr_measurement( void );
178
// --------------------------------------------------------
179
180
static void adc_stop_isr_measurement( void )
181
{
182
}
183
184
// --------------------------------------------------------
185
// ISR(ADC_vect);
186
// --------------------------------------------------------
187
188
ISR(ADC_vect)
189
{
190
  //lokale Variable der ADC ISR-Routine
191
  static uint8_t adc_avg_counter = 0;
192
193
  // Messwert auslesen und Mittelwert bilden
194
  adc_avg_channel += ADCW;
195
196
  // loop counter
197
  if (++ adc_avg_counter == adc_avg_max) {
198
    adc_avg_counter = 0;
199
200
    ADC_DISABLE_INT();        // Disable ADC Interrupt
201
202
    // Mittelwert-Ergebnisse berechnen
203
    adc_avg_channel /= adc_avg_max;
204
205
    // Signal an die wartende Procedure
206
    adc_avg_ready = true;
207
208
  } else {
209
    ADC_START_NEW_MESSURED();      // Starte weitere ADC-Konversion
210
  }
211
}
212
213
// --------------------------------------------------------
214
// adc_messung( uint16_t *adc_avg,
215
//               uint8_t  adc_id,
216
//               uint8_t  adc_avg_cnt );
217
// --------------------------------------------------------
218
219
void adc_messung(
220
  uint16_t *adc_avg,     // Ergebnisse adc_avg
221
  uint8_t  adc_id,    // die ADC-Kanal adc_id
222
  uint8_t  adc_avg_cnt       // Anzahl der Messertte für den Mittelwert 
223
)
224
{
225
  adc_start_isr_measurement( adc_id, adc_avg_cnt );
226
227
  while( !adc_avg_ready ) { }
228
229
  adc_stop_isr_measurement();
230
231
  // Ergebnisse kopieren
232
  (*adc_avg) = adc_avg_channel;
233
}

von My T. (mytrasher)


Lesenswert?

Ich bin ehrlich gesagt kein Profi, daher nicht so die Ahnung was ich mit 
deiner Bibliothek anfangen kann und wo und wie ich sie implementieren 
soll!
:D wirklich sorry!

Wäre aber auch wirklich gut zu wissen, was den an meinem Programm falsch 
ist und wo ich den Fehler gemacht habe um diese Fehlermeldungen 
hervorzurufen!

>Error  2  'ADMUX' undeclared
>Error  4  'REFS1' undeclared

Trotzdem danke ich dir vielmals und hoffe das ich es dank euch es noch 
irgendwie bis Montag hinkriege ^^

von Kai S. (kai1986)


Lesenswert?

Hallo,

dein Fehler liegt in der Bedienung von AVR Studio. Du hast nämlich mit 
Sicherheit keinen µC ausgewählt. Wenn ich deinen Code nehme und bauen 
lasse bekomme ich keine Fehlermeldung.

Gruß Kai

von My T. (mytrasher)


Lesenswert?

Kai S. schrieb:
> Hallo,
>
> dein Fehler liegt in der Bedienung von AVR Studio. Du hast nämlich mit
> Sicherheit keinen µC ausgewählt. Wenn ich deinen Code nehme und bauen
> lasse bekomme ich keine Fehlermeldung.
>
> Gruß Kai

Naja eigentlich schon... wenn ich anderes Programm laufen lasse, wie 
z.b. LEDs aufblinken alle  funktioniert alles...
Aber kannst du mir sagen wo ich es vergessen habe? Danke!!

ps: kann es daran liegen das ich den atmega8515l benutze eigentlich 
nicht oder?

Ich bin verzweifelt :(

von Kai S. (kai1986)


Lesenswert?

Wenn du in deinem Projekt bist, dann hast du unter dem Menüpunkt 
"Project" den Unterpunkt "PROJEKTNAME Properties...ALT+F7". Da gibt es 
dann eine Karteikarte "Device" in der du den µC einstellen kannst.

Es besteht auch noch die Möglichkeit, das du einfach einen falschen µC 
ausgewählt hast, der keinen ADC hat. Mit der Auswahl des Controllers 
gibts du nämlich an, welche Definitionsdatei AVR Studio für das Projekt 
beim Compillieren mitladen soll. Darin sind die ganzen Konstanten 
definiert, die in dem Controller zur Verfügung stehen. Hat der µC eine 
Funktion nicht, ist natürlich auch die Konstante nicht definiert.

Gruß Kai

PS: µC z.B. ATMega 640

von My T. (mytrasher)


Lesenswert?

Ich habe da eingestellt ATmega8515  ... mein MC ist aber 8515L... alle 
anderen Programme funktionieren  aber nicht dieses :/
Hab ich mich falsch informiert ? Hat dieser MC kein ADC?

von Kai S. (kai1986)


Lesenswert?

Ne, der hat keinen.
Ich empfehle dir dringenst dir das Datenblatt zu besorgen (kannst du von 
der Atmel Seite runter laden) und dich daran zu orientieren, sonst wirst 
du ständig irgendwelche Probleme haben und verzweifeln.

Gruß Kai

von Spess53 (Gast)


Lesenswert?

Hi

>Ich habe da eingestellt ATmega8515  ... mein MC ist aber 8515L...

Kein Wunder. Der ATMega8515 hat keinen ADC.

MfG Spess

von My T. (mytrasher)


Lesenswert?

Oh man was furn scheiss ^^ ... Danke euch vielmals!
Letzte Frage! Könnt ihr mir bitte einen guten MC fur meinen STK 500 
empfehlen mir einem ADC?

Danke im Vorraus!!

von Spess53 (Gast)


Lesenswert?

Hi

>Könnt ihr mir bitte einen guten MC fur meinen STK 500
>empfehlen mir einem ADC?

ATmega1284P

MfG Spess

von Kai S. (kai1986)


Lesenswert?

hab ich doch schon ^^

Kai S. schrieb:
> PS: µC z.B. ATMega 640

Auch wenn du µCs suchst ist die Atmel Seite gut, da du aufgelistet 
bekommst, was es alles gibt.

Gruß Kai

von Spess53 (Gast)


Lesenswert?

Hi

>hab ich doch schon ^^

>Kai S. schrieb:
>> PS: µC z.B. ATMega 640

Der ATMega640 lässt sich auf dem STK500 nur mit einem zusätzlichem 
STK501 einsetzen.

MfG Spess

von My T. (mytrasher)


Lesenswert?

^^ danke euch viel mals!  hoffe nur reichelt hat ubernacht express will 
die dinger morgen haben :D

von My T. (mytrasher)


Lesenswert?

Spess53 schrieb:
> Hi
>
>>Könnt ihr mir bitte einen guten MC fur meinen STK 500
>>empfehlen mir einem ADC?
>
> ATmega1284P
>
> MfG Spess

Hallo spess
http://www.reichelt.de/Atmel-ATMega-AVRs/ATMEGA-1284P-PU/3/index.html?;ACTION=3;LA=446;ARTICLE=112738;GROUPID=2959;artnr=ATMEGA+1284P-PU;SID=12UKfRJn8AAAIAAGs7EOI751cf695f8a9a1a089fe43dfc04b8735

ist das der richtige mc ?

Weil finde im Datasheet auch nichs von adc oder habs ubersehen :( bitte 
um bestätigung danke euch vielmals!

von Spess53 (Gast)


Angehängte Dateien:

Lesenswert?

Hi

>Weil finde im Datasheet auch nichs von adc oder habs ubersehen :( bitte
>um bestätigung danke euch vielmals!

Das von Reichelt ist nur die Kurzfassung des Datenblatts. Die Webseite 
vom ATMEL scheint im Moment nicht erreichbar zu sein. Deshalb mache ich 
das mal im Anhang.

MfG Spess

von My T. (mytrasher)


Lesenswert?

Spess53 schrieb:
> Hi
>
>>Weil finde im Datasheet auch nichs von adc oder habs ubersehen :( bitte
>>um bestätigung danke euch vielmals!
>
> Das von Reichelt ist nur die Kurzfassung des Datenblatts. Die Webseite
> vom ATMEL scheint im Moment nicht erreichbar zu sein. Deshalb mache ich
> das mal im Anhang.
>
> MfG Spess


Aber der Verlinkte von mir!!
http://www.reichelt.de/Atmel-ATMega-AVRs/ATMEGA-1284P-PU/3/index.html?;ACTION=3;LA=446;ARTICLE=112738;GROUPID=2959;artnr=ATMEGA+1284P-PU;SID=12UKfRJn8AAAIAAGs7EOI751cf695f8a9a1a089fe43dfc04b8735

der ist doch den du gemeint hast oder? und adc fähig ? :D
Weil wenn nicht muss ich es wissen, hab den nämlich vorhin bestellt ^^

von Spess53 (Gast)


Lesenswert?

Hi

>Ader ist doch den du gemeint hast oder? und adc fähig ? :D

Ja. Das steht sogar auf der ersten Seite des kastrierten Datenblatts von 
Reichelt unter Peripheral Features:

8-channel, 10-bit ADC

MfG Spess

von My T. (mytrasher)


Lesenswert?

ok super danke dir :D hoffe das ding kommt schnell an ^^

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.