www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega8 ADC USART


Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: anonymous (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
volatile uint16_t array[256];
volatile uint8_t messen=0;

main{
   starte_timer();
   while(1){  
      messen=256;
      while (messen>0) warten;
      werte_absenden();
   }
}

ISR(meintimer){
   if messen > 0{
      messen--;
      array[messen]=lese_vom_adc();
   }
}

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.

Autor: Thomas (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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?

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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;)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.
ISR(TIMER1_COMPA_vect)
{
   if (messen<256)
   {
      messen++;
      werte[messen]=adc();
   }
}

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
void senden(unsigned char *zeiger)
{
  while(*zeiger !=0)
  {
    loop_until_bit_is_set(UCSRA,UDRE); /* warten bis Senden moeglich */
    UDR = *zeiger;
    zeiger++;  
  }
}
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.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Thomas (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
so der Code zur einzelnen Messung!

Autor: ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: ich (Gast)
Datum:

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

Autor: Thomas (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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!

Autor: ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und läuft oder nicht?

Autor: Thomas (Gast)
Datum:

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

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Schwankt von 235 - 440:

-240 meinte ich

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Mal einen 100n-C vom ADC-Eingang nach Masse testen.

Der C macht keinen Unterschied!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: ich (Gast)
Datum:

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

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Thomas (Gast)

>Wie übertrage ich ein Array über Uart?

Einen Wert nach dem Anderen?

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, habt ihr ne Ahnung wie ich die Werte nun ins Matlab bekomme?

Autor: holger (Gast)
Datum:

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

Bedienungsanleitung von Matlab lesen?

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Bedienungsanleitung von Matlab lesen?

Hat mir leider nicht geholfen....

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Bedienungsanleitung von Matlab lesen?

>Hat mir leider nicht geholfen....

Dann lies sie noch mal.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht 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...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.