Forum: Mikrocontroller und Digitale Elektronik Fehler in wait-funktion


von Christian (Gast)


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?

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


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);

von Max (Gast)


Lesenswert?

Christian schrieb:
> 0,00000006781684027777780

sollte 0.00000006781684027777780 (Punkt statt komma) sein.
Falls noch mehr spaß rauskommt: mehr detials erzählen

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


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

von Christian (Gast)


Lesenswert?

mhh,
ein bisschen schäme ich mich.
mit zeile 85 war copy paste. damn

danke euch

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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...

von Alpenmatrose (Gast)


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;

von Alpenmatrose (Gast)


Lesenswert?

Nachtrag: Da bin ich jetzt natürlich durcheinander gekommen, bei Nutzung 
der Defines wie von mir angegeben muss es natürlich wieder lauten
1
countzahl = count / VERY_MAGIC_CONSTANT;

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.