mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega128 programmieren


Autor: Ana Kamenova (ada)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

  ich habe Schwierigkeiten einen Atmega128 zu programmieren. Ich bin 
ganz neu in dem Gebiet und bin im Moment total durcheinander. Ich muss 
zwei Mikrofonsignale (die zwei Ohren des Menschen repräsentieren) mit 
dem ADC aufnehmen und eine Kreuzkorrelation der beiden durchführen. Ich 
habe das ganze mit Matlab simuliert und es funktioniert. Ich muss das 
folgende Programm auf dem Microcontroller schreiben:

int main (void) {            // (2)
 float adcval_1[300];   //Signal von dem ersten Mikrofon
  float adcval_2[300];  // Signal von dem zweiten Mikrofon

 for ( i=251; i<301;i++){ //zero padding der zwei Signale
 adcval_1[i]=0;
 adcval_2[i]=0;
 }
 float sum=0;
 float sum_0 =0;
 float sum_1=0;
 int counter =0;


 for (int i=0; i<36;i++){      // Kreuzkorrelation der Signale

   for(int n=0; n<250;n++){

    sum_1= adcval_1[n+1]*adcval_2[n+18];
    sum=sum+sum_1;
    }
    sum_1=0;

    if(sum_0<sum){    // nach Maximum suchen
    sum_0=sum;
    counter=i;
    }
    sum=0;
    }
    counter=counter-18;   / Wegdifferenz der beiden Signale
    float delay=counter/31250;
    float dist=343*delay;
    float sinalpha= dist/0.2;
    float alpha = asin(sinalpha); // Richtung(Winkel) des Tons

  Wobei der ADC muss so eingestellt werden,dass er abwechselnd Werte der 
zwei Mikrofone aufnimmt und in den Arrays adcval_1 und adcval_2 
speichert.
Es kann sein dass,das ganze sehr einfach ist,aber ich habe ganz wenig 
Ahnung und weiss nicht wie ich anfangen soll.

: Verschoben durch Admin
Autor: ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weiß nicht, ob ich es richtig verstanden habe.
Aber du kannst doch das eine Mikrofon an einen ADC-Kanal anschließen, 
das andere Mikrofon an dem anderen Kanal. Nachdem du den ersten Wert von 
einem Kanal hast, schaltest du den auf den anderen Kanal und holst den 
Wert ab und dann wieder auf den ersten Kanal und so weiter bis du alle 
deine Werte hast.
Aber wenn du noch keine Ahnung hast wie das geht, versuch erst die Werte 
von einem Kanal zu holen und seh sie dir an, ob die einigermaßen 
stimmen, dann kannst du mit der Kanalumschlatung weitermachen.
Es ist nicht so schwer, lies dir im Datenblatt den Paragraf zu ADC 
durch.

Autor: Düsendieb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Ana,
das was Du da eingefügt hast kann doch nicht das ganze Programm sein. 
Häng mal alles an, was Du schon geschrieben hast. (Ich hoffe doch Du 
hast das selbst geschrieben)


Axel

Autor: Ana Kamenova (ada)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

danke für die schnelle Antwort. Das Programm abe ich selbst 
geschrieben,deswegen bin ich nicht sicer ob es stimmt. Ic habe Problemme 
mit dem ADC einstellen und abwechselnd die Werte holen. Ich weiss nicht 
wie ich mir Werte ausgeben lassen kann,damit ich schauen kann ob es was 
sinvolles rauskommt. Noch dazu ich weiss nicht was ich mit "float"Werte 
und negative Werte genau machen muss. Und noch dazu,soweit ich 
verstanden habe der Atmega128 arbeitet mit 4MHz,ich möchte die Frequenz 
des ADCs möglichst runterstellen. Geht es nur mit den prescaler 
Bits,oder gibt es eine andere Möglichkeit auch?
Hier ist mein komplettes Programm:

#include <avr/io.h>          // (1)
#include <stdint.h>
#include <math.h>

int main (void) {            // (2)
 float adcval_1[300];
  float adcval_2[300];
  uint8_t ind_1=0;
  uint8_t ind_2=0;

  for (uint8_t i=2; i<503;i++){

 if(i%2==0){
  ADMUX = (1<<REFS1) | (1<<REFS0) | (1<<ADLAR);
  ADCSRA =(1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);



  ADCSRA |= (1<<ADSC);
  while (ADCSRA & (1<<ADSC) ){
    ;
     }

  adcval_2[ind_2] = ADCH*0.0025- 1.28;   // Kanal 0, im adcval_2 
speichern
  ind_2++;
 }
  else{

   ADMUX =(1<<MUX2) | (1<<REFS1) | (1<<REFS0) | (1<<ADLAR);
  ADCSRA =(1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
  ADCSRA |= (1<<ADSC);
  while (ADCSRA & (1<<ADSC) ){           // Kanal 4, im adcval_1 
speichern
  ;
  }

  adcval_1[ind_1] =ADCH*0.0025-1.28;
  ind_1++;
  }
  }

 for (uint8_t i=251; i<301;i++){            // Zero padding
 adcval_1[i]=0;
 adcval_2[i]=0;
 }
 float sum=0;
 float sum_0 =0;
 float sum_1=0;
 int8_t counter =0;


 for (uint8_t i=0; i<36;i++){                   // Kreuzkorrelation

   for(uint8_t n=0; n<250;n++){

    sum_1= adcval_1[n+1]*adcval_2[n+18];
    sum=sum+sum_1;
    }
    sum_1=0;

    if(sum_0<sum){
    sum_0=sum;
    counter=i;
    }
    sum=0;
    }

    counter=counter-18;

    float delay=counter/31250;              // Delay zwischen die beiden 
Signale,(fs=31250)
    float dist=343*delay;                    //Wegdifferenz der beiden 
Signale
    float sinalpha= dist/0.2;                // Richtung des Tons als 
sinus der Winkel
    float alpha = asin(sinalpha);            // Winkel bestimmen


  while(1){

  }
  return 0;
  }

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

Bewertung
0 lesenswert
nicht lesenswert
Ana Kamenova schrieb:
> Hallo,
>
> danke für die schnelle Antwort. Das Programm abe ich selbst
> geschrieben,deswegen bin ich nicht sicer ob es stimmt. Ic habe Problemme
> mit dem ADC einstellen und abwechselnd die Werte holen.

Fang damit an, das
AVR-GCC-Tutorial zu studieren.
Da gibt es auch einen Abschnitt über den ADC


> Ich weiss nicht
> wie ich mir Werte ausgeben lassen kann,damit ich schauen kann ob es was
> sinvolles rauskommt.

Dann musst du dir dafür was einfallen lasse.
UART, LCD  da gibt es schon ein paar Möglichkeiten.

> Noch dazu ich weiss nicht was ich mit "float"Werte
> und negative Werte genau machen muss.

Die meisten float willst du da ganz sicher nicht haben. Fang damit an, 
zumindest die Messwerte einfach nur als ganze Zahlen zu sehen.

Negative Werte kannst du gar nicht haben. Mit dem ADC kannst du nur 
positive Spannungen messen. zur Not muss man eben das Signal in der 
Spannungslage verschieben.

> Und noch dazu,soweit ich
> verstanden habe der Atmega128 arbeitet mit 4MHz,ich möchte die Frequenz
> des ADCs möglichst runterstellen.

Der geht sowieso so schnell oder so langsam wie du ihn programmierst.

In einem Programm etwas langsamer zu machen ist kein Problem. Die 
Umkehrung ist schwieriger :-)

Autor: Ana Kamenova (ada)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:

> Die meisten float willst du da ganz sicher nicht haben. Fang damit an,
> zumindest die Messwerte einfach nur als ganze Zahlen zu sehen.
>
> Negative Werte kannst du gar nicht haben. Mit dem ADC kannst du nur
> positive Spannungen messen. zur Not muss man eben das Signal in der
> Spannungslage verschieben.

Ja das habe ich schon gemacht,ich messe nur positive Werte.Später für 
die Kreuzkorrelation benötige ich die "echten" Werte. Kann ich die 
einfach umrechnen und weiter arbeiten?

Autor: Düsendieb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
zieh einfach einen Offset von dern Werten ab, und schon sind sie wieder 
teils negativ

Autor: Düsendieb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erkläre doch mal was diese Kreuzkorrelation machen soll. Als Formel ohne 
Programm

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

Bewertung
0 lesenswert
nicht lesenswert
Düsendieb schrieb:
> Erkläre doch mal was diese Kreuzkorrelation machen soll. Als Formel ohne
> Programm

Und wenn du das hast, dann geh noch mal dein Programm durch und sieh 
nach ob du alle Elemente deiner Erklärung wiederfindest.

UNd wenn du dann dein Programm nicht einfach so hinrotzt, sondern sauber 
einrückst, dann siehst du auch wo du hier Mist gebaut hast bzw. in 
Matlab nicht richtig getestet hast.

Autor: Düsendieb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weitere Fragen:

wann fängt das Programm an zu arbeiten, was geschieht mit dem Ergebnis?

Der ADC wird bestimmt kein so schönes Sinussignal wie in der Simulation 
aufnehmen. Was geschieht mit einzelnen Peaks?

Welche Frequenz hat das zu messende Signal? Recht der Array um eine 
komplette Schwingung aufzunehmen?

Autor: Ana Kamenova (ada)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Kreuzkorrelation multipliziert die Werte der Zwei Signale x 
u.s,(wobei x ist um n verschoben) und bildet die Summe der 
Multiplikationen. Das wird für 0<n<maxn Verschiebungen durchgeführt. Das 
Ziel ist ein Max(Ks) aller Summen zu finden.

   Ks(x;n) =∑ x(t + n ) *s(t)


 Meine Frage ist,nachdem ich den Offset abziehe und meine echte 
Spannungswerte bekomme,kann ich einfach weiter multiplizieren und 
addieren?

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

Bewertung
0 lesenswert
nicht lesenswert
Ana Kamenova schrieb:
> Die Kreuzkorrelation multipliziert die Werte der Zwei Signale x
> u.s,(wobei x ist um n verschoben)

Das mit dem verschieben .... das findet sich aber in deinem Code nicht 
wieder.

> und bildet die Summe der
> Multiplikationen. Das wird für 0<n<maxn Verschiebungen durchgeführt.

Da der erste Punkt sich schon nicht wiederfindet, findet sich auch der 
Teil bei dir im Programm nicht wieder.

-> Nochmal zurück ins Matlab und mit anderen Werten probieren.

>  Meine Frage ist,nachdem ich den Offset abziehe und meine echte
> Spannungswerte bekomme,kann ich einfach weiter multiplizieren und
> addieren?

Im Prinzip: ja.
Nur musst du darauf achten, dass dir die Berechnungen nicht übergehen.
Die naive Vorstellung, dass float jede beliebige Zahl in unbegrenzter 
Genauigkeit aufnehmen kann, ist leider .... reichlich naiv.

Autor: Ana Kamenova (ada)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Düsendieb schrieb:
> Weitere Fragen:
>
> wann fängt das Programm an zu arbeiten, was geschieht mit dem Ergebnis?
>
> Der ADC wird bestimmt kein so schönes Sinussignal wie in der Simulation
> aufnehmen. Was geschieht mit einzelnen Peaks?
>
> Welche Frequenz hat das zu messende Signal? Recht der Array um eine
> komplette Schwingung aufzunehmen?

 Das Programm soll anfangen sobald ein Ton die Mikrofone trifft. Das 
ganze muss ein künstlicher Kopf sein,der sich in der Richtung der 
Schalls dreht. Die Mikrofone stecken in den Ohren. Im Matlab habe ich 
mit keinem Sinus getestet,sondern mit signale aus den selben Mikrofone. 
Im Matlab wurde der Winkel richtig bestimmt. Mein Ergebnis(Winkel) soll 
dann weiter einem Schrittmotor übergeben,der den Kopf dreht. Meine 
Aufgabe zuerst ist mit dem Microcontroller den Winkel zu bestimmen.

Meine Wunschfrequenz wäre 16KHz,wenn ich die so niedrig stellen kann. 
Die Array Größen aus meinem Programm sind nur ein Beispiel,ich werde mit 
viel mehr Werten rechnen müssen.

Autor: Düsendieb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich muss zugeben, trotz befragung von Wikipedia habe ich noch nicht so 
richtig verstanden, worum es dabei geht.

Mit den Analogeingängen füllst Du zwei Arrays mit Integerwerten zwischen 
0 und 1024.

Nehmen wir mal an, das Sinal ist sogar sinusförmig. Was soll dann 
geschehen?

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

Bewertung
0 lesenswert
nicht lesenswert
Ana Kamenova schrieb:

>  Das Programm soll anfangen sobald ein Ton die Mikrofone trifft. Das
> ganze muss ein künstlicher Kopf sein,der sich in der Richtung der
> Schalls dreht. Die Mikrofone stecken in den Ohren. Im Matlab habe ich
> mit keinem Sinus getestet,sondern mit signale aus den selben Mikrofone.
> Im Matlab wurde der Winkel richtig bestimmt.

Dann machs nochmal mit anderen Messwerten.
Du wirst sehen, dass dein Programm wieder zum selben Winkel kommt.

Im Moment machst du keine Kreuzkorrelation sondern dein Programm 
bestimmt einen Wert, den du vorher schon wusstest. Du hast dein Programm 
solange getrimmt, bis du den bereits bekannten Wert herausbekommen hast.

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

Bewertung
0 lesenswert
nicht lesenswert
Düsendieb schrieb:
> ich muss zugeben, trotz befragung von Wikipedia habe ich noch nicht so
> richtig verstanden, worum es dabei geht.

Es geht darum, in einer Messreihe eine bekannte Messreihe möglichst gut 
wiederzufinden.

Auf Deutsch: Du verschiebst dein bekanntes Signal solange über dem 
gemessenen Signal nach links oder rechts, bist du die beste 
Übereinstimmung hast.

GPS arbeitet zb so. Der GPS Empfänger weiß wie das Signal im Prinzip 
aussehen müsste und fahndet dann im empfangenen Signal danach. Ohne 
Kreuzkorrelation würde das Signal im Rauschen untergehen.

Ich finde hier ist das ganz gut und knapp beschrieben
http://tu-freiberg.de/fakult4/imfd/lehre/fluid/MT/...

Autor: Ana Kamenova (ada)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb im Beitrag:

> Im Moment machst du keine Kreuzkorrelation sondern dein Programm
> bestimmt einen Wert, den du vorher schon wusstest. Du hast dein Programm
> solange getrimmt, bis du den bereits bekannten Wert herausbekommen hast.

 Entschuldigung es gibt ein Tippfehler dabei,so habe ich es gemeint:

for (uint8_t i=0; i<36;i++){                   // Kreuzkorrelation

   for(uint8_t n=0; n<250;n++){

    sum_1= adcval_1[n+i]*adcval_2[n+18];  // i ist die Verschiebung
    sum=sum+sum_1;
    }
    sum_1=0;

    if(sum_0<sum){
    sum_0=sum;
    counter=i;
    }
    sum=0;
    }

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

Bewertung
0 lesenswert
nicht lesenswert
Ana Kamenova schrieb:

>  Entschuldigung es gibt ein Tippfehler dabei

So sieht das schon besser aus.

Jetzt wirfst du noch deinen ganzen ADC Kram raus und verwendest die 
Funktionen aus dem AVR-GCC-Tutorial.

Autor: Ana Kamenova (ada)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Düsendieb schrieb:

> Mit den Analogeingängen füllst Du zwei Arrays mit Integerwerten zwischen
> 0 und 1024.

 Ich möchte die zwei Arrays mit den Werten:

adcval_1[ind_1] =ADCH*0.0025-1.28

 füllen, 0.0025= Uref/1024, 1.28 ist Uref/2(Offset)

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

Bewertung
0 lesenswert
nicht lesenswert
Ana Kamenova schrieb:
> Düsendieb schrieb:
>
>> Mit den Analogeingängen füllst Du zwei Arrays mit Integerwerten zwischen
>> 0 und 1024.
>
>  Ich möchte die zwei Arrays mit den Werten:
>
> adcval_1[ind_1] =ADCH*0.0025-1.28
>
>  füllen, 0.0025= Uref/1024, 1.28 ist Uref/2(Offset)

Preisfrage:
Was ist der Unterschied zwischen
    2.65  Euro
und
    265  Cent

Antwort: So gesehen kar keiner. Man kann mit beiden Beträgen dasselbe 
einkaufen. Als Geldmenge sind sie gleich. Aber das eine ist eine Zahl 
mit einem Dezimalpunkt und das andere nicht.

Rechnen mit Floating Point ist auf deinem Mega128 über den Daumen 
gepeilt rund 30 bis 50 mal langsamer als rechnen mit ganzen Zahlen.

Ob deine Zahlen jetzt von -1.0 bis +1.0 oder von -512 bis +512 laufen, 
kommt sich aufs gleiche raus. Du musst nur berücksichten, dass zweiteres 
einfach nur das 512-fache des ersteren ist.

Autor: Ana Kamenova (ada)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb :

> Jetzt wirfst du noch deinen ganzen ADC Kram raus und verwendest die
> Funktionen aus dem AVR-GCC-Tutorial.

 Ja genau,das ist eigentlich mein Problem,die Einstellung des ADCs war 
mir nicht klar

Autor: Ana Kamenova (ada)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb im Beitrag:

> Rechnen mit Floating Point ist auf deinem Mega128 über den Daumen
> gepeilt rund 30 bis 50 mal langsamer als rechnen mit ganzen Zahlen.

 Würde es dann gehen,den Offset umrechnen(ganze Zahl) und weiter 
arbeiten?

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

Bewertung
0 lesenswert
nicht lesenswert
Ana Kamenova schrieb:
> Karl heinz Buchegger schrieb im Beitrag:
>
>> Rechnen mit Floating Point ist auf deinem Mega128 über den Daumen
>> gepeilt rund 30 bis 50 mal langsamer als rechnen mit ganzen Zahlen.
>
>  Würde es dann gehen,den Offset umrechnen(ganze Zahl) und weiter
> arbeiten?

LOL

Ob du zu 2.68 Euro noch 0.5 Euro Offset dazuzählst, oder ob du zu 268 
Cent noch 50 Cent dazuzählst, kommt sich aufs gleiche raus.

Autor: Ana Kamenova (ada)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:

> Ob du zu 2.68 Euro noch 0.5 Euro Offset dazuzählst, oder ob du zu 268
> Cent noch 50 Cent dazuzählst, kommt sich aufs gleiche raus.


 Ok danke :-))))))

 d.h ich muss einfach die Werte richtig messen(ADC einstellen).

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

Bewertung
0 lesenswert
nicht lesenswert
Ana Kamenova schrieb:
> Karl heinz Buchegger schrieb:
>
>> Ob du zu 2.68 Euro noch 0.5 Euro Offset dazuzählst, oder ob du zu 268
>> Cent noch 50 Cent dazuzählst, kommt sich aufs gleiche raus.
>
>
>  Ok danke :-))))))
>
>  d.h ich muss einfach die Werte richtig messen(ADC einstellen).

Genau
Also: Aus dem Tut die fertigen Routinen holen, noch die Einstellung der 
Referenzspannung anpassen und mal ausprobieren, wie gut dein Signal 
gesampelt wird.

Zunächst mal mit nur 1 Mikrofon, dann mit 2.

Nicht alles auf einmal in Betrieb nehmen. Alles Schritt für Schritt.

16Khz müssten mit dem ADC noch drinnen sein. Geh mit der Abtastfrequenz 
so hoch, wie es gerade noch zulässig ist.

(Dir ist auch klar, dass 16kHz Abtastfrequenz eine vorhergehende 
Filterung des Signals auf unter 8kHz Bandbreite bedingt?)

Autor: Ana Kamenova (ada)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:

> (Dir ist auch klar, dass 16kHz Abtastfrequenz eine vorhergehende
> Filterung des Signals auf unter 8kHz Bandbreite bedingt?)

 Es geht um Sprachsignale und ich gehe davon aus,dass die unter 8kHz 
liegen

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

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:

> 16Khz müssten mit dem ADC noch drinnen sein. Geh mit der Abtastfrequenz
> so hoch, wie es gerade noch zulässig ist.

Was ich noch sagen wollte:
Zwischen dem Aufnehmen der Sampels kann man zur Not immer noch ein wenig 
warten, wenn der ADC wirklich zu schnell sein sollte. Aber ich denke 
spätestens wenn der ADC beide Mikrofone wechselweise sampeln soll, wird 
das nicht mehr wirklich notwendig sein.

Autor: Ana Kamenova (ada)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich möchte die Abtastfrequenz niedrig halten,weil ich so wenig wie 
möglich Werte sampeln möchte. Ich mache mir Gedanken ob der 
Microcontroller genug RAM für das Ganze hat.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kleine Anmerkung:
for (uint8_t i=251; i<301;i++){            // Zero padding
 adcval_1[i]=0;
 adcval_2[i]=0;
 }

mit
 float adcval_1[300];
  float adcval_2[300];

ergibt eine Überschreitung der Arraygrenzen.  In adcval_* existiert kein 
Index mit dem Wert 300.

Autor: Axel Düsendieb (axel_jeromin) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ana Kamenova schrieb:
> Ich möchte die Abtastfrequenz niedrig halten,weil ich so wenig wie
> möglich Werte sampeln möchte.

Mach lieber die Aufnahmezeit kleiner und die Abtastrate hoch, sonst ist 
das Signal hoffnungslos eckig.

Außerdem liegt ja sonst nichts großes im Speicher



Axel

Autor: Axel Düsendieb (axel_jeromin) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Als ich schlage folgende Struktur vor:

Hauptschleife

   Schleife bis ein Analogeingang ein Signal größer irgendwas misst

   Schleife zur Aufnahme von x Werten

   Auswertung der Messreihen

   Bildung des Sollwert für den Schrittmotor

   Schleife bis der Schrittmotor sein Ziel erreicht hat

Ende Hauptschleife

Alles wird nur in Integerwerten gerechnet, da die ADC sowieso nur Werte 
von 0 bis 1024 liefert.


Axel

Autor: Ana Kamenova (ada)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich z. B

  int8_t adcval_1[500]; definieren möchte,kommt die folgende Warnung:


 large integer implicitly truncated to unsigned type

 und der Microcontroller tut nichts,ist die Arraygröße zu groß? mit eine 
Größe von z.B 100 kommt die Meldung nicht.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ana Kamenova schrieb:
> Wenn ich z. B
>
>   int8_t adcval_1[500]; definieren möchte,kommt die folgende Warnung:
>
>
>  large integer implicitly truncated to unsigned type

Für welche Zeile kommt diese Meldung?  Für die zitierte doch eher nicht, 
oder täusche ich mich?  Schau mal nach, welche Zeile das betrifft und 
zeige sie inklusive der daran beteiligten Variablentypen.

Autor: Ana Kamenova (ada)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hc Zimmerer schrieb:

> Für welche Zeile kommt diese Meldung?  Für die zitierte doch eher nicht,



 ja die Zeile war es nicht,aber ich darf aber nicht mehr als 290 für die 
Arrays nehmen,daher habe ich  zu wenig Werte und bekomme nichts 
sinvolles als Ergebnis.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gut.  Es ist nicht besonders sinnvoll, eine Fehlermeldung zu zitieren, 
ohne dass die davon betroffene Zeile dem Leser bekannt ist.

Wenn Du nicht mehr als 290 Werte in ein Array bringst und sonst falsch 
gerechnet wird (so verstehe ich Deine Aussage):  Hast Du die Arrays mit 
[300] vereinbart und nur 290 davon verwendet, oder steht in der 
Vereinbarung [290]?  Und welche Speicherauslastung wird bei Beendigung 
des Kompiliervorgangs angezeigt?  Wie viel bss, wie viel data?

Autor: Axel Düsendieb (axel_jeromin) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
als ich hab mal schnell in einem Programm für einen Mega 168 folgendes 
eingegeben:


unsigned char  adcval_1[1500];
unsigned char  adcval_2[1500];

und in der Hauptschleife:


while(1){

adcval_1[1234]=27;
adcval_2[1499]=123;
.
.
.
.

Da hat der Compiler nirgens gemeckert


Axel

Autor: Axel Düsendieb (axel_jeromin) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
auch gegen:

unsigned int  adcval_1[1500];
unsigned int  adcval_2[1500];


// ********Initialisierung********************************************

initial();  // Initialisierung Ports, Timer

lcd_init();  // LCD Initialisierung


// *******************************************************************


while(1){

adcval_1[1234]=27000;
adcval_2[1499]=1234;


hat er nichts zu sagen außer:
Build succeeded with 0 Warnings...

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und?

Autor: Axel Düsendieb (axel_jeromin) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da muss das Problem wohl wo anders liegen.


auch:

unsigned int zeiger=0;
unsigned int  adcval_1[1500];
unsigned int  adcval_2[1500];
// ********Initialisierung********************************************
initial();  // Initialisierung Ports, Timer
lcd_init();  // LCD Initialisierung
Start_Clock();
// *******************************************************************
while(1){

zeiger=1234;
adcval_1[zeiger]=27000;
adcval_2[zeiger+23]=1234;

ist OK

Autor: Ana Kamenova (ada)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Hc Zimmerer schrieb:
>> Für welche Zeile kommt diese Meldung?  Für die zitierte doch eher nicht,

 Den FEhler habe ich gefunden und korrigiert.
 Nun,wenn ich z.B 7500 eingebe kommt das folgende:

 Program:     326 bytes (0.2% Full)
 (.text + .data + .bootloader)


 Data:          0 bytes (0.0% Full)
 (.data + .bss + .noinit)

Build succeeded with 0 Warnings...


 trotzdem tut der Microcontroller nichts(ich habe den LEDs so 
programmiert,das bei sinvolles Ergebnis 2 läuchten und wenn nicht sollen 
3 läuchten.) In dem Fall ist alles dunkel.

Erst unter 290 passiert was

Autor: Axel Düsendieb (axel_jeromin) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hänge mal das gesamte Programm an

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>als ich hab mal schnell in einem Programm für einen Mega 168 folgendes
>eingegeben:

>unsigned char  adcval_1[1500];
>unsigned char  adcval_2[1500];

Klingt bei 1k Ram interessant.

MfG Spess

Autor: Axel Düsendieb (axel_jeromin) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ups.

Danke für den Hinweis.

Immerhin hat der Mega128 – 4K Bytes Internal SRAM

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du mit 7500 die Größe Deiner Arrays meinst: dass das nicht 
funktionieren kann, kannst Du Dir selbst ausrechnen.  Jede Float belegt 
schließlich 4 Bytes.  Somit bräuchtest Du 30 kBytes.  Der ATmega128 hat 
4 kBytes SRAM.  Erstaunlich ist nur die .data + .bss - Ausgabe. 
Möglicherweise zeigt die Mist, weil Du weit jenseits von Gut und Böse 
liegst.

Natürlich meinte ich die Speicherbelegung bei 290 oder 300 Arraygröße. 
Auch die Frage nach der Vereinbarung ist noch offen.



(@Axel Düsendieb:

Ich habe nach wie vor keine Ahnung, was Du beweisen willst.  Ich finde 
einfach nichts, was irgendwie bemerkenswert wäre, an Deinen 
Codeschnipseln.  Außer dass Du die Speicherbelegung ebenfalls zu den 
vernachlässigbaren Informationen zu zählen scheinst (trotz großer 
Arrays) und prompt weit daneben liegst.)

Autor: Ana Kamenova (ada)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Natürlich 7500 war nur als Beispiel,diese Größe brauche ich ncht,aber 
ich brauche schon was größeres als 290

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch was:
  float delay=counter/31250;              // Delay zwischen die beiden Signale,(fs=31250)

counter ist eine int, 31250 sowieso.  Beide Operanden also int, demnach 
wird eine Integer-Division durchgeführt.  Somit kann delay nur die Werte 
1.0, 0, und -1.0 annehmen.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Möchtest Du nicht vielleicht etwas zu den Fragen aus 
Beitrag "Re: Atmega128 programmieren" sagen?

Autor: Ana Kamenova (ada)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

 könnt ihr mir bitte sagen ob die ADC-Einstellungen stimmen und wie kann 
ich feststellen mit welcher Frequenz der Microcontroller arbeitet?

#include <avr/io.h>          // (1)
#include <stdint.h>
#include <math.h>
/* ADC initialisieren */
void ADC_Init(void) {

  uint16_t result;

  ADMUX = (1<<REFS0) | (1<<REFS1);      // interne Referenzspannung 
nutzen
  ADCSRA = (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);     // 
Frequenzvorteiler
  ADCSRA |= (1<<ADEN);                  // ADC aktivieren

   ADCSRA |= (1<<ADSC);                  // eine ADC-Wandlung
  while (ADCSRA & (1<<ADSC) );
   result = ADCW;
}


 int16_t ADC_Read( uint8_t channel )
{

  ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
  ADCSRA |= (1<<ADSC);
  while (ADCSRA & (1<<ADSC) )     // auf Abschluss der Konvertierung 
warten
    ;
  return ADCW;                   // ADC auslesen und zurückgeben
}


int main (void) {            // (2)
 int16_t adcval_1[1000];
  int16_t adcval_2[1000];


   ADC_Init();


for (uint16_t i=0; i<1000;i++){

   adcval_1[i]= ADC_Read(0)-430;   // 430 ist der Offset
   adcval_2[i]= ADC_Read(6)-430;
   }

Autor: Düsendieb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ana Kamenova schrieb:

>   ADMUX = (1<<REFS0) | (1<<REFS1);      // interne Referenzspannung nutzen = 
Internal 2.56V Voltage Reference with external capacitor at AREF pin. Daher sollte 
das Analogsignal nicht größer sein

>   ADCSRA = (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);     // Frequenzvorteiler

= ADPS2 ADPS1 ADPS0 = Division Factor 128

Kann man nichts falsch machen, aber die Wandelung ist evtl zu langsam. 
Willst schließlich schnell abtasten.


CKSEL3..0 0001 ==> Nominal Frequency (MHz) 1,0Mhz
Note: 1. The device is shipped with this option selected.

Wenn der Controller frisch aus der Presse kam, dann sollte er 1Mhz 
Taktfrequenz haben. Ansonsten die Fuses kontrollieren.

Zur Kontrolle kann man auch den Timer 1 programmieren und eine LED 
blinken lassen.

Axel

Autor: Ana Kamenova (ada)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke :-),
ich habe dafür gesorgt,dass das Signal kleiner als 2.56V bleibt. Und die 
Abtastrate möchte ich auch niedrig halten. Für mich ist wchtig, dass der 
Teil:

int main (void) {
 int16_t adcval_1[1000];
  int16_t adcval_2[1000];

  ADC_Init();

for (uint16_t i=0; i<1000;i++){

   adcval_1[i]= ADC_Read(0)-430;   // 430 ist der Offset
   adcval_2[i]= ADC_Read(6)-430;
   }

richtig ist. Es sind zwei Mikrofonsignale,die ich abwechselnd mit zwei 
Kanäelen des ADCs aufnehmen möchte.

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

Bewertung
0 lesenswert
nicht lesenswert
Ana Kamenova schrieb:

> Abtastrate möchte ich auch niedrig halten. Für mich ist wchtig, dass der
> Teil:

...
> richtig ist.

Grundsätzlich spricht da jetzt erst mal nichts dagegen.
Genaueres kann man erst sagen, wenn du dir eine Möglichkeit schaffst, 
dir die Warte anzusehen. In deinem Fall wäre natürlich eine UART ideal, 
da es mit deinen Wertemengen auf einem LCD schon recht eng ist. Damit 
kann man sich dann auch einmal grafisch aufbereiten, was der ADC da 
eigentlich gesampelt hat.

Man könnte einen Minimaltest machen: Wenn mit dem ADC etwas nicht 
stimmt, dann sind meistens alle Werte gleich, entweder 0 oder 1024.

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.