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 | 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.
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)
> 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!
So wie vorher, nicht der selbe Wert! Schwankt von 235 - 440: 239 239 240 235 239 239 235
Hi >So wie vorher, nicht der selbe Wert! >Schwankt von 235 - 440: Mal einen 100n-C vom ADC-Eingang nach Masse testen. MfG Spess
> Mal einen 100n-C vom ADC-Eingang nach Masse testen.
Der C macht keinen Unterschied!
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.
Rechne doch deine Werte in Spannungen um und gib sie aus, dann kannst du sehen wie groß die Abweichungen sind.
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!
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?
@ Thomas (Gast)
>Wie übertrage ich ein Array über Uart?
Einen Wert nach dem Anderen?
>So, habt ihr ne Ahnung wie ich die Werte nun ins Matlab bekomme?
Bedienungsanleitung von Matlab lesen?
>> Bedienungsanleitung von Matlab lesen? >Hat mir leider nicht geholfen.... Dann lies sie noch mal.
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...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.