Timeout bei serieller abfrage

Gast #5169774
Lesenswert?

Moin

Folgender Quelltext fragt eien AD Wandler ab. Nun ist aber das Problem 
das es immer mal wieder zu kommunikationsfehlern kommt bzw. der AD 
Wandler nicht angeschlossen ist. In diesem Fall hängt die Routine sich 
auf.

Ich suche eine Lösung um nach ca. 2 sec. ohne Antwort die Messung 
abzubrechen.

Da während der Messung die Interupts deaktiviert sind fällt der Timer 
interrupt leider aus.

Kennt jemand eine andere/bessere Lösung ?
1
uint32_t messung(uint8_t ch)
2
{
3
    cli();
4
    uint8_t   address_w=0b11010000;
5
    uint8_t   address_r=0b11010001;
6

7
    uint8_t LowByte;
8
    uint8_t HighByte;
9

10
    uint32_t out;
11

12
    _delay_ms(100);
13

14
    //OSR Register setzen
15

16
    // send START condition
17
    TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
18
    while(!(TWCR & (1<<TWINT)));
19
    // send device address
20
    TWDR = address_w;
21
    TWCR = (1<<TWINT)| (1<<TWEN);
22
    while(!(TWCR & (1<<TWINT)));
23
    // send data
24
    switch (ch)
25
        {
26
        case 1:
27
            TWDR = 0x88;
28
            break;
29
        case 2:
30
            TWDR = 0xA8;
31
            break;
32
        case 3:
33
            TWDR = 0xC8;
34
            break;
35
        case 4:
36
            TWDR = 0xE8;
37
            break;
38
        }
39
    TWCR = (1<<TWINT) | (1<<TWEN);
40
    while(!(TWCR & (1<<TWINT)));
41
    TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); //Stop
42
    while((TWCR & (1<<TWINT)));
43
    // send START condition
44
    TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
45
    while(!(TWCR & (1<<TWINT)));
46
    // send device address
47
    TWDR = address_r;
48
    TWCR = (1<<TWINT) | (1<<TWEN);
49
    while(!(TWCR & (1<<TWINT)));
50
    TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);  //Read and acknowledge
51
    while(!(TWCR & (1<<TWINT)));
52
    HighByte=TWDR;
53
    TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);  //Read and acknowledge
54
    while(!(TWCR & (1<<TWINT)));
55
    LowByte=TWDR;
56
    out = ( HighByte << 8 ) | LowByte;
57
    TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); //Stop
58
    while((TWCR & (1<<TWINT)));
59
    sei();
60
    return out;
61
    //     return 23000;
62
}
Gast #5169789
Lesenswert?

Hallo,

wenn man so etwas schreibt,
1
_delay_ms(100);
 , dann stimmt grundsätzlich etwas nicht.

Man könnte raten, es ist ein Atmel AVR µC ?
Warum werden die Interrupts abgeschaltet? Ist irgendwie sinnlos.
Warum wird der I2C / TWI "kram" nicht funktional verpackt ?
Das sind i.a. Funktionen und Proceduren.
Und dies erhöht merklich die Lesbarkeit und Wartbarkeit des Codes.
Gast #5169794
Lesenswert?

Oder man lässt eine  Timer mit 1ms Auflösung als Systemzeit mitlaufen.
Im Programm: Merkt sich vor dem kritischen Abschnitt die Zeitmarke und 
bildet darin immer die Differenz zur aktuellen Systemzeit.
Ist das Timeout [ms] überschritten, so erfolgt die Fehlerbearbeitung.

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