mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik 10 * 10 Bit multiplizieren


Autor: Bastelphilipp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe einen 10Bit Wert vom Analog-Digitalwandeler.
Dieser ist in einer unsigned short integer Variable gespeichert.
µC ist der ATtiny 25 Der ADC-Wert ist rechtbündig.
Jetzt brauche ich für eine Berechnung das Quadrat des ADC-Wertes.
Eine 10 * 10 Bit Multiplikation würde doch ein 20 Bit Ergebnis erzeugen.
Also müsste ich das in einer unsigned long integer Variablen speichern.

Wie kann ich das pogrammieren?

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auf einem 20-Bit-Prozessor mit dem dortigen MUL-Befehl.

Ansonsten: erst mal verraten, womit du arbeitest?

Autor: Bastelphilipp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:
> Auf einem 20-Bit-Prozessor mit dem dortigen MUL-Befehl.
>

Ich kenne keinen 20-Bit-Prozessor   ;-)

> Ansonsten: erst mal verraten, womit du arbeitest?

AVR-Studio 4

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du die ganzen 20 Bits des Ergebnisses benötigst, dann
  (uint32_t)x * (uint32_t)y

Autor: compilator (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Einfach Produkt als uint32_t deklarieren, der Compiler kümmert sich um 
das Übrige. Bib zwar nicht 100% sicher :/ ev. Faktor zu uint32_t casten.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
compilator schrieb:

> Einfach Produkt als uint32_t deklarieren

Nicht empfehlenswert. Auf einer 16-Bit Maschine ist
  uint32_t product = 10000 * 10000;
undefiniert. Ein Operator richtet sich nur nach dem Typ der Operanden, 
nicht nach dem Typ links vom "=".

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
compilator schrieb:
> Einfach Produkt als uint32_t deklarieren, der Compiler kümmert sich um
> das Übrige. Bib zwar nicht 100% sicher :/ ev. Faktor zu uint32_t casten.

Falls du sowas meinst:
   uint16_t  x = ..., y = ...;
   uint32_t ergebnis;

   ergebnis = x * y;
, dann nein:
Der Compiler kümmert sich nicht vor der Multiplikation um das Erweitern 
auf 32 Bit, sondern erst danach zur Zuweisung.

Richtig wäre:
   uint16_t  x = ..., y = ...;
   uint32_t ergebnis;

   ergebnis = (uint32_t)x * y;
oder
   uint16_t  x = ..., y = ...;
   uint32_t ergebnis;

   ergebnis = x * (uint32_t)y;
oder die Version von A.K.

Autor: Bastelphilipp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> (uint32_t)x * (uint32_t)y

Würde der Compiler bei dieser Schreibweise eine 32 * 32 Bit 
Multiplikation ausführen und nur die unteren 32 Bit des Ergebnisses 
behalten?

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

Bewertung
0 lesenswert
nicht lesenswert
Bastelphilipp schrieb:
> A. K. schrieb:
>> (uint32_t)x * (uint32_t)y
>
> Würde der Compiler bei dieser Schreibweise eine 32 * 32 Bit
> Multiplikation ausführen und nur die unteren 32 Bit des Ergebnisses
> behalten?

Ja, würde er.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Genauer gesagt: er würde aus 32Bit*32Bit nur 32 Bit berechnen
(also nicht 32*32->64 und dann abschneiden).

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Würde der Compiler bei dieser Schreibweise eine 32 * 32 Bit
>> Multiplikation ausführen und nur die unteren 32 Bit des Ergebnisses
>> behalten?

> Ja, würde er.

Nein würde er nicht: die oberen 32-Bit werden erst gar nicht berechnet 
(siehe Assemblertext einer 32-Bit Multiplikation).

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

Bewertung
0 lesenswert
nicht lesenswert
@Klaus und @Martin
Jetzt werdet ihr aber spitzfindig :-)
Ausser der erhöhten Rechenzeit ist das Ergebnis nicht von dem von 
Bastelphillip angedachten Mechanismus zu unterscheiden. Und selbst bei 
dem könnte man argumentieren, dass er eigentlich das Richtige gemeint 
hat.

Autor: ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
20 Bit Prozessoren kenne ich auch nicht, es gibt (bzw. gab) aber welche 
mit 30 Bits.

In ASM könnte man auch die Multiplication gleich 10 Bit * 16 Bit -> 24 
Bits programmieren. Das Ergebnis dann als 3 Bytes. Das wäre von der 
Ausführung einiges schneller.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> @Klaus und @Martin
> Jetzt werdet ihr aber spitzfindig :-)

Ich wollte dich ja auch nicht kritisieren, sondern es nur etwas
klarer präzisieren (weil ich mir schon dachte, daß es sonst gleich
als falsch kritisiert werden würde, was es meiner Meinung ja
nicht war).

Hat nur nichts geholfen :-(

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ulrich schrieb:
> 20 Bit Prozessoren kenne ich auch nicht, es gibt (bzw. gab) aber welche
> mit 30 Bits.

Ich auch nicht, aber hatte ja nicht gesagt, welchen er hat.
Deshalb habe ich der Einfachheit mal 20 angenommen :-)

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bastelphilipp schrieb:
> µC ist der ATtiny 25 Der ADC-Wert ist rechtbündig.

Klaus Wachtler schrieb:
> ulrich schrieb:
>> 20 Bit Prozessoren kenne ich auch nicht, es gibt (bzw. gab) aber welche
>> mit 30 Bits.
>
> Ich auch nicht, aber hatte ja nicht gesagt, welchen er hat.

Wie meinen?

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kenne auch keinen Prozessor mit 20 Bit.
Weil im OP aber nicht stand, welchen Rechner er hat und ich
deshalb nicht wusste, ob er einen der mir bekannten mit 8,
16, 32, 40, 48 oder 64 Bit hat, hätte ich eh falsch geraten.
Dann konnte ich auch genausogut einen mit 20 Bit annehmen.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:
> Weil im OP aber nicht stand, welchen Rechner er hat und ich

Also nochmal:

Bastelphilipp schrieb:
> µC ist der ATtiny 25 Der ADC-Wert ist rechtbündig.
             ^^^^^^^^^

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, jetzt wo du darauf bestehst, sehe ich es auch endlich, sorry.
Ich dachte das mit dem tiny wäre erst später gekommen.

"Ich bin nicht dümmer als andere, nur langsamer."

Autor: Bastelphilipp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ulrich schrieb:
> In ASM könnte man auch die Multiplication gleich 10 Bit * 16 Bit -> 24
> Bits programmieren. Das Ergebnis dann als 3 Bytes. Das wäre von der
> Ausführung einiges schneller.

In ASM könnte man

Wer ist man?

Könntest du eventuel die in C einbindbare ASM Funktion
unsigned long int quad_10_10_20(unsigned short int)
programmieren? Ich würde mich sehr freuen!

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wozu soll sich jemand die Mühe machen, wenn der Compiler 16*16->32 kann?
Siehe A.K.: Beitrag "Re: 10 * 10 Bit multiplizieren"

Autor: Bastelphilipp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:
> wozu soll sich jemand die Mühe machen, wenn der Compiler 16*16->32 kann?

weil der Compiler eine zeitaufwendige 32*32->64 Multiplokation macht und 
die oberen 32 Bit wegwirft. Das dauer auf einem 8-Bit µC (ATtiny 25) 
ohne MUL Befehl mindestens ein paar hundert Taktzyklen!

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Könntest du eventuel die in C einbindbare ASM Funktion
>unsigned long int quad_10_10_20(unsigned short int)
>rogrammieren? Ich würde mich sehr freuen!

Wenn du die Anbindung an C selbst machst kannst du die 10 
Assemblerzeilen für eine Multiplikation 16Bit*16Bit=24Bit auf einem 
ATMega von mir haben.

MfG Spess

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bastelphilipp schrieb:
> Klaus Wachtler schrieb:
>> wozu soll sich jemand die Mühe machen, wenn der Compiler 16*16->32 kann?
>
> weil der Compiler eine zeitaufwendige 32*32->64 Multiplokation macht und
> die oberen 32 Bit wegwirft.

Seit wann das?

Das hatten wir doch eben schon diskutiert.

Autor: Assembler Amateur (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bastelphilipp schrieb:
> mindestens ein paar hundert Taktzyklen!

Wie schnell hättest du es denn gerne?

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

Bewertung
0 lesenswert
nicht lesenswert
Wobei sich dann ja auch noch die Frage erhebt, ob man überhaupt 10*10 
Bit rechnen muss, oder obs nicht 8 * 8 Bit auch tut.

Was berechnest du denn eigentlich?

Irgendwie habe ich gerade das Gefühl, wir erleben gerade die µC-Version 
von: Mein Taschenrechner spuckt 10 Nachkommastellen aus, also geb ich 
die auch an, egal ob das Sinn macht oder nicht.

Autor: ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Immhin macht der Compiler da eine 32 Bit x 32 Bit -> 32 Bit 
Multiplikation.  Wenn man nur die wirklich benötigten Bits berechnet 
kann das schon mal 5-10 mal schneller gehen.

Ließe sich sicher machen. Den ASM code findet man z.B. in der Atmel Appl 
Note 200. Müsste man nur noch in inline ASM umsetzen.
Alternativ einen µC mit MUL-Befehl nehmen, dann ist auch die 32x32 
Multiplikation nicht so langsam.

Ich hätte aber ein paar zweifel daran dass man wirlich das Quadrat des 
AD Wertes braucht. Vermutlich sollte man da vorher noch erstmal 512 oder 
was ähnliches von abziehen.

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>> Bastelphilipp schrieb:
>>> mindestens ein paar hundert Taktzyklen!
>> Wie schnell hättest du es denn gerne?

Der Name von Bastelphilipp scheint Programm zu sein.

Autor: Christoph Kessler (db1uq) (christoph_kessler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Assemblerroutinen gibts hier:
http://www.mikrocontroller.net/articles/AVR_Arithm...

http://avr-asm.tripod.com/math32x.html
-> "MUL32" Multiply Unsigned Rd64 = Rd32 * Rr32

http://elm-chan.org/cc_e.html
->AVR assembler libraries - 16bit x 16bit multiply(signed/unsigned)

Autor: Dirk Schmidt (disc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe mal vor einiger Zeit mehrere Inline-Assembler 
Multiplikations-Funktionen geschrieben.
Es sind da inbesondere spezielle Multiplikationen, wie 8x16bit und auch 
16x16->32bit vorhanden.

Siehe hier: Beitrag "GCC Inline Assembler Multiplikationen"

Gruß

Dirk

Autor: Bastelphilipp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ulrich schrieb:
> Ich hätte aber ein paar zweifel daran dass man wirlich das Quadrat des
> AD Wertes braucht.

Da ist ein doppelt isoliertes Gefäß mit einem Heizwiderstand drin.
Der Heizwiderstand ist aus einer Legierung ohne Temperaturabhängigkeit.
Die Spannung am Heizwiderstand wird 1800 mal pro Sekunde gemessen.
Heizleistung ist U^2 / R.
Dies wird aufsummiert.
Wenn eine vorher eingestellte Wärmeenergie erreicht ist, wird die 
Heizung abgeschaltet.

Autor: Gregor B. (gregor54321)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da der Widerstand ja temperaturunabhängig sein soll, würde doch eine 
stabilisierte Spannung mit definierter Einschaltdauer aufs selbe 
Ergebnis kommen?

Autor: Bastelphilipp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gregor B. schrieb:
> Da der Widerstand ja temperaturunabhängig sein soll, würde doch eine
> stabilisierte Spannung mit definierter Einschaltdauer aufs selbe
> Ergebnis kommen?

Ja, das war der Ausgangspunkt meiner Entwicklung.
Aber eine Stabilisierung der Spannung auf 0,1% ist zu aufwendig und 
verbraucht zuviel Verlustleistung. Deshalb habe ich mich jetzt für ein 
"smart Concept" entschieden, das auf eine 20cm^2 Platine passt und 
einfach einen kleinen ATtiny ein bischen rechnen lässt.

Autor: ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man benötigt dann aber auch eine gute Ref. für den AD Wandler. Die 
chip-interne reicht da eher nicht.

Wenn man nur 2000 mal die Sekunde misst, hat der µC doch relativ viel 
Zeit für die Berechnungen. Mit 2-4 MHz an Takt sollte das reichen, auch 
mit 32 Bit Werten. Sonst halt die Inline ASM routine für 16x16 -> 32 
Bits. Damit sollte es auch bei 1 MHz noch reichen.

Meine Prefferenz wäre da aber eine grobe Stabilisierung und ein 
langsamerer aber genauerer AD Wandler. Damit es am Ende auch hinkommt 
dann die Zeit berechnen unter der Annahmen von wenig Drift.

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.