PIC24F32KA302 UART-Konfiguration

#3842349
Lesenswert?

Hallo!

Ich arbeite an einem Kleinen Bastelprojekt und bin auf ein Problem 
gestoßen. Die Verbindung von meiner Platine mit dem Rechner will einfach 
nicht funktionieren.

Als Ziel ist eine Datenübertragung von 8000+ bits pro Sekunde bei einer 
Baudrate von 115200 von der Platine zum Rechner. Die bits sollen im 
8-bit-Mode mit einem Stopbit ohne Parität und ohne HW-Flusskontrolle.

Zwischenziel sind funktionierende Sende- und Empfangsfunktionen bei 
einer niedrigeren Baudrate von 9600.

Ich verwende folgende Konfiguration:
1
//code protection off & write protection off (boot segment)
2
_FBS(BSS_OFF & BWRP_OFF)
3
//code protection off & write protection off (general segment)
4
_FGS(GSS0_OFF & GWRP_OFF)
5
//8MHz + PLL & internal-external switchover off (oscillator selection)
6
_FOSCSEL(FNOSC_PRIPLL & IESO_OFF)
7
//HS oscillator mode selected & 2nd osc low power, frequency range >8MHz & CLKO OFF & Both Clock Switching and Fail-safe Clock Monitor are enabled (oscillator)
8
_FOSC(POSCMOD_HS & SOSCSEL_SOSCLP & POSCFREQ_HS & OSCIOFNC_OFF & FCKSM_CSECME)
9
//WDT off & windowed WDT off(watchdog timer)
10
_FWDT(FWDTEN_OFF & WINDIS_OFF)
11
//reset pin off & standard i2c-pins & power up timer off(reset config)
12
_FPOR(MCLRE_ON & I2C1SEL_PRI & PWRTEN_OFF & BORV_V18 &  LVRCFG_OFF & BOREN_BOR0)
13
//Deep sleep WTD OFF, Deep Sleep BOR OFF(deep sleep)
14
_FDS(DSWDTEN_OFF & DSBOREN_OFF)

Diese config soll bezwecken, dass der interne clock mit 16 MHz läuft. 
(8*4)/2

Als Init-Funktion benutze ich:
1
void UART_Init(void)
2
{
3
  TRISBbits.TRISB0 = 0;        //TX-Pin Output
4
  TRISBbits.TRISB1 = 1;        //RX-Pin Input
5

6
  U2MODEbits.STSEL = 0;    //One Stop bit
7
  U2MODEbits.PDSEL = 0b00;        //8-bit data, no parity
8
  U2MODEbits.BRGH = 1;    //BRG generates 4 clocks per bit period (4x baud clock, High-Speed mode)
9
  U2MODEbits.RXINV = 0;    //No invertion
10
  U2MODEbits.ABAUD = 0;    //Baud rate measurement is disabled or completed
11
  U2MODEbits.UEN = 0b00;          //UxTX and UxRX pins are enabled and used; UxCTS and UxRTS/UxBCLK pins are controlled by port latches
12
  U2MODEbits.IREN = 0;    //IrDA encoder and decoder are disabled
13

14
        U2BRG = 25;                     //9600 Baud (0.16%) @32MHz (16MIPS)
15

16
  U2MODEbits.UARTEN = 1;          //UART2 is enabled; all UART2 pins are controlled by UART2 as defined by UEN<1:0>
17

18
  U2STAbits.UTXEN = 1;    //Transmit is enabled, UxTX pin is controlled by UARTx
19
}

Kann vllt jmd. sehen wo das Problem sein könnte?

Gruß Konstantin
#3842537
Lesenswert?

Konstantin H. schrieb:
> Die Verbindung von meiner Platine mit dem Rechner will einfach
> nicht funktionieren.
Kannst du das genauer spezifizieren?

> U2BRG = 25;        //9600 Baud (0.16%) @32MHz (16MIPS)
Wie bist du auf U2BRG = 25 gekommen?
Ich komme auf:
U2BRG = 25 würde eine Baudrate von 166.7kBd entsprechen.

Wie sehen die Sende- und Empfangsfunktionen aus?
#3843318
Lesenswert?

Danke für die Antwort.

Max H. schrieb:
> Kannst du das genauer spezifizieren?

Ja. Ich habe eine Platine mit einigen LEDs und diese nutze ich als 
checkpoints für den C-Code. (Alle LEDs sind korrekt angeschlossen und 
laufen mit anderen Programmen) So kann ich verfolgen, an welcher stelle 
befindet sich das Programm. Und mir ist klar geworden, dass das Programm 
nicht ein mal in die main-fkt kommt. Meine ursprüngliche "geniale Idee" 
war die Verbindung der RX- und TX-Leitungen. Es sollte also das 
ankommen, was gesendet wurde.

Max H. schrieb:
> Wie sehen die Sende- und Empfangsfunktionen aus?
1
void delay(void) {                  //Verzögerung
2
    long i = 45535;
3
    while(i--);
4
}
5

6
void UART_zeichen_senden( char zeichen )
7
{
8
    U2TXREG = zeichen;
9
    while(U2STAbits.TRMT == 0);
10
}
11

12
void UART_zeichenkette_senden( char *str )
13
{
14
    unsigned char c;
15
    while((c = *str++))
16
    {
17
        UART_zeichen_senden(c);
18
    }
19
}
20

21
char UART2_RX_Status(void)
22
{
23
  if(U2STAbits.URXDA)      //1 = im Buffer sind Daten
24
    return 1;
25
  return 0;
26
}
27
char UART2_char_empfangen(void)
28
{
29
  return U2RXREG;
30
}
31

32
int main(int argc, char** argv) {
33

34
    char check;
35

36
    ANSA = 0x0000;          // set IOs digital
37
    ANSB = 0x0000;
38

39
    TRISBbits.TRISB13 = 0;  //LED-Ports als Ausgang
40
    TRISBbits.TRISB14 = 0;
41
    TRISBbits.TRISB15 = 0;
42

43
    LATBbits.LATB15 = 1;
44
    delay();
45
    LATBbits.LATB15 = 0;
46
    delay();
47

48
    UART_Init();
49

50
    LATBbits.LATB14 = 1;
51
    delay();
52
    LATBbits.LATB14 = 0;
53
    delay();
54

55
    while(1)
56
    {
57
        LATBbits.LATB13 = 0;
58
        LATBbits.LATB14 = 0;
59
        LATBbits.LATB15 = 0;
60
        check = '0';
61

62
        UART_zeichen_senden('1');
63
        check = UART2_char_empfangen();
64
        if (check != '0') {
65
                LATBbits.LATB13 = 1;
66
                delay();
67
                delay();
68
                delay();
69
                delay();
70
        } else {
71
        LATBbits.LATB14 = 1;
72
        LATBbits.LATB15 = 1;
73
        delay();
74
        delay();
75
        }
76
    }
77

78

79

80
    return (EXIT_SUCCESS);
81
}

Max H. schrieb:
> Wie bist du auf U2BRG = 25 gekommen?
> Ich komme auf:U2BRG = 25 würde eine Baudrate von 166.7kBd entsprechen

Danke, ich habe an dieser Stelle die falsche Formel genommen. Danke für 
die Korrektur. Jedoch auch nach dem Einsetzen des richtigen Wertes, gab 
es keine Veränderung.
#3843338
Lesenswert?

Konstantin H. schrieb:
> Und mir ist klar geworden, dass das Programm
> nicht ein mal in die main-fkt kommt.
Das ist aber eine andere Baustelle als der UART. Es macht z.B: auch 
keinen Sinn ein Haus zu bauen bevor das Fundament fertig ist.

Wie hast du das gesehen? Kann es vllt. sein dass die LED an LATB15 nur 
ein paar Taktzyklen an ist weil der Compiler dein delay wegoptimiert?

Hast du vllt. einen Debugger um das Schritt für Schritt durchzugehen?
Gast #3843360
Lesenswert?

Konstantin H. schrieb:
> (Alle LEDs sind korrekt angeschlossen und
> laufen mit anderen Programmen) So kann ich verfolgen, an welcher stelle
> befindet sich das Programm. Und mir ist klar geworden, dass das Programm
> nicht ein mal in die main-fkt kommt.

Die PICs, insbesondere die PIC24 lassen sich doch prima mit einem PICKit 
3 oder einem Clone direkt debuggen. Da braucht man die LEDs garnicht, 
einfach einen Breakpoint in main und schon sieht man was abgeht.

Max H. schrieb:
> Wie hast du das gesehen? Kann es vllt. sein dass die LED an LATB15 nur
> ein paar Taktzyklen an ist weil der Compiler dein delay wegoptimiert?

Da liefert der XC16 Funktionen wie __delay_ms(), die nicht wegoptimiert 
werden

MfG Klaus
#3844793
Lesenswert?

Also ich bin noch mal alles durchgegangen. Das Problem liegt in dem 
config. Der PIC funktioniert mit dem Config nicht. Ohne dem config kann 
ich Problemlos die Funktionen implementieren.

Ich werde jetzt noch ein mal den config durchgehen. Wenn jemand einen 
Fehler findet, würde es mich freuen, wer er es mir mitteilen würde.

Gruß

Konstantin
#3844823
Lesenswert?

Konstantin H. schrieb:
> Also ich bin noch mal alles durchgegangen. Das Problem liegt in dem
> config. Der PIC funktioniert mit dem Config nicht. Ohne dem config kann
> ich Problemlos die Funktionen implementieren.
>
> Ich werde jetzt noch ein mal den config durchgehen. Wenn jemand einen
> Fehler findet, würde es mich freuen, wer er es mir mitteilen würde.
>
> Gruß
>
> Konstantin

>"_FOSC(POSCMOD_HS ........"
Wir der PIC24 mit externem Quarz betrieben?

Weil einige Posts vorher:
>"Diese config soll bezwecken, dass der interne clock mit 16 MHz läuft. "
Dann wäre die Einstellung eher etwas mit FRC bzw. FRCPLL (genaue 
Schreibweise in der *.h u.ä.).

Denn ohne Änderungen in den CONFIG-Einstellungen (also mit 
Defaultwerten)läuft der PIC mit internem Oscillator, wenn aber in der 
CONFIG "HS" eingestellt und kein Quarz angeschlossen ist, tut sich nix.
#3844841
Lesenswert?

@TO:

Warum muss der µC unbedingt mit 16Mhz laufen?
Machen es nicht auch 8Mhz oder gar 32Mhz? Die notwendige Genauigkeit bei 
der Baudrate sollte kein Problem darstellen.

Wie Chris B. schon schrieb, ist deine Config der Taktquelle falsch!
"HS" definiert immer einen externen Quarz.

in der Header vom CCS-Compiler lautet das notwendige Bit FRC bzw. 
FRC_PLL.

kleiner Tip:
Um die grundlegende Funktionsweise des µC zu verifizieren, hat sich eine 
blinkende LED als Status-/Life-LED als ziemlich praktisch herausgestellt 
;)
SO kannst du auch schon sehen, ob die Taktfrequenz mit deiner 
berechneten übereinstimmt.
#3844853
Lesenswert?

Chris B. schrieb:
> Denn ohne Änderungen in den CONFIG-Einstellungen (also mit
> Defaultwerten)läuft der PIC mit internem Oscillator, wenn aber in der
> CONFIG "HS" eingestellt und kein Quarz angeschlossen ist, tut sich nix.

Oha. Ich dachte nur der "EC" (external clock mode)auf einen externen 
Quarz zugreift?
Also dann muss der Register

Konstantin H. schrieb:
> _FOSCSEL(FNOSC_PRIPLL & IESO_OFF)

geändert werden. FNOSC_PRIPLL -> FNOSC_FRCPLL. Und der Register

Konstantin H. schrieb:
> _FOSC(POSCMOD_HS & SOSCSEL_SOSCLP & POSCFREQ_HS & OSCIOFNC_OFF &
> FCKSM_CSECME)

in _FOSC(POSCMOD_XT & SOSCSEL_SOSCLP & POSCFREQ_MS & OSCIOFNC_OFF &
  FCKSM_CSECME)

Ich werde das erstmal ausprobiren.
#3844873
Lesenswert?

Das Datenblatt hilft dabei manchmal wesentlich weiter.
In Figure 9-1 ist die Zugehörigkeit der Fuses/ConfigBits eigentlich gut 
zu erkennen (Siehe Anhang)

Nebenbei bemerkt funktioniert dein Ansatz zur Takterzeugung nicht.
Mit der Formel (8*4)/2 suggerierst du, dass du den "Post"Scaler hinter 
der PLL einsetzen willst, was aber hardwaretechnisch nicht implementiert 
ist.

INTOSC --> POSTSCALER --> PLL

8Mhz --> :2 --> x4 --> 16MHz

EDIT:

habe den Microchip-Compiler gerade nicht zur Hand.
Wofür steht "POSCMOD_XT"?
Das scheint mir nicht passend zu sein, weil damit wieder eine externe 
Taktquelle gemeint ist.
Angehängte Dateien:
#3844887
Lesenswert?

@bjrn_g und @dekatz
Vielen Dank für die sehr nützliche Tipps.

Ich habe das BRGH Register auf 0 gesetzt und die Baudrate (U2BRG) 
entsprechend der Formel auf 25 gesetzt.

Mit der config funktioniert der PIC und die Status LEDs zeigen den 
Verlauf des Programms an. Ich bin aber auf ein Programmierproblem 
gestoßen, ich werde mich erstmal dem Problem wenden. Ich muss mein 
Sende- und Empfangtestsystem nachbessern und die Platine an einen 
Rechner anschließen.

Wenn ich die RX- und TX- Leitungen kurzschließe, bekomme ich an dem RX 
dasselbe, was ich über TX sende?


Gruß

Konstantin
#3844899
Lesenswert?

Björn G. schrieb:
> habe den Microchip-Compiler gerade nicht zur Hand.
> Wofür steht "POSCMOD_XT"?
> Das scheint mir nicht passend zu sein, weil damit wieder eine externe
> Taktquelle gemeint ist.

LP - low power
Im LP Mode kann U2 keine 'großen' Ströme erzeugen, er muss es auch 
nicht, da dieser Mode nur für Takte bis zu 200 kHz gedacht ist. Der 
LP-Mode ist auf niedrigen Stromverbrauch hin optimiert. Typischerweise 
nutzt man dann einen 32-kHz-Uhrenquarz.

XT - normal
Im XT-Mode geht U2 schon etwas stärker an die Arbeit. Der 
Ausgangswiderstand ist niedrig genug, um Schwingungen bis zu 4 MHz 
sicher zu erzeugen.

HS - high speed
Um Frequenzen oberhalb von 4 MHz zu erzeugen, wird U2 niederohmig 
eingestellt. Das ist zwar gut für die Verarbeitungsgeschwindigkeit des 
PIC, hebt aber auch den Stromverbrauch des Oszillators um einige 
Milliampere an (typabhängig).

http://sprut.de/electronic/pic/osc/index.htm#oszillator

Deswegen war ich mir sicher, dass nur der EC mode den externen 
Oscillator nutzt. Kann HS-Mode nicht duch den internal oscillator 
betrieben werden?
#3844902
Lesenswert?

Konstantin H. schrieb:
>
> Wenn ich die RX- und TX- Leitungen kurzschließe, bekomme ich an dem RX
> dasselbe, was ich über TX sende?

Natürlich ginge das, aber kannst du die Platine nicht an einen PC 
anschließen und dauerhaft irgendwas raus senden?
Macht sich leichter, weil du mit dem Feedback (TX auf RX) auch von außen 
irgendwie erkennbar machen müsstest, das und was angekommen ist. (eine 
LED eignet sich da natürlich nur bedingt)
#3844907
Lesenswert?

Konstantin H. schrieb:
> Mathematisch gesehen ist die Formel korrekt. Ich habe in diesem Fall nur
> zusammengefasst, denn 32/2 ist dasselbe wie 4*4.

Ja ich weiß xD
Wusste auch das dieses Statement noch kommt. War auch nur eine 
Anmerkung.

Btw steht bei Sprut auch:

"externe Taktquelle (LP, XT, HS, EC)
Steht ein externes Takt-Signal zur Verfügung, so wird es im Mode LP, XT 
oder HS direkt an das Pin OSC1 angeschlossen (CLKIN). Der Inverter U1 
speist dieses Signal dann in den PIC ein, während der Ausgang OSC2 
unbenutzt bleibt. An ihm ließe sich aber bei Bedarf der Takt abgreifen 
(CLKOUT).
Als externe Taktquellen eignen sich z.B. Quarzoszillatoren.

Einige Typen (16F62x) unterstützen den EC (external clock)-Mode. Auch in 
diesem Mode kann ein externer Takt direkt an OSC1 angelegt werden. Das 
OSC2-Pin wird dann allerdings nicht als Taktausgang (CLKOUT) verwendet, 
sondern kann als I/O-Pin genutzt werden."

Diese 4 Konfigurationen sind demnach nur bei externen Taktquellen 
nutzbar.
#3844935
Lesenswert?

Konstantin H. schrieb:
> Stimmt. Das heißt, der Register FOSC muss default gelassen werden?

Jain... Ich würde die Configbits immer vollständig im Code einstellen.
Per default ist natürlich der interne Oszillator aktiviert (sofern 
vorhanden).

Kleine Anekdote, warum ich die Bits immer im Code einstelle:

Zu Zeiten von MPLab 8 und PIC18/PIC16 habe ich die ConfigBits immer in 
MPLab selbst eingestellt. Sie waren demnach zwar Projektgebunden, aber 
nicht Codegebunden. Hatte dann manchmal aufm Laptop weitergearbeitet -> 
quasi C-File kopiert -> neues Projekt erstellt -> C-File eingefügt -> 
nichts lief mehr^^

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