Forum: Mikrocontroller und Digitale Elektronik Timeout bei serieller abfrage


von Klaus (Gast)


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
}

von Karl M. (Gast)


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.

von grundschüler (Gast)


Lesenswert?

hängt dann wohl in einer while-Schleife:
1
u32 downtimer=200000;
2
    while((TWCR & (1<<TWINT)) && downtimer)downtimer--;
3
if (!downtimer)return;

von Karl M. (Gast)


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.

von Peter D. (peda)


Lesenswert?

Klaus schrieb:
> In diesem Fall hängt die Routine sich
> auf.

Du mußt natürlich nach jedem I2C-Kommando den Status auswerten. Z.B. 
nach einem NACK kannst Du kein weiteres Byte mehr senden.

von Sascha W. (sascha-w)


Lesenswert?

Klaus schrieb:
> Da während der Messung die Interupts deaktiviert sind fällt der Timer
> interrupt leider aus.
Wenn die Wandlung in einem externen AD-Wandler stattfindet verstehe ich 
nicht warum du auf dem μC währenddessen keine Interrupts haben willst.

Sascha

von Klaus (Gast)


Lesenswert?

grundschüler schrieb:
> u32 downtimer=200000;
>     while((TWCR & (1<<TWINT)) && downtimer)downtimer--;
> if (!downtimer)return;

Danke !! Das wars was mir gefehlt hat.

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.