Forum: Mikrocontroller und Digitale Elektronik ATTiny13: PORTB-Zuweisung funktioniert nicht wie gewünscht.


von Thomas (Gast)


Lesenswert?

ATTiny13, Studio 7, keine Optimierung(-O0)

Die IF-Anweisungen sind wahr und die Zuweisungen werden ausgeführt, aber 
PORTB bleibt auf 0x00.

Warum ist das so?
1
#include <avr/io.h>
2
#include <stdfix.h>
3
4
int main(void)
5
{
6
  short _Fract fx1 = 0.9;
7
  short _Fract fx2 = 0.7;
8
  short _Fract fx;
9
10
  fx = fx1 * fx2;
11
  
12
  if (fx > 0.5)
13
  {
14
    PORTB = (uint8_t)fx;
15
  }
16
  
17
  fx = fx + 0.1;
18
  
19
  if (fx > 0.6)
20
  {
21
    PORTB = (uint8_t)fx;
22
  }
23
}

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

0,9 * 0,7 ergibt 0,63. Dann 0,1 addiert ergibt
0,73. In eine int verwandelt wird das 0 ...

von Karl M. (Gast)


Lesenswert?

Hallo,

zu was, wird eine float 0.5 nach short umgewandelt?

von Carl D. (jcw2)


Lesenswert?

Bist du sicher daß _Fract gemischt mit double (die Konstanten im if) gut 
funktioniert? Generierten Code begutachtet?

von g457 (Gast)


Lesenswert?

> 0,9 * 0,7 ergibt 0,63.

Nein, fx1 und fx2 und fx sind alle 0.

von M. K. (sylaina)


Lesenswert?

Joachim D. schrieb:
> 0,9 * 0,7 ergibt 0,63. Dann 0,1 addiert ergibt

Im Grund richtig erklärt aber der TE schrieb u.a.
1
short _Fract fx1 = 0.9;

und da bleibt schon fx1 doch gleich 0 weil auch short ein Integer-Typ 
ist und der hats nicht so mit dem was hinterm Komma steht.

von Stefan F. (Gast)


Lesenswert?

Da musste ich gerade erst einmal googeln, was "short" überhaupt für ein 
Datentyp ist. In 30 Jahren habe ich den noch nie gesehen - was für mich 
schon ein ganz großer Wink mit dem Zaunpfahl ist.

short ist ein also ein Integer mit mindestens 16 Bits.

Ich bin ziemlich sicher, dass man besser mit exakten Größen arbeiten 
sollte. In diesem Fall also uint16_t. Dann ist auch klar, was dabei 
heraus kommt und es ist offensichtlich, dass man darin keine 
Fließkommazahlen speichern kann.

Bei plattform-unabhängigen Code sind noch die fast_xxx Typen 
interessant. Da gibt man die mindeste Größe an die man braucht, und der 
Compiler nimmt ggf. was größeres, wenn der Prozessor damit schneller 
umgehen kann.

von Carl D. (jcw2)


Lesenswert?

Scheinbar werden _Fract Literale z.B. "0.5k" geschrieben.
Die Literale sind das Problem, die stehen bisher im "double" Format im 
Programm. Also:
1
short _Fract fx1 = 0.9k;

von M. K. (sylaina)


Lesenswert?

Stefan U. schrieb:
> Da musste ich gerade erst einmal googeln, was "short" überhaupt für ein
> Datentyp ist. In 30 Jahren habe ich den noch nie gesehen - was für mich
> schon ein ganz großer Wink mit dem Zaunpfahl ist.

Auf jeden Fall, wer mit C unterwegs ist sollte schon wissen was ein 
short ist ;)
Ist dir das echt noch nie bei C untergekommen? Ich hab das noch vor z.B. 
int8_t gesehen und ich bin auch fast 30 Jahre dabei.

von Carl D. (jcw2)


Lesenswert?

Es muß r statt k heißen:

 Scheinbar werden _Fract Literale z.B. "0.5r" geschrieben.
 Die Literale sind das Problem, die stehen bisher im "double" Format im
 Programm. Also:
1
short _Fract fx1 = 0.9r;

von sönke (Gast)


Lesenswert?

Thomas schrieb:
> Die IF-Anweisungen sind wahr und die Zuweisungen werden ausgeführt, aber
> PORTB bleibt auf 0x00.
>
> Warum ist das so?

Weil vor der Zuweisung zum PORTB (uint8_t)fx gleich 0 ist. Wenn du das 
dem PORTB zuweist bleibt er halt auf null.

von Carl D. (jcw2)


Lesenswert?

M. K. schrieb:
> Stefan U. schrieb:
>> Da musste ich gerade erst einmal googeln, was "short" überhaupt für ein
>> Datentyp ist. In 30 Jahren habe ich den noch nie gesehen - was für mich
>> schon ein ganz großer Wink mit dem Zaunpfahl ist.
>
> Auf jeden Fall, wer mit C unterwegs ist sollte schon wissen was ein
> short ist ;)
> Ist dir das echt noch nie bei C untergekommen? Ich hab das noch vor z.B.
> int8_t gesehen und ich bin auch fast 30 Jahre dabei.

"short (int)" und "short _Fract" sind ganz unterschiedliche Datentypen.
Gemeinsam haben sie nur, daß sie die jeweils kurze Version ihrer Art 
sind.

von Jim M. (turboj)


Lesenswert?

Ich sehe kein DDRB im Code - Port B Pins sind dann AFAIK alle Inputs.

Bei allen
1
PORTB = (uint8_t)fx;

.. ist fx jeweils kleiner als 1 und damit PortB immer 0 (Null). C rundet 
nicht, es truncated. Wollte man runden muss man die für _Frakt 
zuständige Funktion aufrufen.

von Thomas (Gast)


Lesenswert?

Jim M. schrieb:

> Bei allen
>
1
> PORTB = (uint8_t)fx;
2
>
>
> .. ist fx jeweils kleiner als 1 und damit PortB immer 0 (Null). C rundet
> nicht, es truncated.

So ist es. Danke für deinen Hinweis.

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.