mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Float to Int?


Autor: Lea Weiss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey Leute, ich möchte gerne meine Output Compare Register mit einer 
Variable laden
OCR1A=k;
dies funktioniert nicht weil k ein Float Wert ist.

wie kann ich k in einen Int Wert konvertieren?

MFG Lea

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

Bewertung
0 lesenswert
nicht lesenswert
Lea Weiss schrieb:
> Hey Leute, ich möchte gerne meine Output Compare Register mit einer
> Variable laden
>
> OCR1A=k;
> 
> dies funktioniert nicht weil k ein Float Wert ist.

Nö. das funktioniert schon.
Bei der Zuweisung eines float an einen int werden alle Kommastellen 
abgeschnitten und das Ergebnis als int weiterbehandelt.

Autor: Thomas K. (muetze1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wäre mir neu, mWn muss man diesen Verlust an Informationen explizit 
erlauben mit einem Cast zu einem int.
OCR1A = (int)k;

Eine Erweiterung mit Informationen, also einen int einem Float zuweisen, 
das ist aber ohne Cast möglich.

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

Bewertung
0 lesenswert
nicht lesenswert
Thomas K. schrieb:
> Wäre mir neu, mWn muss man diesen Verlust an Informationen explizit
> erlauben

Nö, muss man nicht.
Einige Compiler warnen, wenn so etwas passiert. Aber grundsätzlich ist 
das nicht verboten.

Autor: Thomas K. (muetze1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber genau das war doch der Unterschied zwischen expliziten und 
impliziten Casts. Implizite macht der Compiler stillschweigend (und alle 
samt ohne Datenverlust) und explizite waren immer bei Datenverlust nötig 
(oder bei komplexen Typen).

Ok, das war nun nicht der Unterschied der definiert was implizit und 
explizit Casts sind. Sondern der Unterschied der die Anwendung dieser 
beschreibt/nötig macht.

/EDIT: Aber du hast Recht. Habe mich nochmal kundig gemacht und 
getestet. Bin wohl noch etwas von Delphi/Pascal geschädigt, da ist es 
wie ich es geschrieben hatte. Aber eine strenge Typprüfung ist ja einer 
der Punkte von Delphi Language/Pascal. In C/C++ ist kein Cast notwendig.

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

Bewertung
0 lesenswert
nicht lesenswert
Thomas K. schrieb:
> Aber genau das war doch der Unterschied zwischen expliziten und
> impliziten Casts. Implizite macht der Compiler stillschweigend (und alle
> samt ohne Datenverlust) und explizite waren immer bei Datenverlust nötig
> (oder bei komplexen Typen).

Du must unterscheiden zwischen einem Fehler, von dem die 
Sprachdefinition fordert, das er angemäkelt wird und einer Warnung, die 
ein Compilerbauer von sich aus, aus freien Stücken, eingebaut hat.

Die Zuweisung eines float an einen int ist kein Fehler. Selbst wenn 
einige Compiler (aus guten Gründen) eine Warnung geben. So nach dem 
Motto: "Ich tu schon was du von mir willst, aber bist du dir da wirklich 
sicher? Oft ist das ein Flüchtigkeitsfehler, drum werfe ich mal 
sicherheitshalber eine Warnung."

Aber auf jeden Fall ist das kein Kandidat für
<Zitat>
dies funktioniert nicht
</Zitat>

Im übrigen ist diese Version, die auch noch rundet
  OCR1A = (int)( k + 0.5);
meistens die bessere Wahl. Sonst kann es nämlich ganz schnell passieren, 
das aus 5.99999999 (also praktisch 6) trotzdem 5 wird und nicht 6.

Autor: Lea Weiss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
habe es so versucht:

  OCR1A=(int)k;


funktioniert auch nicht...

fehler meldung ist für mich auch nicht verständlich:

Build started 30.4.2010 at 21:14:40
avr-gcc  -mmcu=atmega32 -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char 
-funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT 
Pflichtsoftware1.o -MF dep/Pflichtsoftware1.o.d  -c 
../Pflichtsoftware1.c
avr-gcc -mmcu=atmega32 -Wl,-Map=Pflichtsoftware1.map Pflichtsoftware1.o 
-o Pflichtsoftware1.elf
c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr5\lib 
c.a(log.o):  In function `log':
(.text.fplib+0x46): relocation truncated to fit: R_AVR_13_PCREL against 
symbol `__addsf3' defined in .text section in 
c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/avr5\libgcc.a(_addsub_sf.o)
c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr5\lib 
c.a(log.o):  In function `log':
(.text.fplib+0x4e): relocation truncated to fit: R_AVR_13_PCREL against 
symbol `__addsf3' defined in .text section in 
c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/avr5\libgcc.a(_addsub_sf.o)
make: *** [Pflichtsoftware1.elf] Error 1
Build failed with 1 errors and 0 warnings...

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

Bewertung
0 lesenswert
nicht lesenswert
Das müsste sein:
Du hast die Floating Point Library nicht eingebunden, oder mit deiner 
Installation stimmt etwas nicht.

Autor: Thomas K. (muetze1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und wie zum Teufel kommst du von der Fehlermeldung auf die o.g. 
Fehlerzeile?

@khbuchegg: hatte oben schon editiert, du hast vollkommen Recht. Hatte 
das noch anders im Kopf aufgrund der langen Delphi/Pascal 
Programmierung. Hatte es auch schon ausprobiert.

Autor: Lea Weiss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das ist halt die Fehlermeldung die kommt..

wenn ich die Zeile auskommentiere funktioniert alles wunderbar.

Autor: Lea Weiss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
<float.h> wurde eingebunden.

Autor: Lea Weiss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hier der Code... kann mir niemand helfen?

int main(void)
{
float temperatur_soll_LM45 = 0;
float k=0;

float Kp=200;
float Ki=2;
float Ta=20;

float e=0;
float esum=0;

DDRC=0xFF;
DDRD=0xFF;

PORTC=0;
PORTD=0xFF;
PORTB=0xFF;

Initialize_Timer0(2,2,256);
TIMSK |= (1<<TOIE0);

ADMUX   |=   (   1<<REFS0   |  1<<MUX0);
ADCSRA   |=  (   1<<ADEN    );

TCCR1A   |=  (  1<<COM1A1  |  1<<WGM10  |  1<<WGM11);
TCCR1B  |=  (  1<<CS10    |  1<<CS12);

OCR1A=0;

lcd_init();
lcd_clear();
sei();

while(1)
    {      
  temperatur_soll_LM45 = temperatur_ist_NTC+2;
  e=temperatur_soll_LM45-temperatur_ist_LM45;
  esum+=e;

  if(esum<-300)esum=-300;
  if(esum>300)esum=300;

  k=e*Kp+Ki*Ta*esum;


  if(k>1021)k=1021;
  if(k<0)k=0;

  OCR1A=(int)k;

  _delay_ms(250);
    {
    // Daten an Display ausgeben
    char Buffer[20]; // in diesem {} lokal
    set_cursor(0,1);lcd_string(" Temp1:");
    set_cursor(6,1);lcd_string("     ");set_cursor(6,1);
    dtostrf(temperatur_ist_LM45,7,2, Buffer );
    lcd_string( Buffer );lcd_data(223);lcd_data('C');

    set_cursor(0,2);lcd_string(" Temp2:");
    set_cursor(6,2);lcd_string("     ");set_cursor(6,2);
    dtostrf(temperatur_ist_NTC, 7, 2, Buffer );
    lcd_string( Buffer );lcd_data(223);lcd_data('C');

  /*  set_cursor(0,4);lcd_string("     ");set_cursor(0,4);
    itoa(OCR1A, Buffer, 10 );
    lcd_string( Buffer );*/
    }
    }
 
    return 0;
}

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die float.h hilft nur dem Compiler.
Wenn der Linker Fehlermeldungen spuckt, fehlt meist die libm,
und die wird mit -lm eingebunden.

Das war damit wohl gemeint:
Karl heinz Buchegger schrieb:
> Du hast die Floating Point Library nicht eingebunden, oder mit deiner
> Installation stimmt etwas nicht.

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

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:
> Die float.h hilft nur dem Compiler.
> Wenn der Linker Fehlermeldungen spuckt, fehlt meist die libm,
> und die wird mit -lm eingebunden.
>
> Das war damit wohl gemeint:
> Karl heinz Buchegger schrieb:
>> Du hast die Floating Point Library nicht eingebunden, oder mit deiner
>> Installation stimmt etwas nicht.

Genau.
Aber ich wusste nicht mehr auswendig, wie man das im AVR-Studio macht 
:-)

Inzwischen hab ich nachgesehen:

Menüpunkt "Project" / "Configuration Options"
Im Dialog dann links "Libraries" anklicken
Im linken Listfeld die libm.a auswählen und "Add Library"

Alles mit OK bestätigen und erneut Builden lassen.

Autor: Guest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

wieso verwendest du überhaupt "float" Variablen? Sollte auch ohne gehen.
Denn ich sehe nur ganzzahlige Werte. Und eine Division kommt auch nicht 
vor ...
Verwende einfach Int16 bzw. Int32. Das macht auch den Code deutlich 
kleiner.

Autor: Lea Weiss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hm das Problem ist aber nur beim laden ins OCR1A Register.. ich konnte 
mit float rechnen, diese Werte ans Display übergeben, das hat keine 
Probleme verursacht..

float Bibliothek ist vorhanden, hab es soeben überprüft.

Autor: Lea Weiss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In der Subroutione wird mit einer Log() funktion gerechnet, daher 
entstehen Zahlen mit Kommastellen

[C]
ISR(TIMER0_OVF_vect){

// Sensor1 auslesen
  ADMUX   =   (   1<<REFS0   |  0<<MUX0  );   // AVcc als 
Referenzspannung, Multiplexer auf Position 0
  ADCSRA   |=  (   1<<ADSC  );           // Start einer Wandlung
  while(CHECKBIT(ADCSRA,ADIF)==0);
  SETBIT(ADCSRA,ADIF);//clear Interupt Flag

// Sensor 1 als LM45 auswerten
  ADC_Wert_LM45=ADCL;
  ADC_Wert_LM45+=ADCH<<8;
  temperatur_ist_LM45=50*ADC_Wert_LM45/102.4;

// Sensor2 auslesen
  ADMUX   =   (   1<<REFS0   |  1<<MUX0  ); // AVcc als 
Referenzspannung, Multiplexer auf Position 1
  ADCSRA   |=  (   1<<ADSC  );           // Start einer Wandlung
  while(CHECKBIT(ADCSRA,ADIF)==0);
  SETBIT(ADCSRA,ADIF);//clear Interupt Flag

// Sensor 2 als NTC behandeln
  ADC_Wert_NTC=ADCL;
  ADC_Wert_NTC+=ADCH<<8;
  temperatur_ist_NTC=(108025/(3625+log(1024/ADC_Wert_NTC-1)*298))*10-273;
  }
[\C]

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

Bewertung
0 lesenswert
nicht lesenswert
Lea Weiss schrieb:
> In der Subroutione wird mit einer Log() funktion gerechnet, daher
> entstehen Zahlen mit Kommastellen

LOL.
Wusste gar nicht das der gcc soooo gut ist.

Die Fehlermledung beschwert sich dass etwas mit log nicht stimmt.

In function `log':
(.text.fplib+0x46): relocation truncated to fit: R_AVR_13_PCREL against
symbol `__addsf3' defined in .text section in
c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/avr5\libgcc.a(_addsub_sf.o)


und in deiner ISR kommt ein log vor.
Was ist dein logischer Schluss?

> das Problem ist aber nur beim laden ins OCR1A Register.

Das ist der falsche Schluss. Der hat damit nichts oder nur auf Umwegen 
zu tun.

Autor: Lea Weiss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also Leute, ich habe jetzt folgendes gemacht:

int k;
int esum;

restliche Variablen float Zahlen, so funktioniert es..

wenn
float k;
float esum;

funktioniert es nicht...

wtf? :)

Autor: Lea Weiss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mein lieber  Karl heinz Buchegger,
variable k und esum kommen in der Subroutine nicht vor...

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

Bewertung
0 lesenswert
nicht lesenswert
Aber temperatur_ist_NTC

Ist die volatile?

Im übrigen brauchst du nicht mit mir streiten, denn: Der Compiler/Linker 
hat immer recht. Und dein Linker (nicht der Compiler) beschwert sich, 
dass er ein Problem mit der Funktion log() hat. Steht schwarz auf weiß 
dort.

Das kann nichts mit der Zuweisung zu tun haben. Ausser: Lässt du die 
Zuweisung weg, kann es sein, dass die Voraussetzung für die Berechnung 
des log() in der ISR wegfällt und der Optimizer den log ganz einfach 
rauswirft. Kein log() mehr, kein Problem für den Linker.

Autor: Lea Weiss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ist nicht volatile..

Autor: Lea Weiss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
habe mit volatile ausprobiert, hatte keinen Einfluss, die selbe 
Fehlermeldung.

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

Bewertung
0 lesenswert
nicht lesenswert
Lea Weiss schrieb:
> ist nicht volatile..

Dann solltest du die ganz schnell volatile machen. Genauso wie alle 
anderen Variablen, die sowohl in der ISR als auch in main() benutzt 
werden. Und eine Absicherung auf atomaren Zugriff wäre auch dringend 
angeraten. Vor allen Dingen dann, wenn du darauf bestehst alles in float 
zu lassen.

Autor: Lea Weiss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger, sie haben recht, wenn ich die Log funktion 
ausklammere kommt die Fehlermeldung nicht...

aber ich kann auf diese Funktion leider nicht verzichten...

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

Bewertung
0 lesenswert
nicht lesenswert
Es ist irgendein Problem in deiner Konfiguration.
Die libm.a sagst du hast du beim Projekt dabei.

Hmm.
Dein WinAVR ist schon reichlich angestaubt. Nimm mal eine andere 
Version.

Autor: Guest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Frage am Rande: wie oft wird der Timer0-Interrupt aufgerufen? Ich 
werde aus
> Initialize_Timer0(2,2,256);
nicht schlau ...

Unabhängig vom Compilier-Fehler: In einer ISR fasst man sich kurz. Hier 
solltest du nur die Messwerte der Sensoren einlesen und sie dann im 
Hauptprogramm bearbeiten.
Gerade Floating Point Berechnungen brauchen viel Zeit ... (und die hat 
man in einer ISR normalerweise nicht.)

Autor: Lea Weiss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
libm.a??
sry bin halt kein Profi, ich hol mir mal die neuste version des winavr 
und schau ob das was bringt..

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

Bewertung
0 lesenswert
nicht lesenswert
Spielt kaum eine Rolle. Dieser PID Regler wird, wenn überhaupt, nur 
durch Zufall funktionieren.
Das ist wie wenn du einem 100-m Sprinter einen Betonklotz ans Bein 
bindest. Der kommt auch nicht weit.

Autor: Lea Weiss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
der timer interrupt wird alle 131ms aufgerufen

Initialize_Timer0(2,2,256);// phasecorrectmode(2), set upcounting(2), 
prescaler(256)

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

Bewertung
0 lesenswert
nicht lesenswert
Lea Weiss schrieb:
> libm.a??

Ich habs dir doch weiter oben aufgeschrieben
Beitrag "Re: Float to Int?"

Autor: Lea Weiss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
soso, wie würdest du es denn machen?

bisher hats nicht so schlecht funktioniert ;)

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

Bewertung
0 lesenswert
nicht lesenswert
Lea Weiss schrieb:
> soso, wie würdest du es denn machen?

Auf jeden Fall nicht mit float

> bisher hats nicht so schlecht funktioniert ;)

Ach. Ich dachte du konntest es bisher noch gar nicht linken.-)

Autor: Lea Weiss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ach scheisse, das hab ich gar nicht gesehen... du bist ein Held, es war 
tatsächlich wegen dem...

danke dir viel mal...!!!! danke danke danke

Autor: Lea Weiss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
verdammt, von wo weisst du das eigentlich alles??? :)

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

Bewertung
0 lesenswert
nicht lesenswert
Du bist nicht die erste mit so einer (oder so einer ähnlichen) 
Fehlermeldung :-)

Autor: Lea Weiss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
voll nett echt, da hast du mir viel Ärger ersparrt ;)

wünsche dir ein schönes WE

tschüss

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist bei der Fehlermmeldung eigentlich eindeutig. Wenn der Linker 
versucht Fließkommaroutinen (wie log) aus der libc.a zu benutzen, fehlt 
immer die libm.a. Entweder weil sie nicht mit angegeben wurde oder wenn 
doch, dann aber an der falschen Stelle.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:

> In function `log':
> (.text.fplib+0x46): relocation truncated to fit: R_AVR_13_PCREL against
> symbol `__addsf3' defined in .text section in
> c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/avr5\libgcc.a(_addsub_sf.o)

Das Problem ist also, daß bestimmte Relocs nicht passen, weil Offsets 
für PC-relative Adressierung zu groß werden. Irgendwer ruft da die 
__addsf3 auf, und das kann eigentlich nur avr-gcc sein, weil die 
__addsf3 zur libgcc gehört. Möglicherweise kann der Linker das 
ausbügeln, wenn man ihn Sprünge relaxen lässt.

Daß das Problem (zunächst) verschwindet, wenn man das Programm kleiner 
macht, hat nix zu sagen. Dadurch passt die Adresslage wieder, weil dann 
anders lokatiert wird. Irgendwann hat man das Ding aber wieder am 
Schenkel kleben...

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.