PIC UART fehlerhafte Übertragung

Gast #4935485
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.
#4936402
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 ;-)
Gast #4936499
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.
Gast #4936554
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 ?
Gast #4936573
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.
Gast #4936669
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.

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