Timeout bei serieller abfrage

Gast #5169774
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
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
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

Eine eigene Frage? Dieser Thread ist über 9 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.