PIC18F + MAX232 USART Skurrilität

Okay, ich habe wochenlang damit gekämpft, und es haut mich um. Ich arbeite seit langem mit PICs und bin sehr verwirrt darüber, warum ich meinen USART nicht zum Laufen bringen kann.

Zunächst einmal ein paar Fragen für Leute, die diesen Beitrag nicht durchlesen möchten, aber vielleicht helfen können:

  • Wie invertiere ich die Signale zur Verwendung mit dem MAX232-Chip?
  • Sollen TX und RX auf Ausgänge, Eingänge oder Ausgang für RX und Eingang für TX eingestellt werden? Das Datenblatt sagt eins, Beispiele sagen ein anderes.
  • Muss ich die PLL verwenden?
  • Wofür sind die Flags USART_ADDEN_OFF und BAUD_IDLE_RX_PIN_STATE_HIGH und warum sind sie nicht in der C18-Dokumentation enthalten?

Für alle anderen hier die lange Geschichte:

Das Setup: PIC18F46K20 <--> MAX232 <--> PC

RC7 ist RX und RC6 ist TX.

Terminal-Software ist nur ein Python-Interpreter:

port = serial.Serial("COM6", 2400, timeout=5)
port.write("abcd")
print port.read(1)
etc...
  • Wenn ich die T1in- und R1out-Pins des MAX232 miteinander verbinde, funktioniert der serielle Loopback von meinem PC aus einwandfrei, sodass ich weiß, dass die MAX232-Karte in Ordnung ist.
  • Ich habe den PIC von seiner Platine entfernt und er sitzt zum Debuggen auf einem Steckbrett. Die einzigen Dinge, die daran angeschlossen sind, sind Strom, Masse und TX & RX.

Ich habe eine unglaubliche Anzahl von Codevariationen ausprobiert - keine funktioniert. Hier sind einige der Dinge, die ich versucht habe:

Dies ist im Grunde vollständig aus diesem Beitrag entnommen: PIC18 USART-Problem

Beachten Sie die Verwendung einer PLL und die HS-Einstellung für BRGH und dass der TX-Pin auf Eingang eingestellt ist und nur RX auf Ausgang eingestellt ist, im Gegensatz zum Datenblatt.

#include <p18cxxx.h>
#include <usart.h>

void main(void)
{
char c = 'a';

TRISC = 0x80;
    // Internal osc. 8 MHz, PLL 4x
    OSCCON |= 0xE2;
    OSCTUNEbits.PLLEN = 1;

    // wait until IOFS = 1 (osc. stable)
    while (!OSCCONbits.IOFS)
        ;


    /*
     * Open the USART configured as
     * 8N1, 2400 baud, in polled mode
     */
     OpenUSART (USART_TX_INT_OFF &
                USART_RX_INT_OFF &
                USART_ASYNCH_MODE &
                USART_EIGHT_BIT &
                USART_CONT_RX &
                USART_BRGH_HIGH, 207);

     while (1)
     {
          putcUSART(c);
          c = getcUSART();
          Nop();
     }

}

Wie auch immer, ich fühle mich albern, dass ich eine alberne USART nicht zum Laufen bringen kann, aber ich bin völlig ratlos. Was vermisse ich? Was mache ich Dummes? Jemand bitte helfen!

Außerdem bin ich erschöpft – ich poste das Letzte, bevor ich ins Bett gehe, und probiere morgen mehr aus.

Dies gibt einen konstanten Strom von Kauderwelsch zurück, auch wenn ich nichts vom PC an den USART schreibe:

#include <p18cxxx.h>
#include <usart.h>

void main(void)
{
char test = 'a';
TRISC = 0xFF;
OSCCON |= 0b11100010;
OSCTUNEbits.PLLEN = 1;

    while (!OSCCONbits.IOFS);

baudUSART(BAUD_IDLE_CLK_LOW & 
          BAUD_AUTO_OFF & 
          BAUD_8_BIT_RATE & 
          BAUD_IDLE_RX_PIN_STATE_HIGH);

OpenUSART (USART_TX_INT_OFF &
           USART_RX_INT_OFF &
           USART_ASYNCH_MODE &
           USART_EIGHT_BIT &
           USART_CONT_RX &
           USART_ADDEN_OFF &
           USART_BRGH_HIGH, 207);
    while (1)
    {
        WriteUSART(test);
        while(!DataRdyUSART());
        test = ReadUSART();
        Nop();
    }
}

AKTUALISIEREN

Okay, jetzt liegt mein TX-Pin konstant bei 0,00 Volt. Es ist fast so, als wäre es direkt mit dem Boden verbunden (es kann an diesem Punkt sehr gut sein, ich weiß es nicht). Ich habe versucht, PICs auszuschalten, es ständig senden zu lassen, es nichts tun zu lassen, Konfigurationsbits zu ändern ... nichts scheint zu helfen. Der RX-Pin sitzt hoch (was richtig ist, weil er nichts empfängt), aber der TX-Pin sitzt flach bei 0 V - ob er senden soll oder nicht.

Hier mein aktueller Code:

#include <p18cxxx.h>
#include <usart.h>

void main(void)
{
char test = 't';
TRISCbits.RC7 = 1;
TRISCbits.RC6 = 0;
OSCCON = 0b11100010;
OSCTUNEbits.PLLEN = 0;

    while (!OSCCONbits.IOFS);

baudUSART(BAUD_IDLE_CLK_LOW & 
          BAUD_AUTO_OFF & 
          BAUD_8_BIT_RATE & 
          BAUD_IDLE_RX_PIN_STATE_HIGH &
          BAUD_IDLE_TX_PIN_STATE_HIGH);

OpenUSART (USART_TX_INT_OFF &
           USART_RX_INT_OFF &
           USART_ASYNCH_MODE &
           USART_EIGHT_BIT &
           USART_CONT_RX &
           USART_ADDEN_OFF &
           USART_BRGH_HIGH, 207);
    while (1) {
//       WriteUSART(test);
//      while(!DataRdyUSART());
//        test = ReadUSART();
        Nop();
    }
}

Was um alles in der Welt habe ich getan, um es dazu zu bringen? Beachten Sie, dass ich auch meinen alten Code neu erstellt habe (ein Beispiel von oben, das vorher nur Kauderwelsch ausspuckte) - und jetzt beträgt die Spannung auch bei dieser Hex-Datei 0,0 V. Außerdem funktioniert der Loopback des MAX232 immer noch korrekt. Häh?

Welche Terminalsoftware verwendest du? Wie ist es aufgebaut? Haben Sie auch die PICs Rx/Tx mit einem Oszilloskop überprüft und / oder die Kontinuität zwischen allen Leitungen mit einem Multimeter bestätigt?
Ich habe oben eine Notiz zu meinem Terminal-Setup (alles Python) hinzugefügt. Ich habe noch nicht mit einem Zielfernrohr nachgesehen, weil ich keins zur Hand habe - kann morgen irgendwohin reisen, wo es eines gibt. Ich habe jedoch Spannungen mit einem Multimeter bestätigt.
Ein Update am Ende meines Beitrags hinzugefügt, wenn Sie irgendwelche Ideen haben :-/

Antworten (2)

Okay, für alle, die in Zukunft jemals auf so etwas stoßen:

Das Problem war, dass es Lecks von der Stromspur in die serielle Spur gab, so dass eine 60-Hz-Welle auf der SPI-Leitung erschien, was offensichtlich die Dinge durcheinander bringen würde.

Ich weiß, dass die Wahrscheinlichkeit, dass die gleiche Lösung auf andere Leute zutrifft, gering ist, aber vielleicht gibt es Ihnen zumindest einige Ideen!

Alter Rat:

  • Teilen Sie es in Abschnitte auf.

  • Eliminieren Sie nach Möglichkeit die Komplexität, die der grundlegenden funktionierenden Low-Level-Verbindung im Wege stehen könnte.

  • Versuchen Sie, eine Sache nach der anderen zu testen und eine Sache nach der anderen zu ändern.

    Sie können nach N Dingen suchen, die als Ergebnis einer Änderung passieren können, aber dies riskiert, zu verschleiern, was was verursacht.

    Änderungen würden idealerweise nur auf einen einzigen Bereich in ihrer Wirkung abzielen).


DANN:

Der TX-Pin muss auf Ausgang gesetzt sein.

Wenn Sie einen RS232-IC verwenden (der invertiert), muss der TX-Leerlaufpegel am PIC hoch sein.

Wenn Sie sehen möchten, ob die PIC-Uhr und die Kommunikationsverbindungen wie erwartet funktionieren, können Sie eine etwas angeschlagene TX-Routine (viele in der Nähe) verwenden, um Zeichen an den PC zu senden. Wenn Sie keine Daten erhalten, die auf diese Weise angezeigt werden, ist Ihre Verbindung in irgendeiner Weise verdächtig. Wenn Sie am PC Datenspuren erhalten, können Sie die Dinge ändern, bis es funktioniert, und dann wissen, was Ihr PIC über UART tun soll

Die TX-Low-Level-Funktionalität kann durch Messen der Spannung mit einem Voltmeter bestätigt werden.

  • Wenn im Leerlauf = logisch 1 = hoch = 5 V (sagen wir) und Sie in einer engen Schleife senden
    und null ($ 00) senden

  • dann fällt die Spannung auf einen niedrigen Prozentsatz von 5 V.
    Wenn Sie z. B. ohne Verzögerung zwischen Zeichen senden können * (abhängig von Pufferung usw.), senden Sie:
    Start = 0, 8 x niedrig, 1 x Stopp = 5 V, sodass Sie 1/10 x 5 V = 0,5 V sehen würden Gleichstrom.

    Wenn Sie zwischen den Zeichen eine Verzögerung haben, steigt die Spannung entsprechend an.

Ohne Oszilloskop - Wenn Sie TX-Zeichen in einer Schleife an den PC senden, sollten Sie beim Senden eine Spannungsänderung sehen, und Sie sollten sehen, dass sich die Spannung am RS232-Ausgang ebenfalls ändert, jedoch mit entgegengesetzter Polarität.

Der RS232-Ausgang zum PC sollte im Leerlauf niedrig sein und dann auf die entgegengesetzte Weise zum obigen Test geändert werden.

Vielen Dank für die Tipps! Ich habe Ihren Rat befolgt und den TX-Pin auf Ausgang gesetzt. Außerdem habe ich angefangen, die Spannungen zu überprüfen, und irgendwie habe ich jetzt einen TX-Pin, der konstant auf 0,0 V liegt (das war vorher nicht der Fall) - überprüfen Sie das Ende meines Beitrags auf das Update, das meinen aktuellen Code zeigt. Gedanken?