Atmega8 ADC USART

Gast #1687031
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
Gast #1687044
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.
Gast #1691750
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;)
#1691751
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.
Gast #1692192
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!
Gast #1692460
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.
Gast #1692591
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!
Angehängte Dateien:
#1692712
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.
Gast #1693340
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.
#1693529
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.

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