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
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.
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?
>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;)
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
voidsenden(unsignedchar*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.
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
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!
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.
> 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!
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.
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?
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.
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.
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...