Int mit float multiplizieren

Gast #3073491
Hey ich möchte per µC (ATMega 64) eine Frequenz Messen. Ich arbeite mit 
AVR Studio 4.

Meine Idee war es ich starte per Flanke an einem Port Pin einen 8-Bit 
Timer der bei überlauf per Interrupt eine Variable hochzählt. Bei der 
nächsten Flanke soll der Timer gestoppt werden. (Ich weis ihr würdet das 
bestimmt anders lösen aber das ist auch erstmal nicht das Problem). 
Anschließend reche ich mir den gesamten Timerwert aus und speicher den 
Wert in einer INT Variable. Diese will ich anschließend mit einer Float 
multiplizieren und wieder in eine Float abspeichern. Und da liegt das 
Probelm bei der Simulation springt er da komplet aus dem Programm raus. 
Habt ihr eine erklärung wieso?



1
float CPUT=0.0000000625;
2
int T0OF=0;
3
float periodendauer=0.0;
4
int freq=0;
5

6
int main(void)
7
{
8
reg_init();        //Initialisierung von den Registern
9
port_config();      //Ports konfigurieren
10
sei();           //Globale Interrupt Enable
11
char string[8]="0";
12

13

14
while(1)
15
{
16

17

18
/*Vorheriger Code wurd ausgeschnitten. Funktion wurde einzeln geprüft und erwiesen keine Fehler*/
19

20

21
T0OF=8000;//Beispielwert für den gesamten Timerwert
22

23
periodendauer=T0OF*CPUT;/*<<<--- An dieser Stelle verlässt die Simulation das Programm*/
24
freq=1/periodendauer;
25

26

27
/*weiterer unkritischer Code zum senden eines Strings per RS232*/
28

29
T0OF=0;
30
freq=0;
31

32
}
33

34
return 0;
35
}



Ich hoffe ihr habt einen Rat für mich. Bitte bezieht euch auf das 
Problem. Dankeschön Grüße
Gast
Naja eigenklich würde er dan druch fehler rausspringen da division durch 
0 nicht möglich ist. Aber er spring ja schon vorherraus und 
8000*0.0000000625 ist doch nicht 0 von daher sollte das doch bei diesem 
Beispeil kein Problem sein oder? ansonsten geb ich periodendauer gern 
einen Wert vor.
Gast
moin moin,

eventuell ist float ein Problem.

Einfach mal
periodendauer=TOOF* 1E6 / 16
rechnen lassen.

>>freq=1/periodendauer;
das wird bestimmt auch nicht.

MfG
Pieter
Gast
Hey danke für dne Tipp.

Die kleinste Frequenz ist ca 2kHz. Der Timer der eine Taktfreqeunz von 
16Mhz hat würde dan einen maximalen Timerwert von 8000 haben.

1/16.000.000=0.0000000625

1/2.000=0.0005

0.0005/0.0000000625=8000

Richtig?

Wenn ich dan weiterrechne mit der Formel von Pieter erhalte ich

8000*1.000.000/16=500.000.000

Aber was dann? Ich muss doch irgentwo über ein 1/ gehen um eine Frequenz 
daraus zu erhalten oder? Wie schließe ich aus den 500.000.000 wieder 
zurück auf 2.000Hz?
Gast
Steel bei deinen 2 Rechnungen spring er auch direkt raus.
1
  T0OF=8000;
2
  
3
  periodendauer=T0OF*1E6/16;
4
  zwischens=periodendauer/1E12;
5
  freq=1/zwischens;

periodendauer wird wie in der rechnung auf 500.000.000 und auch 
zwischens geht nach derrechnugn auf die 0.0005

aber bei freq=1/0.0005 spchreibt er mir immer eine 1 in freq rein
Gast
@ Ralf
Math lib ist verlinkt und es ergibt trozdem bei der Rechnung 
freq=1/zwischens immer noch 1


@Christopher
1
float CPUT=16e6; // 1/0.0000000625;
2
freq = CPUT/T0OF;


freq=CPUT/T0OF was soll mir das genau bringen?

0.0000000625/8000 dadurch komme ich auch nicht auf die Frequenz oder hab 
ich iwo ein Denkfehler?


Aber nein die Periodendauer wird auch nur als Zwischenschritt benötigt 
und wird nicht weiter verwendet.
Gast
Das Programm/Die Umrechung läuft jetzt. Danke für euche Hilfe. Ich werde 
dne COntroller mal anschließen und schaun ob der vernümpftig arbeitet. 
Fals es doch noch was gibt werdet ihr villeicht nochmal von mir hören :) 
Danke
Gast
@ Ralf
Bei mir leider nicht ich weis nicht woran es liegt.

Aber die andere Version funktioniert ja jetzt.

Jetzt habe ich aber das Problem das der Messwert einfach nicht stimmt 
und der COntroller nur Müll ruaswirft.

Ich warte auf die Flanke an dem Pin und starte darauf hin den 8 Bit 
Timer. Wenn die nächste Flanke kommt Stoppe ich den wieder und werte den 
Gesamten Timerstand aus. Das passt aber garnicht die Wert im 
Hyperterminal springne hin und er und sind nicht stabil. Hier mal der 
Code bitte macht mich nicht fertig man das so nicht macht ^^ bin noch 
relativer Anfänger.
1
int main(void)
2
{
3
  reg_init();        //Initialisierung von den Registern
4
  port_config();      //Ports konfigurieren
5
  sei();           //Globale Interrupt Enable
6
  char string[10]="0";
7

8

9
  while(1)
10
  {
11
    TCNT0=0;
12
    T0OF=0;
13
    freq=0;
14
    _delay_ms(1000);
15
    while(PINA>0);
16
    while(PINA==0);
17
    
18
    TCCR0=0x01;//Timer mit CPU Takt starten
19

20
    while(PINA>0);
21
    while(PINA==0);
22
    TCCR0=0x00;//Timer stoppen
23
  
24
    T0OF=T0OF*255;
25
    T0OF=T0OF+TCNT0;
26

27
    freq=16E6/T0OF;
28

29
    zt=freq/10000;
30
    freq=freq%10000;
31

32
    t=freq/1000;
33
    freq=freq%1000;
34

35
    h=freq/100;
36
    freq=freq%100;
37

38
    z=freq/10;
39
    freq=freq%10;
40

41
    e=freq;
42

43
    /*Anpassung an die ASCII Tabelle*/
44
    zt=zt+0x30;
45
    t=t+0x30;
46
    h=h+0x30;
47
    z=z+0x30;
48
    e=e+0x30;
49

50
    /*Werte in einen String schreiben*/
51
    string[0]=zt;
52
    string[1]=t;
53
    string[2]=h;
54
    string[3]=z;
55
    string[4]=e;
56
    string[5]=' ';
57
    string[6]='H';
58
    string[7]='z';
59
    string[8]=0x0A;;
60
    string[9]=0x0D;
61

62
    /*Stringlaenge auslesen und String senden*/
63
    stringlaenge=sizeof(string);
64
    string_senden(string);
65

66
  
67
  }
68

69
  return 0;
70
}


Das Senden des Strings funktioniert. Das benutze ich auch schon seit ein 
paar Programmen.

Meine Frequenzmessung muss nicht auf 1 Hz genau sein. 10 Hz würden 
locker reichen.

Wie gesagt die Erfassung ist warscheinlich totaler Müll mir ist aber in 
dem Moment nix besseres eingefallen.
Gast
Guten Morgen. Hab es gestern nicht mehr geschafft etas auszuprobieren

@Jim Meba
volatile int T0OF

funktioniert auch nicht. Im Hyperterminal wirft er irgentwelche Zahlen 
zwischen 0Hz und ca. 65000 Hz. Wenn der ausgegebene Wert wenigstens 
stabil wäre könnte es ein Rechenfehler sein. Der springt aber immer 
lustig hin und her. Mal 900Hz mal 22054Hz und dan auch ma wieder 
64000Hz.

Lieg wahrscheinlich an meiner Erfassung.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 13 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.