Forum: Mikrocontroller und Digitale Elektronik Atmega8 ADC USART


von Thomas (Gast)


Lesenswert?

Hallo! Brauch eure Hilfe, da ich ein Einsteiger in Sachen Atmega8/C
Programmierung bin.

Ich hab ein Signal(500Hz) und möchte jenes mit dem ADC abtasten.
Möchte so über 10 Perioden ca. 256 Werte erzeugen, diese in einen Buffer
schreiben und den Inhalt dieses per Rs232 an den pc übertragen!
Mein Hauptproblem besteht in der Erzeugung der 256 Werte.

Habt ihr Ideen bzw. Code-Schnipsel für mich wie ich das am besten
realisiere?

LG

von anonymous (Gast)


Lesenswert?

Du meinst, du weißt nicht wie du den ADC dazu bringst 256 Werte in einem 
exakten Abstand einzulesen?

Nimm einen Timer, und erzeuge damit Interrupts in der Abtastfrequenz.
In der ISR des Timers betätigst du den ADC, genau 256 mal.
und schon hast du deine 256 Werte.

Im pseudocode:
1
volatile uint16_t array[256];
2
volatile uint8_t messen=0;
3
4
main{
5
   starte_timer();
6
   while(1){  
7
      messen=256;
8
      while (messen>0) warten;
9
      werte_absenden();
10
   }
11
}
12
13
ISR(meintimer){
14
   if messen > 0{
15
      messen--;
16
      array[messen]=lese_vom_adc();
17
   }
18
}

die delux version wäre vom timer direkt den ADC auslösen zu lassen, und 
die Interruptroutine des ADC für das abspeichern ins array zu verwenden.

von Thomas (Gast)


Angehängte Dateien:

Lesenswert?

So, das is mal vorläufig mein Code!

Bis zu welchem Wert muss der Timer nun zählen damit ich auf eine 
Abtastfrequenz von ca. 20kHz komme?
und wie übertrag ich das Array mit den Werten richtig?

Passt der Code sonst?

von holger (Gast)


Lesenswert?

>und wie übertrag ich das Array mit den Werten richtig?

Kleiner Tip: Rechne mal aus wie lange du für 256 16Bit Werte
bei 9600 Baud brauchst. Deine Messwerte sind schon Geschichte bevor
sie gesendet wurden, wenn du die Messung nicht anhälst während du
sendest.

>   if (messen<256)

8 Bit Variablen sind immer kleiner als 256;)

von Karl H. (kbuchegg)


Lesenswert?

Thomas schrieb:
> So, das is mal vorläufig mein Code!
>
> Bis zu welchem Wert muss der Timer nun zählen damit ich auf eine
> Abtastfrequenz von ca. 20kHz komme?

Da musst du ein bischen rechnen.
Wie schnell läuft denn der Timer?
Wie weit zählt er?
Wieviele Overflows hast du daher in 1 Sekunde

> und wie übertrag ich das Array mit den Werten richtig?

kommt drauf an.
Willst du binär oder in textform übertragen.

> Passt der Code sonst?

Nicht wirklich

Schau dir im Tutorial an, was es alles beim ADC einzustellen gilt.
1
ISR(TIMER1_COMPA_vect)
2
{
3
   if (messen<256)
4
   {
5
      messen++;
6
      werte[messen]=adc();
7
   }
8
}

du überläufst dein Array. Wenn messen 255 ist, dann machst du noch eine 
Messung und speicherst die im Array beim Index 256. Der existiert aber 
nicht.
Ein Array
int wert[5];
besteht aus 5 Elementen
  array[0], array[1], array[2], array[3], array[4]
zähl nach, sind genau 5 Stück.

Bei der Array-Definition gibt man an, wieviele Elemente man möchte. Der 
höchste erlaubte Index ist dann um 1 kleiner, da ja bei 0 angefangen 
wird zu zählen.

Das hier
1
void senden(unsigned char *zeiger)
2
{
3
  while(*zeiger !=0)
4
  {
5
    loop_until_bit_is_set(UCSRA,UDRE); /* warten bis Senden moeglich */
6
    UDR = *zeiger;
7
    zeiger++;  
8
  }
9
}
ist eine Funktion um einen String zu versenden. Du hast aber keine 
Strings.


Alles in allem:
Du schreibst zuviel ungetesteten Code auf einmal. Das wird so nichts.
Fang erst mal klein an.

Hol dir aus dem Tutorial die ADC Funktion und vergiss fürs erste die 
ganze Sache mit dem Timer.
Mach 1 Messung mit dem ADC und sieh zu, dass du das Ergebnis dieser 
Messung auf den PC kriegst.
Und dann, wenn das klappt, baust du das Programm aus.

Ein paar Vorübungen über den Umgang mit der USART können auch nicht 
schaden, wenn ich mir den Code so ansehe.

von spess53 (Gast)


Lesenswert?

Hi

Wie willst du auf eine Abtastfrequenz von 20kHz kommen? Mit deinen 
Einstellungen kommst du auf max. 14,4kS/s. Außerdem vermisse ich die 
Konfiguration von ADMUX

MfG Spess

von Thomas (Gast)


Lesenswert?

Erstmal Danke für eure Antworten!

> Kleiner Tip: Rechne mal aus wie lange du für 256 16Bit Werte
> bei 9600 Baud brauchst.
Über die richtige Baudrate hab ich mir noch keine Gedanken gemacht!

Hab jetzt mal versucht nur einen Messung zu machen und diese auf den PC 
zu schicken. An PC0 hängt ein Poti mit dem ich die Spannung einstelle.

mit Hterm empfange ich allerdings bei der selben Spannung nicht immer 
den selben Wert.
131 124 131 124 124 131 124
039 031 039 031 039 030 039 031 039 039 032
207 216 207 207 207 207 216 207
082 078 082 081 077 082 082

Man erkennt allerdings klar, wann am Poti gedreht wurde!

von Thomas (Gast)


Angehängte Dateien:

Lesenswert?

so der Code zur einzelnen Messung!

von ich (Gast)


Lesenswert?

Also im Datenblatt steht, dass der ADC eine Takt von 50 kHz bis 200 kHz 
braucht. Wenn ich richtig verstehe arbeitest du mit 12 MHz und nimmst 
ein Vorteiler von 8 für den ADC --> dann bekommst du eine Frequenz von 
1,5 MHz.

von ich (Gast)


Lesenswert?

Und ein "return" in der Funktion "volatile uint16_t adc(uint8_t mux)" 
würde auch nicht schaden (glaube ich)

von Thomas (Gast)


Angehängte Dateien:

Lesenswert?

> Und ein "return" in der Funktion "volatile uint16_t adc(uint8_t mux)"
> würde auch nicht schaden (glaube ich)

Ist beim Löschen des auskommentierten Testcodes verschwunden! :P

> Also im Datenblatt steht, dass der ADC eine Takt von 50 kHz bis 200 kHz
> braucht.

Prescaler jetzt auf 64 eingestellt!

von ich (Gast)


Lesenswert?

Und läuft oder nicht?

von Thomas (Gast)


Lesenswert?

So wie vorher, nicht der selbe Wert!
Schwankt von 235 - 440:
239 239 240 235 239 239 235

von spess53 (Gast)


Lesenswert?

Hi

>So wie vorher, nicht der selbe Wert!
>Schwankt von 235 - 440:

Mal einen 100n-C vom ADC-Eingang nach Masse testen.

MfG Spess

von Thomas (Gast)


Lesenswert?

> Schwankt von 235 - 440:

-240 meinte ich

von Thomas (Gast)


Lesenswert?

> Mal einen 100n-C vom ADC-Eingang nach Masse testen.

Der C macht keinen Unterschied!

von Karl H. (kbuchegg)


Lesenswert?

Wie sieht der Rest der Schaltung aus?
Insbesondere
  AVcc
  bzw. generell die Spannungsversorgung


ADC Differenzen von 5 sind immerhin lediglich 2 Hundertsel Volt. Das ist 
nicht viel, wenn sie auf der Versorungungsspannung durch irgendwelche 
schaltende IC verursacht werden. Am ADC siehst du das aber.

von ich (Gast)


Lesenswert?

Rechne doch deine Werte in Spannungen um und gib sie aus, dann kannst du 
sehen wie groß die Abweichungen sind.

von Thomas (Gast)


Lesenswert?

Fehler behoben! Der zweite µC der mir die Spannung für das Poti 
geliefert hat, hatte ne schwankende Vcc! bekomme jetzt ned konstanten 
werd in HTerm!

von Thomas (Gast)


Lesenswert?

Das sollte also soweit passen oder?

Möchte jetzt ca. 10 Messungen nacheinander in ein Array schreiben, und 
dieses Array dann übertragen!

Wie übertrage ich ein Array über Uart?

von Falk B. (falk)


Lesenswert?

@  Thomas (Gast)

>Wie übertrage ich ein Array über Uart?

Einen Wert nach dem Anderen?

von Thomas (Gast)


Lesenswert?

So, habt ihr ne Ahnung wie ich die Werte nun ins Matlab bekomme?

von holger (Gast)


Lesenswert?

>So, habt ihr ne Ahnung wie ich die Werte nun ins Matlab bekomme?

Bedienungsanleitung von Matlab lesen?

von Thomas (Gast)


Lesenswert?

> Bedienungsanleitung von Matlab lesen?

Hat mir leider nicht geholfen....

von holger (Gast)


Lesenswert?

>> Bedienungsanleitung von Matlab lesen?

>Hat mir leider nicht geholfen....

Dann lies sie noch mal.

von Thomas (Gast)


Lesenswert?

So das hab ich herausgefunden, ist das das was ich brauche?

s = serial('COM32',...
           'BaudRate', 19200,...
           'Parity', 'none',...
           'DataBits', 8,...
           'StopBits', 1,...
           'InputBufferSize', 1024,...
           'OutputBufferSize', 1024,...
           'Timeout', 2);
fopen(s);
a=fread(s,1024,'uchar');

das kommt dabei raus: :/

Warning: The specified amount of data was not returned within the 
Timeout period.

von Karl H. (kbuchegg)


Lesenswert?

Thomas schrieb:

> Warning: The specified amount of data was not returned within the
> Timeout period.

Na ja.

Was heißt denn "Timeout"?
Offenbar eine Zeit die abgelaufen ist, ohne das etwas passiert.

Was ist nicht passiert?
Offenbar wurden in der vorgegebenen Zeit keine 1024 Bytes empfangen.

Warum nicht?
Höchst wahrscheinlich deshalb, weil du keine 1024 Bytes weggeschickt 
hast in der vorgegebenen Zeit oder weil die Übertragung von 1024 Bytes 
länger als das von dir vorgegebene Timout Zeit gedauert hat.


Daher die Frage:
Was davon kannst du ausschliessen bzw. was davon hast du überprüft. Es 
folgt logisch eines vom anderen.

von Justus S. (jussa)


Lesenswert?

Thomas schrieb:
> Warning: The specified amount of data was not returned within the
> Timeout period.

dann solltest du nur so viele Zeichen auslesen lassen, wie du auch 
tatsächlich verschickst...oder gleich mit Terminator arbeiten...

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.