Forum: Mikrocontroller und Digitale Elektronik PIC UART fehlerhafte Übertragung


von Lasse01 (Gast)


Lesenswert?

Hallo zusammen,

ich habe hier einen PIC24FV32KA301 mit dem ich Text über UART übertragen 
will.

Den nötigen Code habe ich mir zum größten Teil vom Code Configurator in 
MPLAB X generieren lasse. Ich habe den generierten Code natürchlich auch 
schon selber durch geschaut, aber habe keinen Fehler des Generators 
gefunden.

In der main habe ich dann nur noch diesen einfachen Code.
1
    char buffer[50] = "Hallo-Welt123\n";
2
    
3
    SYSTEM_Initialize();
4
    
5
    __delay_ms(10);
6
    
7
    while(1)
8
    {
9
        UART1_WriteBuffer((const uint8_t*)buffer, strlen(buffer));
10
        __delay_ms(1000);
11
    }
12
    
13
    return 0;

auf dem PC emfange ich aber nur abwechselnd

HalloWl13<\n>
l1lHal-et2<\n>




der Initialisierungs Code des UART sieht so aus
1
#define UART1_CONFIG_TX_BYTEQ_LENGTH 100
2
#define UART1_CONFIG_RX_BYTEQ_LENGTH 100
3
4
static uint8_t uart1_txByteQ[UART1_CONFIG_TX_BYTEQ_LENGTH] ;
5
static uint8_t uart1_rxByteQ[UART1_CONFIG_RX_BYTEQ_LENGTH] ;
6
7
void UART1_Initialize (void)
8
{
9
   // STSEL 1; IREN disabled; PDSEL 8N; UARTEN enabled; RTSMD disabled; USIDL disabled; WAKE disabled; ABAUD disabled; LPBACK disabled; BRGH enabled; RXINV disabled; UEN TX_RX; 
10
   U1MODE = (0x8008 & ~(1<<15));  // disabling UARTEN bit   
11
   // UTXISEL0 TX_ONE_CHAR; UTXINV disabled; OERR NO_ERROR_cleared; URXISEL RX_ONE_CHAR; UTXBRK COMPLETED; UTXEN disabled; ADDEN disabled; 
12
   U1STA = 0x0000;
13
   // BaudRate = 9600; Frequency = 4000000 Hz; BRG 103; 
14
   U1BRG = 0x0067;
15
16
   IEC0bits.U1RXIE = 1;
17
18
    //Make sure to set LAT bit corresponding to TxPin as high before UART initialization
19
   U1MODEbits.UARTEN = 1;  // enabling UART ON bit
20
   U1STAbits.UTXEN = 1;
21
   
22
   
23
24
   uart1_obj.txHead = uart1_txByteQ;
25
   uart1_obj.txTail = uart1_txByteQ;
26
   uart1_obj.rxHead = uart1_rxByteQ;
27
   uart1_obj.rxTail = uart1_rxByteQ;
28
   uart1_obj.rxStatus.s.empty = true;
29
   uart1_obj.txStatus.s.empty = true;
30
   uart1_obj.txStatus.s.full = false;
31
   uart1_obj.rxStatus.s.full = false;
32
}

vielleicht kann mir ja jemand weiter helfen.

von Volker S. (vloki)


Lesenswert?

Ein Oszilloskop hast du wohl nicht gerade zur Hand?
Dann könntest du einfach mal nachschauen, was auf der Leitung...

von Lasse01 (Gast)


Lesenswert?

Nein leider nicht.

von Dieter W. (dds5)


Lesenswert?

Sieht so aus, als ob UART1_WriteBuffer den Hardware-Sendepuffer 
überfährt.

von Volker S. (vloki)


Lesenswert?

Warum fehlt dann jedes zweite Zeichen?
1000ms sollten auch mehr als genug sein.

@lasse01
Kommen die (falschen)  Strings ungefähr im Sekundenrythmus?

von Lasse01 (Gast)


Lesenswert?

Ja, das timing stimmt.

von Volker S. (vloki)


Lesenswert?

Mit was empfängst du die Daten auf dem PC?
Irgendein Terminal (Br@y, TeraTerm, HTerm....) oder was selber 
geschriebenes?

Kann man bei dem PIC24 irgendwie 2 Stopbits einstellen?
Du könntest auch mal testen, was passiert, wenn der Wert für die BAUD 
Rate leicht verändert wird...
(Ohne Oszi ist alles doof ;-)

von waflija (Gast)


Lesenswert?

Volker S. schrieb:
> Mit was empfängst du die Daten auf dem PC?
> Irgendein Terminal (Br@y, TeraTerm, HTerm....) oder was selber
> geschriebenes?
>
> Kann man bei dem PIC24 irgendwie 2 Stopbits einstellen?
> Du könntest auch mal testen, was passiert, wenn der Wert für die BAUD
> Rate leicht verändert wird...
> (Ohne Oszi ist alles doof ;-)

Das wäre auch mein erster Anstatz. Prüfe in jedem Fall mal die 
Verbindungseinstellungen auf beiden Seiten.

->Baudrate korrekt?
->Anzahl Startbits korrekt?
->Anzahl Stoppbits korrekt?
->Parity richtig?
->Wartet eine Seite eventuell auf bestimmte Signale wie Ready-to-recive 
or ähnliches?

Auf Seiten des PIC muss man etwas im Datenblatt wühlen bevor man alles 
zusammen hat. Teilweise stellen die Bibiliotheken von Microchip das dann 
auch als "default" auf andere Werte. Am besten du lässt dir die im 
Debugger / Simulation mal ausgeben, kurz bevor du die Verbindung 
öffnest.

von Lasse01 (Gast)


Lesenswert?

Ich benutze HTerm auf dem PC.

Ja er kann 2 StopBits, bringt leider auch nichts.
Andere Baud-Raten machen auch keinen Unterschied.

von Lasse01 (Gast)


Lesenswert?

Ich habe jetzt mal absichtlich unpassende einstellungen gewählt, einfach 
um zu sehen was passiert.

HTerm:
- 9600 Baud
- 7 Datenbits
- 1 Stopbit
- Odd Parity

PIC:
- 9600 Baud
- 8 Datenbits
- 2 StopBits
- keine Parität

komischer weise ändert das nichts an dem Ergebniss. Ist das normal ?

von waflija (Gast)


Lesenswert?

Lasse01 schrieb:
> Ich habe jetzt mal absichtlich unpassende einstellungen gewählt,
> einfach
> um zu sehen was passiert.
>
> HTerm:
> - 9600 Baud
> - 7 Datenbits
> - 1 Stopbit
> - Odd Parity
>
> PIC:
> - 9600 Baud
> - 8 Datenbits
> - 2 StopBits
> - keine Parität
>
> komischer weise ändert das nichts an dem Ergebniss. Ist das normal ?

Das sollte einiges Ändern. Falsche Anzahl Datenbit und ein weiteres bit 
wird als 1 gliefert und dann als Parität interpretiert. Das müsste jede 
Menge Paritätsfehler produzieren und könnte durchaus deinen Fehler 
erklären.

Versuch im Zweifel mal ein anderes Terminal z.B. Putty.

von Lasse01 (Gast)


Lesenswert?

Ich hab den Fehler gefunden.

Ich konnte mich noch erinnern das es früher immer ohne probleme 
funktioniert hat, also habe ich mal eine ältere Version vom MPLAB X 
CodeConfigurator ausprobiert und siehe da, es geht wieder.

MCC v3.26.2
1
/**
2
    Maintains the driver's transmitter state machine and implements its ISR
3
*/
4
void __attribute__ ( ( interrupt, no_auto_psv ) ) _U1TXInterrupt ( void )
5
{ 
6
    if(uart1_obj.txStatus.s.empty)
7
    {
8
        IEC0bits.U1TXIE = false;
9
        return;
10
    }
11
12
    IFS0bits.U1TXIF = false;
13
14
15
    while(!(U1STAbits.UTXBF == 1)) // <---------
16
    {
17
18
19
        U1TXREG = *uart1_obj.txHead;
20
21
        uart1_obj.txHead++;
22
23
        if(uart1_obj.txHead == (uart1_txByteQ + UART1_CONFIG_TX_BYTEQ_LENGTH))
24
        {
25
            uart1_obj.txHead = uart1_txByteQ;
26
        }
27
28
        uart1_obj.txStatus.s.full = false;
29
30
        if(uart1_obj.txHead == uart1_obj.txTail)
31
        {
32
            uart1_obj.txStatus.s.empty = true;
33
            break;
34
        }
35
    }
36
}

MCC v3.15
1
/**
2
    Maintains the driver's transmitter state machine and implements its ISR
3
*/
4
void __attribute__ ( ( interrupt, no_auto_psv ) ) _U1TXInterrupt ( void )
5
{ 
6
    if(uart1_obj.txStatus.s.empty)
7
    {
8
        IEC0bits.U1TXIE = false;
9
        return;
10
    }
11
12
    IFS0bits.U1TXIF = false;
13
14
    int count = 0;
15
    while((count < UART1_TX_FIFO_LENGTH)&& !(U1STAbits.UTXBF == 1)) // <---------
16
    {
17
        count++;
18
19
        U1TXREG = *uart1_obj.txHead;
20
21
        uart1_obj.txHead++;
22
23
        if(uart1_obj.txHead == (uart1_txByteQ + UART1_CONFIG_TX_BYTEQ_LENGTH))
24
        {
25
            uart1_obj.txHead = uart1_txByteQ;
26
        }
27
28
        uart1_obj.txStatus.s.full = false;
29
30
        if(uart1_obj.txHead == uart1_obj.txTail)
31
        {
32
            uart1_obj.txStatus.s.empty = true;
33
            break;
34
        }
35
    }
36
}


Da hat wohl jemand zu viel "optimiert" ;)

trotzdem Danke für die Hilfe.

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.