Forum: Mikrocontroller und Digitale Elektronik 1-Wire/UART/PIC24F


von Kevin Lüttler (Gast)


Lesenswert?

Hallo,

Ich habe die 1-Wire Routinen von Peter Dannegger auf einen PIC24F32KA302 
portiert. Die Bitbanging-Variante funktioniert einwandfrei. Dann habe 
ich die Lowlevel-Routinen Reset & BitIO auf UART umgestellt (TX über 
Diode entkoppelt), was soweit auch funktioniert, aber:
Jegliche Änderungen am Bus (z.B. hinzufügen eines Sensors oder abklemmen 
eines Sensors) bringt die UART-Variante aus dem Tritt und erfordert 
einen Reset (Neustart). Die Bitbanging-Variante war hier robuster. Der 
UART-Code basiert auf den AppNotes von ATMEL, Maxim und natürlich auf 
der Originalroutine von Peter.

Vielleicht fällt jemandem ja der Grund für die "Empfindlichkeit" bzgl. 
Busänderungen auf, ich sehe gerade den Wald vor lauter Bäumen nicht.

1
uint8_t OneWire_Reset()
2
{
3
    uint8_t result = 0;
4
    
5
    // UART mit 9600 Baud initialisieren
6
7
    U2MODEbits.BRGH = 1;        // 16bit Baudrate Generator
8
    U2BRG = 415;                // 9600 Baud bei FOSC 32MHz
9
    U2MODEbits.UEN = 0;         // Keine HW Flusskontrolle
10
    U2MODEbits.UARTEN = 1;      // UART einschalten
11
    U2STAbits.UTXEN = 1;        // UART Transmitter einschalten
12
    
13
    U2TXREG = 0xF0;             // Reset senden
14
15
    while(!U2STAbits.URXDA);    // RX Puffer einlesen
16
    do
17
    {
18
        result = U2RXREG;
19
    } while (U2STAbits.URXDA);
20
       
21
    if ((result & 0xF0) == 0xF0)         // 1Wire: No presence
22
        return 1;
23
    else
24
        return 0;
25
}
26
27
uint8_t OneWire_BitIO(uint8_t b)
28
{
29
    uint8_t result = 0;
30
31
    // UART auf 115200 Baud
32
33
    U2MODEbits.BRGH = 1;        // 16bit Baudrate Generator
34
    U2BRG = 33;                 // 115200 Baud bei FOSC 32MHz
35
    U2MODEbits.UEN = 0;         // Keine HW Flusskontrolle
36
    U2MODEbits.UARTEN = 1;      // UART einschalten
37
    U2STAbits.UTXEN = 1;        // UART Transmitter einschalten
38
39
    if (b)                      // 1 senden
40
    {
41
        U2TXREG = 0xFF;         // 0xFF ist 1 auf Bus
42
        while(!U2STAbits.URXDA);// RX Puffer lesen
43
        do
44
        {
45
            result = U2RXREG;
46
        } while (U2STAbits.URXDA);
47
    }
48
    else
49
    {
50
        U2TXREG = 0x00;         // 0x00 ist 0 auf Bus
51
        while(!U2STAbits.URXDA);// RX Puffer lesen
52
        do
53
        {
54
            result = U2RXREG;
55
        } while (U2STAbits.URXDA);
56
        result = 0;
57
    }
58
59
    if ((result & 0xFF) == 0xFF)         // 0xFF entspricht 1
60
        return 1;
61
    else                        // alles andere 0
62
        return 0;
63
}

von Kevin Lüttler (Gast)


Lesenswert?

Problem gelöst indem der int. FIFO vor dem eigentlichen Senden/Empfangen 
gelöscht wird und ein evtl. aufgetretenes Overrun (durch Störungen auf 
DQ) abgefangen wird (da blockiert dann der FIFO). Falls es jemand 
interessiert oder in 2 Jahren mal danach sucht, Code anbei.
1
uint8_t OneWire_UART(uint16_t brg, uint8_t value)
2
{
3
    while(!U2STAbits.TRMT);     // Warten bis TX Puffer leer
4
5
    while(U2STAbits.URXDA)      // RX Puffer leeren
6
        (void)U2RXREG;          // Inhalt verwerfen
7
8
    if (U2STAbits.OERR)         // Overrun behandeln
9
    {
10
        U2STAbits.OERR = 0;     // OERR löschen
11
    }
12
13
    U2BRG = brg;                // 9600 Baud bei FOSC 32MHz
14
15
    Nop();                      // Kurze Pause nach dem Wechsel der Baudrate
16
    Nop();
17
18
    U2TXREG = value;            // Wert senden
19
    Nop();                      // Einen Zyklus warten bevor das Transmit-Flag. abgefragt wird
20
    while(!U2STAbits.TRMT);     // Warten bis gesendet
21
22
    while(!U2STAbits.URXDA);    // Warten bis etwas im RX Puffer ist
23
24
    return (U2RXREG);
25
}
26
27
uint8_t OneWire_Reset()
28
{
29
    uint8_t result = 0;
30
31
    result = OneWire_UART(LOWSPEED, 0xF0);   // 415 = 9600 Baud
32
33
    if (result == 0xF0)// 1Wire: No presence
34
        return result;
35
    else
36
        return 0;
37
}
38
39
uint8_t OneWire_BitIO(uint8_t b)
40
{
41
    uint8_t result = 0;
42
43
    if (b)                      // 1 senden
44
    {
45
        result = OneWire_UART(HIGHSPEED, 0xFF);
46
    }
47
    else
48
    {
49
        result = OneWire_UART(HIGHSPEED, 0x00);
50
        result = 0;
51
    }
52
53
    if ((result) == 0xFF)       // 0xFF entspricht 1
54
        return 1;
55
    else                        // alles andere 0
56
        return 0;
57
}

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.