Forum: Mikrocontroller und Digitale Elektronik "Berechnungsfunktion" liefert immer 0


von Miau (Gast)


Lesenswert?

Moin,
1
int32_t calculatedCurrentValue(int16_t data, int16_t senseResistor)
2
{
3
  int32_t tempData = data;
4
  tempData = ((tempData*1562)/senseResistor);
5
  return tempData;
6
}
In data steht 33 drin.

In senseResistor steht 100 drin.

Aufgerufen wirds so:
1
int32_t test;
2
test= calculatedCurrentValue(34,100);
3
lcd_setcursor(0,2);
4
sprintf(buffer,"%16d",test);
5
lcd_string( buffer );

Liefert immer 0 :(

Seltsam ist, ich bekomme den richtigen Wert (531) wenn ich die Funktion 
mit int16_t verwende...
also: int16_t calculatedCurrentValue(int16_t data, int16_t 
senseResistor)

Da meine Werte aber sehr groß werden können brauch ich das als 
int32_t....

Verwende Atmel Studio 6.2 und der uC ist der ATMEGA644PA.

von Peter II (Gast)


Lesenswert?

%d steht für int

wenn du 32bit nimmst, ist das kein int mehr. versuchst mal mit %l

von Theor (Gast)


Lesenswert?

Suchterm "printf format specifier"

Achtung: Vergleiche int16_t mit Standardtypen int bzw. long.

von Miau (Gast)


Lesenswert?

Moin,

habe probiert:

sprintf(buffer,"%l",test);
sprintf(buffer,"%L",test);

Allerdings wird dann gar nichts mehr ausgegeben.

Muss ich dann noch irgendwas einbinden?
Habe nur das included:

#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <stdio.h>

von Stefan E. (sternst)


Lesenswert?

%ld

von Theor (Gast)


Lesenswert?

Miau schrieb:
> Moin,
>
> habe probiert:

Wir sind hier nicht bei der Weinprobe. ;-)

Statt dessen: Dokumentation lesen und dann gezielt handeln.

von Rolf M. (rmagnus)


Lesenswert?

Theor schrieb:
> Statt dessen: Dokumentation lesen und dann gezielt handeln.

Dann sieht man, dass es eigentlich heißen müsste:
1
  sprintf(buffer,"%16"PRId32,test);

von Miau (Gast)


Lesenswert?

Theor schrieb:
> Suchterm "printf format specifier"

Theor schrieb:
> Miau schrieb:
>> Moin,
>>
>> habe probiert:
>
> Wir sind hier nicht bei der Weinprobe. ;-)
>
> Statt dessen: Dokumentation lesen und dann gezielt handeln.

Ja sorry, mit dem Suchbegriff hab ich das auch gesehen mit %ld.

Lustigerweise...
Liefert immer noch 0.
Nun habe:
sprintf(buffer,"%ld",test);

Muss ich wirklich nicht noch irgendwas einbinden?

Ich meine z.B. wenn ich ja auch floats ausgeben möchte muss man ja für 
sprintf auch irgendwas noch einbinden.

Allerdings bin ich noch voll der Noob.... mir fehlen leider ein paar 
Stichwörter um das rauszufinden...

Habe sogar das ausprobiert:
https://startingelectronics.org/articles/atmel-AVR-8-bit/print-float-atmel-studio-7/

Aber natürlich brachte das auch keine Veränderung... Dachte vielleicht 
hilft es auch bei int32 :D

Rolf M. schrieb:
> Theor schrieb:
>> Statt dessen: Dokumentation lesen und dann gezielt handeln.
>
> Dann sieht man, dass es eigentlich heißen müsste:
>   sprintf(buffer,"%16"PRId32,test);

geht auch nicht :(

von Theor (Gast)


Lesenswert?

Ist der Buffer groß genug?

Bei "%16...." muss er 17 Bytes lang sein.

von Miau (Gast)


Lesenswert?

Theor schrieb:
> Ist der Buffer groß genug?
>
> Bei "%16...." muss er 17 Bytes lang sein.

war die ganze zeit:
char buffer[20];



testweise mal gemacht:
char buffer[100];

mit
sprintf(buffer,"%ld",test);
und
sprintf(buffer,"%16"PRId32,test);

Geht alles nicht :(

Ist es bei mir nicht vllt irendwo ein generelles C Problem?

Das ist meine Main:
1
    while(1)
2
    {
3
    char buffer[100];
4
    lcd_clear();
5
    lcd_home();
6
    int32_t test;
7
    test = calculatedCurrentValue(34,100);
8
    lcd_setcursor(0,2);
9
    sprintf(buffer,"%ld",test);
10
    lcd_string( buffer );
11
    _delay_ms(3500);
12
    }

Das meine Funktion:
1
int32_t calculatedCurrentValue(int16_t data, int16_t senseResistor)
2
{
3
  int32_t tempData = data;
4
  int32_t  tempResistor = senseResistor;
5
  tempData = ((tempData*1562)/tempResistor);
6
  return tempData;
7
}

Sobald die Funktion mit int16_t gemacht wird, geht alles.
Ich weiß ich wiederhole mich, weiß aber nicht was vielleicht noch an 
Infos fehlen...

von Miau (Gast)


Lesenswert?

Update:
Wenn ich das so mache:
1
    
2
while(1)
3
{
4
    char buffer[100];
5
    lcd_clear();
6
    lcd_home();
7
    lcd_setcursor(0,2);
8
    int32_t tempData = 34;
9
    int32_t tempResistor = 100;
10
    tempData = ((tempData*1562)/tempResistor);
11
    sprintf(buffer,"%ld",tempData);
12
    lcd_string( buffer );
13
    _delay_ms(3500);
14
}

Dann gehts....

Es hat irgendwas anscheinend damit zutun:

meine .h
1
#ifndef Calc_H_
2
#define Calc_H_
3
#define F_CPU 20000000UL
4
//int A,B,C,D,E,F,G,H,I,J;
5
6
int32_t calculatedCurrentValue(int16_t data, int16_t senseResistor);
7
#endif /* Calc_H_ */


meine .c
1
#include "DS2740.h"
2
3
int32_t calculatedCurrentValue(int16_t data, int16_t senseResistor)
4
{
5
  int32_t tempData = data;
6
  int32_t  tempResistor = senseResistor;
7
  tempData = ((tempData*1562)/tempResistor);
8
  return tempData;
9
}

von Miau (Gast)


Lesenswert?

Miau schrieb:
> meine .c
> #include "DS2740.h"
>
> int32_t calculatedCurrentValue(int16_t data, int16_t senseResistor)
> {
>   int32_t tempData = data;
>   int32_t  tempResistor = senseResistor;
>   tempData = ((tempData*1562)/tempResistor);
>   return tempData;
> }

Grad alles gekürzt.
Ging natürlich nicht.

Neu gebaut mit #include "Calc.h"

Damit ging es nicht.

Beitrag #4953925 wurde vom Autor gelöscht.
von Theor (Gast)


Lesenswert?

Ja, hast Du denn die H-Datei, in der der Prototyp der Funktion steht, 
auch in main.c eingefügt?

Falls nicht, sollten da eigentlich Warnungen kommen, wenn ich nicht 
irre.

von Miau (Gast)


Lesenswert?

Theor schrieb:
> Ja, hast Du denn die H-Datei, in der der Prototyp der Funktion steht,
> auch in main.c eingefügt?
>
> Falls nicht, sollten da eigentlich Warnungen kommen, wenn ich nicht
> irre.

Es tut mir so leid....

Ja das war es....

Danke an alle...

Peinlich^^

von Ralph S. (jjflash)


Angehängte Dateien:

Lesenswert?

... so, jetzt komme ich "zu spät", ich habe meine Funktionen, die 
eigentlich für einen STM32F030 geschrieben sind für AVR geported, um 
eine große printf - Bibliothek in den Code NICHT einbinden zu müssen.

Der Code funktioniert (hier getestet) mit einem ATmega8, ATmega88, 
ATmega168 und ATmega328p.

Er beinhaltet eine abgespeckte Version eines eigenen printf, die jedoch 
keine floats unterstützt, dafür jedoch eine Ausgabe eines "Pseudokommas" 
(hab ich halt so genannt).

Funktionen sind vor ca. einem 3/4 Jahr unter Mithilfe von 
Forumsmitgliedern entstanden.

Der angefügte Democode beinhaltet zum Testen rudimentäre Ausgaben für 
eine serielle Schnittstelle.

Für eine Ausgabe auf einem LCD muss in der Funktion

my_putchar

die Funktion angegeben sein, mittels der ein Zeichen auf das 
Ausgabegerät ausgegeben wird. In deinem Falle wohl so etwas wie ein 
lcd_putchar (ich weiß nicht wie das bei deinen LCD-Funktionen heißt). In 
diesem Falle können die seriellen Funktionen gelöscht werden.

Vielleicht wird dir ja mal der Speicher knapp und du bindest tiny_printf 
ein.

Nächtlichen Gruß,

Ralph

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.