Forum: Mikrocontroller und Digitale Elektronik conversion float nach int


von Uwe N. (soda79)


Lesenswert?

Hallo,


MCU ATtiny13A
IDE Microchip Studio


Hab hier ein conversion Problem von float nach int bzw. umgekehrt.
Ist dies mit einem 8-bit MCU überhaupt ohne weiteres möglich?
Der Compiler wills einfach nicht bauen.




float min = 40.f;
float max = 200.f;

int adcValue = ADCH;
float adcValueNormalized = (float)adcValue / 255.f;

OCR0B = (int)(min * (1.f - adcValueNormalized) + max * 
adcValueNormalized);



Danke
Uwe

von mitlesa (Gast)


Lesenswert?

Uwe N. schrieb:
> Der Compiler wills einfach nicht bauen.

Was sagt denn dein Compiler?

"Ich wills nicht bauen"?

Oder sagt er was anderes?

von Uwe N. (soda79)


Lesenswert?

Hi,

hier die Fehlerliste.
1
Severity  Code  Description  Project  File  Line
2
Error    ATtiny13A-PWM.elf section `.text%16' will not fit in region `text'  ATtiny13A-PWM    1
3
Error    Could not allocate section .text, size = 10 bytes, attributes = code  ATtiny13A-PWM  addsf3.o  0
4
Error    Could not allocate section .text, size = 2 bytes, attributes = code  ATtiny13A-PWM  C:/Program Files (x86)/Atmel/Studio/7.0/Packs/atmel/ATtiny_DFP/1.10.348/xc8/avr/lib/avr25/tiny-stack/memx-const/crtattiny13a.o  0
5
Error    recipe for target 'ATtiny13A-PWM.elf' failed  ATtiny13A-PWM  C:\Microchip-Studio-Projekte\AVR-Projekte\ATtiny13A-PWM\ATtiny13A-PWM\Debug\Makefile  106
6
Error    ld returned 1 exit status  ATtiny13A-PWM  collect2.exe  0
7
Error    Could not allocate section .text.exit, size = 14 bytes, attributes = code  ATtiny13A-PWM  exit.o  0
8
Error    Could not allocate section .text.__dummy_fini, size = 2 bytes, attributes = code keep  ATtiny13A-PWM  exit.o  0
9
Error    Could not allocate section .text.__dummy_funcs_on_exit, size = 2 bytes, attributes = code  ATtiny13A-PWM  exit.o  0
10
Error    Could not allocate section .text.__dummy_simulator_exit, size = 2 bytes, attributes = code  ATtiny13A-PWM  exit.o  0
11
Error    Could not allocate section .text, size = 10 bytes, attributes = code  ATtiny13A-PWM  fixsfsi.o  0
12
Error    Could not allocate section .text, size = 122 bytes, attributes = code  ATtiny13A-PWM  floatsisf.o  0
13
Error    Could not allocate section .text, size = 12 bytes, attributes = code  ATtiny13A-PWM  fp_inf.o  0
14
Error    Could not allocate section .text, size = 6 bytes, attributes = code  ATtiny13A-PWM  fp_nan.o  0
15
Error    Could not allocate section .text, size = 34 bytes, attributes = code  ATtiny13A-PWM  fp_round.o  0
16
Error    Could not allocate section .text, size = 68 bytes, attributes = code  ATtiny13A-PWM  fp_split3.o  0
17
Error    Could not allocate section .text, size = 14 bytes, attributes = code  ATtiny13A-PWM  fp_zero.o  0
18
Error    Could not allocate section .text, size = 4 bytes, attributes = code  ATtiny13A-PWM  mulsf3.o  0
19
Error    Could not allocate program memory  ATtiny13A-PWM  RUNCOMPILERTASK  0
20
Error    Could not allocate section .text._Exit, size = 2 bytes, attributes = code  ATtiny13A-PWM  _Exit.o  0

: Bearbeitet durch Moderator
von Irgend W. (Firma: egal) (irgendwer)


Lesenswert?

Uwe N. schrieb:
> hier die Fehlerliste.

Da ist aber so rein garnichts dabei was mit dem oben gezeigten Code zu 
tun hat.

Ich würde mal darauf tippen das du mit dem (vermutlich)kaputten Makefile 
noch nichtmal eine leere "main" zum laufen bekommst.

von foobar (Gast)


Lesenswert?

Dem geht wohl ROM und/oder RAM aus.

Warum nicht einfach mit int rechnen?
1
unsigned min = 40, max = 200;
2
3
OCR0B = min + ((max - min) * ADCH + 127) / 255;

von Uwe N. (soda79)


Lesenswert?

Falsch Irgend W.,


PWM läuft ohne Probleme in Mode 5. Habs das Signal mit dem Oszi geprüft.
Hab OCR0A auf max (float max = 200.f) gesetzt und will nun ADC und PWM 
abgleichen;


Aber erstmal rumkrähen!

Nicht Danke!

von Uwe N. (soda79)


Lesenswert?

Danke Foobar,

für den konstruktiven Beitrag.

ROM ? Meinst du den 1kB Programmspeicher?

Der ist mit den paar Zeilen schon ausgeschöpft?

von foobar (Gast)


Lesenswert?

> ROM ? Meinst du den 1kB Programmspeicher?
> Der ist mit den paar Zeilen schon ausgeschöpft?

Nun ja, die HW kann kein float - das muss emuliert werden.  Beim 
Einbinden des Codes für die Addition (addsf3.o) fliegt er raus.


PS: Das ".size%16" sagt mir aber nichts - AVR Eigenheit?

von MaWin (Gast)


Lesenswert?

Uwe N. schrieb:
> Der ist mit den paar Zeilen schon ausgeschöpft?

Wahrscheinlich schon. Du rechnest mit Software-emuliertem-Float.
Das braucht jede Menge Librarycode und jede Menge Code bei jeder 
Berechnung.

von Martin (Gast)


Lesenswert?

>Der ist mit den paar Zeilen schon ausgeschöpft?

Folgender Code liefert bei mir 96,3 % Speicherauslastung. die fp-lib 
braucht fast ein kilobyte.
1
#include <avr/io.h>
2
 
3
int main(void) {
4
  volatile float fl1, fl2 = 2.33, fl3 = 0.66;
5
6
  fl1 = fl2 + fl3;
7
  fl1 = fl2 - fl3;
8
  fl1 = fl2 * fl3;
9
  fl3 = fl2 / fl3;
10
}

von foobar (Gast)


Lesenswert?

> Folgender Code liefert bei mir 96,3 % Speicherauslastung.

RAM (afaik 64 Bytes) dürfte ähnlich eng sein - alleine die 3 lokalen 
Variablen brauchen schon 20% des RAMs ...

von Mark B. (markbrandis)


Lesenswert?

Uwe N. schrieb:
> Der Compiler wills einfach nicht bauen.

Der Compiler baut das sehr wohl. Der Fehler tritt beim Linken auf.

Wenn Deine Zielhardware keine native Unterstützung für Gleitkommazahlen 
bietet, dann solltest Du sie auch nicht einsetzen. Wie andere schon 
gesagt haben wird das sonst in Software emuliert. Und zack ist der 
Speicher (zu) voll.

von Uwe N. (soda79)


Lesenswert?

Der Code von foobar wird compiliert mit:

Program Memory Usage   :  392 bytes   38,3 % Full
Data Memory Usage  :  4 bytes   6,3 % Full

Werde wohl nun mit dem Attiny13 float-Operationen vermeiden.


Danke allen und einen schönen Abend.
Uwe

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Hier ein Bespiel mit ISO/IEC TR18037 "Embedded-C" Fixed-point:
1
#include <stdfix.h>
2
#include <avr/io.h>
3
4
int main (void)
5
{
6
    accum min = 40.0k;
7
    accum max = 200.0k;
8
9
    accum adcValue = ADCH;
10
    accum adcValueNormalized = adcValue / 255.0k;
11
12
    accum ocr = min * (1.0k - adcValueNormalized) + max * adcValueNormalized;
13
14
    OCR0B = (uint8_t) ocr;
15
}

"accum" ist ein 32-Bit Fixed-Point Typ mit Signatur s16.15, also Signed 
mit 16 Vorkomma-Bits.

Für "Embedded-C" gibt's keinen eigenen GCC-Schalter, man muss GNU-C 
verwenden, also etwa
1
avr-gcc -Os fix.c -save-temps -mmcu=attiny13a -o fix.elf -std=gnu99

Codegröße im ELF ist 460 Bytes mit avr-gcc v8, also inclusive 
Startup-Code und Lib-Funktionen (32-Bit Fixed-Point Multiplikation und 
Division mit Rundung zum Nächsten).

Mit "unsigned accum" und Konstanten (Suffix "uk") fällt die Codegröße 
auf unter 300 Bytes.

Mit weiterer [unsigned] accum Arithmetik wächst die Code größe dann nur 
noch langsam, weil man die Lib-Funktionen ja nur 1x braucht.

: Bearbeitet durch User
von Denn-sie-wissen-nicht-was-sie-tun (Gast)


Lesenswert?

Uwe N. schrieb:
> ROM ? Meinst du den 1kB Programmspeicher?
>
> Der ist mit den paar Zeilen schon ausgeschöpft?

Der ist schon in dem Moment ausgeschöpft, wo du an float denkst.
Wie kann man auf die Idee kommen, bei insgesamt nur 1kB verfügbarem 
Programmspeicher eine Float Library einzubinden?

von Uwe N. (soda79)


Lesenswert?

Denn-sie-wissen-nicht-was-sie-tun schrieb:
> Wie kann man auf die Idee kommen, bei insgesamt nur 1kB verfügbarem
> Programmspeicher eine Float Library einzubinden?

Ist das eine rhetorische Frage? Ich antworte mal trotzdem.

Vermutlich aufgrund meiner Unwissenheit, daß der Tiny13 keine 
Hardwareunterstützung für Gleitkommazahlen bietet.

Hab ja auch Microstudio und den Tiny erst seit gestern.



@Johann L.:
Danke für den Beitrag.

von DerEinzigeBernd (Gast)


Lesenswert?

Uwe N. schrieb:
> Vermutlich aufgrund meiner Unwissenheit, daß der Tiny13 keine
> Hardwareunterstützung für Gleitkommazahlen bietet.

Das machen Microcontroller so gut wie nie. So etwas gibt es erst bei 
recht fetten Kloppern wie einem ARM-Cortex M4, der aber in einer mehrere 
Größenordnungen anderen Liga spielt als irgendein AVR, ob Tiny oder 
Mega.

von Stefan F. (Gast)


Lesenswert?

Nur um der nächsten Überraschung vorzubeugen:

printf() geht auf den ATtiny13 ebenfalls nicht, weil er dafür zu klein 
ist.

von Denn-sie-wissen-nicht-was-sie-tun (Gast)


Lesenswert?

Uwe N. schrieb:
> Vermutlich aufgrund meiner Unwissenheit, daß der Tiny13 keine
> Hardwareunterstützung für Gleitkommazahlen bietet.

Zu den allermeisten Mikrocontrollern gibt es Datenblätter. Manchmal 
lohnt es sich, dort einen Blick reinzuwerfen.

von Uwe N. (soda79)


Lesenswert?

Denn-sie-wissen-nicht-was-sie-tun schrieb:
> Zu den allermeisten Mikrocontrollern gibt es Datenblätter. Manchmal
> lohnt es sich, dort einen Blick reinzuwerfen.

Hab die 178 Seiten PDF seit gestern hier vorliegen, und sogar mal 
reingeschaut um herauszufinden wie ich Phase Correct PWM, ADC und Timer 
konfiguriere.

Habs halt nicht wie einen Roman von Anfang bis Ende gelesen. Dafür war 
ich zu ungeduldig.

von Jonas B. (jibi)


Lesenswert?

Ich hätte ja gleich ein dicken "Klopper" genommen. Downsizen lässt sich 
später immer noch. Nur Upsizing ist schwierig ohne neue Hardware. Gut 
die Datenblätter haben dann halt mal 800 Seiten - aber hey irgendeinen 
Tod muss man sterben. Viel Erfolg noch :)

von foobar (Gast)


Lesenswert?

Uwe schrieb:
> Werde wohl nun mit dem Attiny13 float-Operationen vermeiden.

Ich würde sogar noch einen Schritt weiter gehen: auf Mikrocontrollern 
mit so wenig RAM (hier 64 Bytes, für Daten und Stack) würde ich C 
vermeiden!

Wenn man den Compiler nicht seeehr intim kennt, fliegt man in 
Null-Komm-Nix auf die Schnauze.  Und selbst wenn man ihn gut kennt, 
kommt man nicht drum herum, den generierten Kode zu überprüfen - ein 
Register-spill zuviel und es bleibt kein Stack für IRQs oder einen 
weiteren Funktionsaufruf übrig. Beim AVR kommt noch dazu, dass alle 
Daten (auch read-only) ins RAM kopiert werden.  Wenn man da nicht 
ordentlich PROGMEM benutzt, reicht's evtl nichtmal für den main-Aufruf.

Insbesondere sollte man fremde Libraries, die nicht explizit auf so 
geringen Speicherbedarf getrimmt sind[1], nicht ohne Code-Review 
benutzten.  Die FP-Routinen z.B. würden für jede Temp-Variable, die sie 
evtl benötigen, ~10% des RAMs belegen.  Wieviele brauchen sie für die 
verschiedenen Funktionen?  Wie tief sind Funktionsaufrufe geschachtelt? 
Usw.

Klar, man kann einfach "Augen-zu" losprogrammieren und ausprobieren - 
das sind dann die Programme, die undefiniert absemmeln[2] und wo dann 
das Problem in der HW gesucht wird (das Programm ist ja "ausprobiert" 
und läuft!) :-(

Assembler ist auf AVRs ziemlich angenehm - ruhig mal ausprobieren[3] ;-)


--
[1] Die geben dann an, wieviel Resourcen (Stack/RAM/ROM/Takte) sie 
benötigen.  Bei so geringem Speicher ist das kein "nice to have" sondern 
zwingend notwendig!
[2] Z.B. IRQ zum unpassenden Zeitpunkt, wo der Stack gerade gut belegt 
war.
[3] So wenig Speicher ist einer der wenigen Fälle, wo ich Assembler 
propagiere ...

von Oliver S. (oliverso)


Lesenswert?

foobar schrieb:
> Ich würde sogar noch einen Schritt weiter gehen: auf Mikrocontrollern
> mit so wenig RAM (hier 64 Bytes, für Daten und Stack) würde ich C
> vermeiden!

Ich würde sogar noch den Schritt weitergehen, und so etwas wie den 
ATtiny13 überhaupt nur dann einzusetzen, wenn es dafür einen sehr, sehr 
guten Grund gibt. Und den gibt es beim To augenscheinlich nicht.

Oliver

von Uwe N. (soda79)


Lesenswert?

foobar schrieb:
> Assembler ist auf AVRs ziemlich angenehm - ruhig mal ausprobieren[3] ;-)

Werd ich machen. Muß mich mal mit den mnemonics auseinandersetzen.


Oliver S. schrieb:
> Ich würde sogar noch den Schritt weitergehen, und so etwas wie den
> ATtiny13 überhaupt nur dann einzusetzen, wenn es dafür einen sehr, sehr
> guten Grund gibt. Und den gibt es beim To augenscheinlich nicht.

Ich habe den Tiny13 gewählt, weil ich für mein Projekt genau eine PWM 
und ein ADC benötige. Wollte deshalb keinen größeren MCU.

Uwe

von EAF (Gast)


Lesenswert?

Uwe N. schrieb:
> Wollte deshalb keinen größeren MCU.

Der t85 hat die selben Ausmaße und einen nur geringfügig höheren Preis.
Ist dafür allerdings für C und C++ recht gut geeignet.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Uwe N. schrieb:
> Ich habe den Tiny13 gewählt, weil ich für mein Projekt genau eine PWM
> und ein ADC benötige.

Dann hättest du dir vorher auch Gedanken um die weiteren benötigten 
Ressourcen, insbesondere hinsichtlich der Software machen sollen.

Mal ehrlich, für ein Hobbyprojekt in einstelligen Stückzahlen würde ich 
mir die Platzknappheit eines 1-KiB-Controllers nicht so ohne weiteres 
antun. Ein ATtiny25 kostet nur ein paar Cents mehr und bietet schon 
doppelte Ressourcen, und mit dem ATtiny85 im gleichen Gehäuse hast du 
reichlich Reserven während der Entwicklungsarbeit.

Bei wirklich finanziell knapp aufgestellten Projekten ist das was 
anderes, aber da macht man sich (s.o.) halt auch wirklich schon mal 
vorher Gedanken, dass die Software damit zurecht kommen kann.

: Bearbeitet durch Moderator
von Uwe N. (soda79)


Lesenswert?

Danke, ich werde eure Tipps beim nächsten Projekt beherzigen.

Die einfache PWM Steuerung ist nun fertig.

Program Memory Usage   :  368 bytes   35,9 % Full
Data Memory Usage   :  4 bytes   6,3 % Full
Warning: Memory Usage estimation may not be accurate if there are 
sections other than .text sections in ELF file



Grüße
Uwe

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Klar, die PWM selbst braucht nicht viel Code. Ist ja nur die Frage, wie 
du berechnest, was du da einstellen musst.

Manchmal ist Gleitkomma für sowas eben schön einfach, weil es unserer 
sonst üblichen Zahlendarstellung entspricht.

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
Noch kein Account? Hier anmelden.