Forum: Mikrocontroller und Digitale Elektronik Problem mit ADC


von ghostbuster1989 (Gast)


Lesenswert?

Ich habe folgendes Problem:

Ich möchte gerne mit dem ADC eine Messung durchführen - dazu habe ich 
einen Generator angeschlossen, der analoge Werte ausgibt -

Verbundem mit PA0 (STK-500) und mit GND. PA0 kann (so weit ich das 
verstanden habe - AD0 werden, wenn man das Bit setzt.

Ich möchte also gerne eine Frequenz reingeben und diese dann messen.
Zum Messen möchte ich meine 8 LED's nutzen, da ich keine LCD Anzeige 
habe- d.h. die LED's sollen leuchten, je nach dem was für Messwerte ich 
hineingebe - ist das möglich? Also gebe einen Messwertr (50 kHz) hinein 
und dann leuchten beispielsweise LED 1 und 2 - jede LED soll also einen 
Wert ausgeben.




Mein QQ sieht wiefolgt aus:
1
#include <avr/io.h>
2
3
#define F_CPU 3600000UL   // 3.6 MHz
4
5
6
int main(void)
7
{
8
9
  
10
  DDRB = 255;                       // LED 0-7 sind auf Ausgang gestellt            
11
12
  ADMUX = (1<<REFS0);            // Gibt Referenzspannung (5V)
13
  ADCSRA = (1<<ADPS1) | (1<<ADPS0);     // Frequenzvorteiler
14
    ADCSRA |= (1<<ADEN);                  // ADC aktivieren
15
16
  adc >>= 2;                // AD-Wandler hat jetzt nur noch 8 Bits 
17
  
18
uint16_t ADC_Read( uint8_t channel )
19
{
20
  // Kanal waehlen, ohne andere Bits zu beeinflußen
21
  ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
22
  ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
23
  while (ADCSRA & (1<<ADSC) ) {   // auf Abschluss der Konvertierung warten
24
  }
25
  return ADCW;                    // ADC auslesen und zurückgeben
26
}              
27
28
29
}


----------------

Nun habe ich 9x Error - undeclared function - wie delcare ich die ganzen 
Funktionen (ADMUX,ADCSRA etc.)

Herzliche Grüße
Torben

von Karl H. (kbuchegg)


Lesenswert?

ghostbuster1989 schrieb:

> Ich möchte also gerne eine Frequenz reingeben und diese dann messen.

Wenn ich dir einen Vorschlag machen darf.
Stell diese Aufgabenstellung erst mal zurück.

Da du noch nie mit dem ADC gearbeitet hast, fang erst mal damit an, dich 
damit vertraut zu machen. Dazu ist aber eine Frequenz kontraproduktiv.

Schalte an deinen PA0 diese Schaltung drann
1
    +5V  +-------+
2
                 |
3
                 |
4
                +-+ Poti, 10k
5
                | |
6
               <---------------------+ PA0
7
                | |
8
                +-+
9
                 |
10
    GND +--------+------------------- GND

und sieh zu, dass du vom ADC die Spannungswerte korrekt bekommst. 
Vorteil, da ändert sich erst mal nichts. DIe SPannung, die du mit dem 
Poti als Spannungsteiler einstellst, die bleibt auch stundenlang 
konstant, solange du nicht am Poti drehst und du hast alle Zeit der Welt 
dein Programm mit reproduzierbaren Eingangswerten zu schreiben bzw. in 
Betrieb zu nehmen.

WEnn du das soweit hast, dann kannst du dich um deine Wechselspannung 
kümmern und darum, wie du aus den sich laufend verändernden Werten die 
Frequenz rausrechnest. Das gute daran: Da du deinen ADC schon in Betrieb 
hast und auch ein wenig Erfahrung damit gesammelt hast, weisst du, dass 
deine ADC Werte korrekt sind. Wenn also dein Freuquenergebnis nicht 
stimmt (und das wird es sehr wahrscheinlich auf Anhieb nicht tun), dann 
weisst du zumindest schon mal, dass es nicht am ADC liegt.

> Zum Messen möchte ich meine 8 LED's nutzen, da ich keine LCD Anzeige
> habe

Das ist keine so gute Idee.
Ich meine, man kann das natürlich schon machen. Aber gerade als Anfänger 
ist es eine enorm grosse Hilfe, wenn du irgendwo eine Ausgabe hast, in 
der du dir auch ein paar Angaben ausgeben lassen kannst. Man kann 
natürlich sich mit LED behelfen, aber ein LCD auf dem steht:
1
 akt: 426    vorher: 429
2
 errechn: 32Hz
3
 ISR wurde betreten
ist dann doch etwas ganz anderes, als einfach nur 8 LED, von denen man 
selbst bei Zahlenwerten erst mal im Kopf Binär auf Dezimal umrechnen 
muss.

Von daher: Ehe du mit dem ADC loslegst, wäre ein LCD nicht verkehrt. 
Deine Debugmöglichkeiten vervielfachen sich damit auf einen Schlag. Das 
solltest du als ein mögliches nächstes Projekt mal ins Auge fassen.


> Nun habe ich 9x Error - undeclared function - wie delcare ich die ganzen
> Funktionen (ADMUX,ADCSRA etc.)

Die brauchst du nicht deklarieren.
Diese Register hast du automatisch, wenn du <avr/io.h> inkludiert hast

von Karl H. (kbuchegg)


Lesenswert?

ghostbuster1989 schrieb:

>   ADMUX = (1<<REFS0);            // Gibt Referenzspannung (5V)
>   ADCSRA = (1<<ADPS1) | (1<<ADPS0);     // Frequenzvorteiler
>     ADCSRA |= (1<<ADEN);                  // ADC aktivieren
>
>   adc >>= 2;                // AD-Wandler hat jetzt nur noch 8 Bits
>
> uint16_t ADC_Read( uint8_t channel )
> {
>   // Kanal waehlen, ohne andere Bits zu beeinflußen
>   ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
>   ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
>   while (ADCSRA & (1<<ADSC) ) {   // auf Abschluss der Konvertierung
> warten
>   }
>   return ADCW;                    // ADC auslesen und zurückgeben
> }


Sieh dir mal an, wie du Funktionen ineinander geschachtelt hast.

Der Gcc erlaubt das als Erweiterung. Standard C allerdings nicht.

So ist das erlaubt
1
void foo()
2
{
3
  ...
4
}
5
6
void bar()
7
{
8
  ....
9
}

so hingegebn nicht:
1
void bar()
2
{
3
  ...
4
5
  void bar()
6
  {
7
    ...
8
  }
9
10
  ....
11
}

C kennt offiziell keine geschachtelten Funktionsdefinitionen.

von Karl H. (kbuchegg)


Lesenswert?

Und zu guter letzt:
warum benutzt du nicht die ADC Funktionen aus dem AVR-gcc-Tutorial?

AVR-GCC-Tutorial/Analoge Ein- und Ausgabe: Der interne ADC im AVR

von Pandur S. (jetztnicht)


Lesenswert?

Ich empfehl das UART zum debuggen und zur User Interaktion

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:
> Und zu guter letzt:
> warum benutzt du nicht die ADC Funktionen aus dem AVR-gcc-Tutorial?
>
> AVR-GCC-Tutorial/Analoge Ein- und Ausgabe: Der interne ADC im AVR


Ah ich seh grad. Deine ADC_read stammt ganz offensichtlich aus dem 
Tutorial.

Aber dann bitte nicht so einbinden, sondern so
1
void ADC_Init(void) {
2
 
3
  ....
4
}
5
 
6
/* ADC Einzelmessung */
7
uint16_t ADC_Read( uint8_t channel )
8
{
9
  .....
10
}
11
12
/* Beispielaufrufe: */
13
 
14
int main( void )
15
{
16
  uint16_t adcval;
17
  ADC_Init();
18
 
19
  while( 1 ) {
20
    adcval = ADC_Read(0);  // Kanal 0
21
    // mach was mit adcval
22
  }
23
}


Im Tutorial ist nicht ohne Grund auch eine beispielhafte Verwendung der 
Funktionen in Form eines rudimentären main() gezeigt: Damit auch die 
Leute, deren C-Kentnisse eigentlich unter aller Sau sind, mit den 
Funktionen noch was anfangen können. Was das Tutorial allerdings nicht 
kann: den Code lesen und verstehen warum er genau so aufgebaut ist, muss 
man immer noch selber. Das kann dir auch ein Tutorial nicht abnehmen. 
Einen gewissen Mindestlevel an C-Kentnissen muss auch das Tutorial 
voraussetzen. Man kann nicht bei Adam und Eva anfangen.

von rmu (Gast)


Lesenswert?

Das ist kein gültiger C-Code, sieht nach Copy/Paste-Fehler aus...

von Karl H. (kbuchegg)


Lesenswert?

Moment:
Da ich deinen Namen gerade in einem anderen Thread gefunden habe.

Von dort weiss ich, dass du einen Mega 8515 benutzt.
Der hat aber gar keinen ADC!

Wichtig:
Neben dem Tutorial ist immer auch das Datenblatt zum Prozessor wichtig!
Das Datenblatt ist deine Bibel. Wann immer es etwas zu klären gilt, dann 
hat dieses das allerletzte Wort. Das Tutorial ist mehr so eine Art 
'Interpretation bzw. Erläuterung des Datenblatts', wobei das Tutorial 
natürlich für einen bestimmten Prozessor geschrieben ist. Ob dein 
konkreter Prozessor das auch kann, bzw. ob es da Unterschiede gibt, das 
erfährst du - wie könnte es anders sein - aus deiner Bibel, dem 
Datenblatt.


Damit ist auch klar, warum du 'undefined variables' hast. Dein µC hat 
diese Register schlicht und ergreifend nicht, weil er keinen ADC hat.

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.