Fehler in wait-funktion

Gast #4127367
Lesenswert?

hi,
ich möchte eine wait-funktion in c mit einem Timer erstellen.
dazu habe ihc es wie folgt gemacht
1
...
2
#define wait_flag = 0x00;
3
...
4

5
void wait(unsigned int count);
6
void Timer1_Init(void);
7
void __attribute__((interrupt, no_auto_psv)) _T1Interrupt(void);
8
...
9

10
int main (void){
11
...
12
  ADPCFGbits.PCFG0 = 1;
13
  TRISBbits.TRISB0 = 0;
14
  LATBbits.LATB0 = 0;
15
...
16
  while(1){
17
    LATBbits.LATB0 = !LATBbits.LATB0;
18
    wait(200);
19
  }
20
}
21

22
void wait(unsigned int count)
23
{
24
    unsigned int countzahl;
25
    wait_flag = 1;
26
    countzahl = count/(0,00000006781684027777780*256*1000);
27
    PR1 = countzahl;
28
    TMR1 = 0;           // set timer to 0
29
    T1CONbits.TON = 1;
30
    while(wait_flag!=0){ }
31
}
32

33
{
34
    // PR1 and TCKPS are set to call interrupt every 1000ms.´
35
    // Period = PR1 * prescaler * Tcy = 57600 * 256 * 67ns = 1000ms
36
    T1CONbits.TON = 0;    // Clear Timer 1 configuration
37
    T1CONbits.TCKPS = 3;  // Set timer 1 prescaler (0=1:1, 1=1:8, 2=1:64, 3=1:256)
38
    T1CONbits.TSYNC = 1;  // Synchronize external clock input (1: Synchronize, 0: Do not synchronize)
39
    T1CONbits.TCS = 0;    // Timer Clock Source bit (1: External clock from pin TxCK, 0: Internal clock (Fosc/4))
40
    //PR1 = 57600/2;         // Set Timer 1 period (max value is 65535 (16 bit))  -> has to be set to 576 (10ms)
41
    IPC0bits.T1IP = 1;    // Set Timer 1 interrupt priority
42
    IFS0bits.T1IF = 0;    // Clear Timer 1 interrupt flag
43
    IEC0bits.T1IE = 1;    // Enable Timer 1 interrupt
44
    //T1CONbits.TON = 1;    // Turn on Timer 1 // made in _C1Interrupt(void)
45
}
46

47
void __attribute__((interrupt, no_auto_psv)) _T1Interrupt(void)
48
{
49
    wait_flag = 0;
50
    T1CONbits.TON = 0;  // stopts timer
51
    IFS0bits.T1IF = 0;  // Clear Timer 1 interrupt flag
52
}

aber er gibt mir den Fehler

Main.c: In function 'wait':
Main.c:84:5: error: lvalue required as left operand of assignment
Main.c:85:26: error: invalid digit "8" in octal constant
Main.c:85:25: warning: left-hand operand of comma expression has no 
effect
Main.c: In function '_T1Interrupt':
Main.c:111:5: error: lvalue required as left operand of assignment
make[2]: *** [build/default/production/Main.o] Error 255
make[2]: *** Waiting for unfinished jobs....
nbproject/Makefile-default.mk:101: recipe for target 
'build/default/production/Main.o' failed
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2

was ist daran falsch? bzw. was bedeutet die Fehlermeldung?
(Firma: Schweigstill IT) Persönliche Seite #4127390
Lesenswert?

Fehlerhafter Ausdruck:
1
countzahl = count/(0,00000006781684027777780*256*1000);

Korrekter Ausdruck:
1
countzahl = count/(0.00000006781684027777780*256*1000);

Inwiefern dieser Ausdruck überhaupt sinnvoll ist, steht noch zur 
Diskussion. Um zumindest weitere Rundungsfehler bei der Vorberechnung 
des Divisors zu reduzieren, kann es sinnvoll sein, die Ganzzahlfaktoren 
auch noch in Fließkommazahlen zu wandeln:
1
countzahl = count/(0.00000006781684027777780*256.0*1000.0);
(Firma: Torrox.de) #4127396
Lesenswert?

Zeile 84:
1
wait_flag = 1;

wait_flag hast Du als Makro definiert und löst zu 0x00 auf, da steht 
also:
1
0x00 = 1;


Zeile 85:
1
(0,00000006781684027777780*256*1000);

Ist ein Ausdruck mit Komma-Operator. Der rechte Operant ist ein oktal 
kodiertes Literal (wegen der führenden 0) und in oktal-Zahlen gibt es 
die Ziffer 8 nicht. Wahrscheinlich meinst Du 0.000...

mfg Torsten
Moderator (Firma: Titel) Persönliche Seite #4127408
Lesenswert?

Christian schrieb:
> bzw. was bedeutet die Fehlermeldung?
Die Ursache ist, dass ein Integerwert, der mit einer 0 beginnt, als 
Oktalzahl interpretiert wird.
Es ist z.B. eine schlechte Idee, aus Gründen der bessern Lesbarkeit 
sowas zu schreiben:
1
a = 2345;
2
b = 1234;
3
c = 0123;
4
d = 0012;
5
e = 0001;
c und d werden hier unerwarete Werte enthalten: c == 83 bzw. d == 8

Fazit:
00000006781684027777780
Du hast Glück, dass deine Zahl eine 8 enthält...


Christian schrieb:
> TMR1 = 0;           // set timer to 0
Das ist eine Idee, die in die Sackgasse führt. Denn damit lässt sich 
dieser Timer für nichts Anderes mehr verwenden. Ausserdem ist explizites 
Warten sowieso nur Rechenzeitvergeudung...
Gast #4127411
Lesenswert?

Andreas Schweigstill schrieb:
> countzahl = count/(0.00000006781684027777780*256.0*1000.0);

Oder man spart sich diesen Moloch und rechnet:
> countzahl = count * 57.6;

Ganz davon ab finde ich Magic Number sehr unschön, weil sie die 
Wartbarkeit des Codes erschweren.

Also lieber:
1
#define MAGIC_CONSTANT1    (0.00000006781684027777780)
2
#define MAGIC_CONSTANT2    (256)
3
#define MAGIC_CONSTANT3    (1000)
4
#define VERY_MAGIC_CONSTANT (MAGIC_CONSTANT1 * MAGIC_CONSTANT2 * MAGIC_CONSTANT3)
5

6
...
7
countzahl = count * VERY_MAGIC_CONSTANT;

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren