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?
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
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 "=".
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:
1
uint16_tx=...,y=...;
2
uint32_tergebnis;
3
4
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:
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?
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.
>> 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).
@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.
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.
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 :-(
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 :-)
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?
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.
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.
^^^^^^^^^
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."
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
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!
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
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.
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.
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.
Hi
>> Bastelphilipp schrieb:>>> mindestens ein paar hundert Taktzyklen!>> Wie schnell hättest du es denn gerne?
Der Name von Bastelphilipp scheint Programm zu sein.
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
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.
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.
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.