Forum: Mikrocontroller und Digitale Elektronik C18 Berechnungen


von Andreas R. (blackpuma)


Lesenswert?

Guten Abend!

Ich habe heute 2 Fragen:

Ich habe folgende Formel: ( 5000000/48000000 ) * 0xFFFFFFFF.

Wie kann ich diese in C18 umsetzten? Ich weiß nicht was passiert wenn 
ich eine Division im uC rechne bei der eine Kommazahl raus kommt. Das 
Ergebnis wird an einen AD9834 übertragen. Was mich auch gleich zu meiner 
zweiten Frage bringt.

Wie kann ich das Ergebnis in 4 Variablen teilen um es mit SPI an meinen 
Chip übertragen zu können?

Danke schon mal
Andreas

von Anja (Gast)


Lesenswert?

Andreas Riegebauer schrieb:
> Ich habe folgende Formel: ( 5000000/48000000 ) * 0xFFFFFFFF.

kann man auch einfacher schreiben  0 * 0xFFFFFFFF.
Die Division wird zu "0" abgerundet.

Ich würde wie folgt schreiben: (eventuell noch Rundungsoffset addieren)

(int64_t) 5000000 * (int64_t) 0xFFFFFFFF / 48000000

Das zerlegen in Bytes geht dann mit byte-pointer oder variantem record

Gruß Anja

von Andreas R. (blackpuma)


Lesenswert?

Also ich habe für das erste Problem eine Lösung gefunden.
Eine kurze Erklärung dazu:
Die Division von 0xFFFFFFFF / 48000000 ist ja ein Konstanter Wert. Den 
habe ich in 5 Teile zerlegt. Jeder einzelne Teil wird mit der 
eingestellten Frequenz multipliziert. Dann werden die einzelnen Werte 
dividiert um das Komma zu setzten. Jetzt noch addieren und fertig.
1
void set_new_frequ( void )
2
{
3
unsigned double f1 = 89, f2 = 47, f3 = 84, f4 = 85, f5 = 31, fges = 0;
4
5
// Umrechnen der Frequenz
6
f1 *= frequ;
7
f2 *= frequ;
8
f3 *= frequ;
9
f4 *= frequ;
10
f5 *= frequ;
11
12
f2 /= 100;
13
f3 /= 10000;
14
f4 /= 1000000;
15
f5 /= 100000000;
16
17
fges = f1 + f2 + f3 + f4 + f5;
18
19
Frequenz._word = fges;
20
}


Mein zweites Problem habe ich noch. Ich habe mit union was gebaut 
allerdings bekomme ich nicht das richtige heraus.
1
typedef unsigned char      byte;           // 8-bit
2
typedef unsigned double    word;           // 16-bit
3
4
union _WORD
5
{
6
    word _word;
7
    struct
8
    {
9
        byte HMSB;
10
    byte LMSB;
11
    byte HLSB;
12
        byte LLSB;
13
    };
14
} Frequenz;

Ausgelesen werden die Werte so:
1
.
2
.
3
Frequenz._word = fges;
4
.
5
.
6
WriteSPI( Frequenz.HMSB );
7
// Write other 8 Frequency bits to Register 88 L MSB
8
WriteSPI( 0x22 );
9
WriteSPI( Frequenz.LMSB );
10
// Write other 8 Frequency bits to Register 88 H LSB
11
WriteSPI( 0x31 );
12
WriteSPI( Frequenz.HLSB );
13
// Write other 8 Frequency bits to Register 40 L LSB
14
WriteSPI( 0x20 );
15
WriteSPI( Frequenz.LLSB );
16
.
17
.

Leider bekomme ich nicht die richtigen Werte heraus. Mit einer 
Testfrequenz von 12630 Hz steht in der Variable bzw. dem union 1130113 
dez drinnen. das bedeutet es sollte in den Bytes doch 0x00, 0x11, 0x3E 
und 0x81 stehen. Leider kommt dort aber irgendwas heraus.

Könnt ihr das bitte durchsehen und mir sagen was da nicht funktioniert?

BG
Andreas

von Andreas R. (blackpuma)


Lesenswert?

Guten Abend!

ich habe die Lösung gefunden. Es waren 2 Probleme. Einmal waren die Bits 
in der falschen Reihenfolge geschrieben und dann habe ich double durch 
long int ersetzt. Kann mir jemand erklären wieso das mit long int 
funktioniert und mit double nicht?
1
typedef unsigned char      byte;           // 8-bit
2
typedef unsigned long int    word;           // 16-bit
3
4
union _WORD
5
{
6
    word _word;
7
    struct
8
    {
9
        byte LLSB;
10
        byte LMSB;
11
        byte LMSB;
12
        byte HMSB;
13
    };
14
} Frequenz;

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.