Forum: Mikrocontroller und Digitale Elektronik Übertragung PIC24 zu WLAN-Modul über UART2


von Gisti (Gast)


Lesenswert?

Bei dem Versuch ein WLAN Modul über UART zu initialisieren habe ich 
UART2 wie unten dargestellt initialisiert:

Bei debuggen habe ich jetzt festgestellt, dass beim Einlesen eines 
Characters (z.B.
1
 U2TXREG = '1';
) das U2TXREG bzw U2RXREG, also das Transceive Register bzw. das 
Transmit Register immer "leer bleiben" (also Value: 0xOOOO bzw Char: 
"..."). Ich habe versucht beim Setup für UART Transmit mich genau an die 
Schritte im Datenblatt zu halten, trotzdem scheint es noch irgendwo bei 
der Initialisierung zu haken. Jemand ne Idee was ich falsch gemacht 
haben könnte?
1
    #define FCY 10000000    // FCY = FOSC/2
2
    #define BAUDRATE 9600
3
    #define BRGVAL ((FCY/BAUDRATE)/16)-1
4
5
    U2MODEbits.BRGH = 0;  // Bit3 16 clocks per bit period, BRGH = 0: BRG generates 16 clocks per bit period (16x baud clock, Standard mode)
6
    U2BRG = BRGVAL; // Baud Rate setting for 9600
7
    
8
9
    // 9600 baud, 8 bits data, 1 stop bit, no parity, and no flow control
10
    // 2.
11
    U2MODEbits.PDSEL = 0;  // Bits1,2 8bit-data, No Parity, PDSEL = 0: 8-bit data, no parity
12
    U2MODEbits.STSEL = 0;  // Bit0 One Stop Bit, STSEL = 0: One Stop bit
13
14
    //  Later, receive interrupts are enabled. Transmit interrupts remain disabled.
15
    // 3.
16
    IEC1bits.U2TXIE = 0;  // disable Transmit Interrupts
17
    IEC1bits.U2RXIE = 0;  // disable Recieve InterruptsU2STAbits.URXISEL = 0;      //  UARTx Receive Interrupt Mode Selection bits; 0x  = Interrupt flag bit is set when a character is received
18
    U2MODEbits.UEN = 0;     // Bits8,9 TX,RX enabled, CTS,RTS not, -> no Flo Control
19
20
    // Peripheral Pin Select
21
    // URX
22
    TRISFbits.TRISF4 = 1;  // RF4 input - U2RX pin;    /*  Uart Rx is an input */
23
    RPINR19 = 0;
24
    RPINR19bits.U2RXR = 0b1100100; // RF4 pin - RP100 assigned to U2RX function
25
26
27
    // UTX
28
    TRISFbits.TRISF5 = 0; // RF5 output - U2TX pin;  /*  Uart Tx is an output */
29
    RPOR9 = 0;
30
    RPOR9bits.RP101R = 0b000011; // RF5 as U2TX; RP101 tied for UART2 transmit
31
32
    // 5.
33
    U2MODEbits.UARTEN = 1;  // 1 = UARTx is enabled; all UARTx pins are controlled by UARTx as defined by UEN<1:0>
34
    // The UTXEN bit should not be set until the UARTEN bit has been set; otherwise UART transmissions will not be enabled.
35
36
    // 6.
37
    U2STAbits.UTXEN = 1;    // Bit10 TX pins controlled by periph, UTXEN = 1:  Transmit  is  enabled,  U2TXIF is set

von Hermann U. (Firma: www.pcb-devboards.de) (gera82)


Lesenswert?

Gisti schrieb:
> // Peripheral Pin Select
>     // URX
>     TRISFbits.TRISF4 = 1;  // RF4 input - U2RX pin;    /*  Uart Rx is an
> input */
>     RPINR19 = 0;
>     RPINR19bits.U2RXR = 0b1100100; // RF4 pin - RP100 assigned to U2RX
> function
>
>     // UTX
>     TRISFbits.TRISF5 = 0; // RF5 output - U2TX pin;  /*  Uart Tx is an
> output */
>     RPOR9 = 0;
>     RPOR9bits.RP101R = 0b000011; // RF5 as U2TX; RP101 tied for UART2
> transmit

auf die schnelle aufgefallen, ändere das mal:
1
     // URX
2
     TRISFbits.TRISF4 = 1;  // RF4 input - U2RX pin;    /*  Uart Rx is an input */
3
4
     // UTX
5
     TRISFbits.TRISF5 = 0; // RF5 output - U2TX pin;  /*  Uart Tx is an output */
6
7
8
      __builtin_write_OSCCONL(OSCCON & (~(1<<6))); // clear bit 6 
9
10
        RPINR19 = 0;
11
        RPINR19bits.U2RXR = 0b1100100; // RF4 pin - RP100 assigned to U2RX 
12
        RPOR9 = 0;
13
        RPOR9bits.RP101R = 0b000011; // RF5 as U2TX; RP101 tied for UART2 
14
15
      __builtin_write_OSCCONL(OSCCON | (1<<6));    // Set bit 6

Gruß
Hermann

von Gisti (Gast)


Lesenswert?

Danke sehr. War leider erfolglos.

von Hermann U. (Firma: www.pcb-devboards.de) (gera82)


Lesenswert?

Gisti schrieb:
> Danke sehr. War leider erfolglos.

Ja was heißt es, kommt am TXPin nichts raus, hast du ein OSZI da?

Oder kommt was falsches raus, dann stimmen die Timings nicht, Zb. 
Einstellung von QUARZ:
1
/* Macros for Configuration Fuse Registers :*/
2
_FOSCSEL(FNOSC_PRIPLL & IESO_OFF)
3
_FOSC   (POSCMD_XT & OSCIOFNC_OFF & IOL1WAY_OFF & FCKSM_CSECMD)

oder Takteinstellung z.B.:
1
/********************************************************************************
2
 *                                                                              *
3
 *  Funktion:      OSCswitching                                                 * 
4
 *                                                                              *
5
 *------------------------------------------------------------------------------*
6
 *  Description: 
7
 ********************************************************************************/
8
void OSCswitching(void) 
9
{
10
   
11
// Hier muss dann einstellen
12
// PLLFBD = ?;    /* M = ? */
13
// CLKDIVbits.PLLPOST = ?;  /* N1 = ? */
14
// CLKDIVbits.PLLPRE = ?;  /* N2 = ? */
15
16
 CLKDIVbits.DOZEN = 0;  /* Processor clock and peripheral clock ratio forced to 1:1 */
17
18
 RCONbits.SWDTEN = 0; //Disable Watch Dog Timer
19
20
 __builtin_write_OSCCONH(0b011);  //Initiate clock switch to HS with PLL
21
22
 __builtin_write_OSCCONL(0b001);  //Start clock switching
23
24
 while (OSCCONbits.COSC != 0b011) //Wait for clock switch to occur
25
26
 while(OSCCONbits.LOCK!=1) {};    //Wait for PLL to lock
27
}



falls am TX Pin nichts raus kommt, dann ist die Einstellung von PIN (z.B 
Peripheral Pin Select etc.)
1
        // PORTF Einstellung: 
2
        LATF  = 0x0000;
3
        TRISF = (1 << 4);  // RF4 input - U2RX pin; // RF5 output - U2TX pin;
4
 //       CNENF = 0;  //CN PINS konfigurieren

PPS Einstellung:
1
      __builtin_write_OSCCONL(OSCCON & (~(1<<6))); // clear bit 6 
2
3
        RPINR19bits.U2RXR = 100;     // RF4 pin - RP100 assigned to U2RX 
4
        RPOR9bits.RP101R = 0b000011; // RF5 as U2TX; RP101 tied for UART2 
5
6
      __builtin_write_OSCCONL(OSCCON | (1<<6));    // Set bit 6

Und als letztes kommt UART Einstellung:
1
    #define FCY 10000000UL    // FCY = FOSC/2
2
    #define BAUDRATE 9600UL
3
    #define BRGVAL ((FCY/BAUDRATE)/16UL)-1UL
4
5
// UART2
6
       U2MODEbits.USIDL = 0;        /* Continue in Idle mode */
7
       U2MODEbits.LPBACK = 0;        /* Disable LoopBack */
8
       U2MODEbits.PDSEL = 0b00;      /* 8-bit data, no parity */
9
       U2MODEbits.STSEL = 0;        /* One Stop bit */
10
                       
11
       U2BRG = BRGVAL;              /* Baud rate generator */
12
13
       IFS1bits.U2RXIF = 0;        /* Clear interrupt flag */
14
       IPC7bits.U2RXIP = 5;        /* Set to highest priority */
15
       IEC1bits.U2RXIE = 1;        /* Enable receive interrupts */
16
17
    
18
       U2MODEbits.UARTEN = 1;              /* Enable UART module 2 */
19
       U2STAbits.UTXEN = 1;              /* Enable transmission, overrides TRIS settings */


Gruß
Hermann

von Gisti (Gast)


Lesenswert?

Hallo und vielen Dank für die ausführliche Antwort.
Dann mal von Anfang an:

Ich nutze internen FRC mit PLL.
1
_FOSCSEL(FNOSC_FRCPLL);      // Internal FRC oscillator with PLL
2
_FOSC(FCKSM_CSDCMD & OSCIOFNC_ON  & POSCMD_NONE);
3
              // Clock Switching is enabled and Fail Safe Clock Monitor is disabled
4
              // OSC2 Pin Function: OSC2 is Clock Output
5
              // Primary Oscillator Mode: XT Crystanl
6
7
_FWDT(FWDTEN_OFF); // Watchdog Timer enabled/disabled by user software
8
_FICD(ICS_PGD1 & JTAGEN_OFF); // Communication Channel: PGC1/EMUC1 and PGD1/EMUD1

Die Takteinstellung habe ich wie folgt vorgenommen:
Ich bekomme eine Oszillatorfrequenz von 21MHz -> Inputclock: Fcy=Fosc/2 
= 10,5 MHz. Diese errechnete Frequenz nutze ich auch als define FCY 
10500000 über die die Baudrate ermittelt wird.
1
 // Fosc= 7.37M*40/(2*7)=21Mhz für 10,5 Mips Input Clock =Fcy; 7.37 da OSCTUN = 0b000000
2
    PLLFBD = 38; // M=40
3
    CLKDIVbits.PLLPOST = 0b00; // N2=2
4
    CLKDIVbits.PLLPRE = 0b00101; // N1=7
5
    OSCTUN = 0;             // Tune FRC oscillator
6
    RCONbits.SWDTEN = 0; // Disable Watch Dog Timer " "RCON Control register; SWDT: 1: WDT is enabled 0: WDT disabled"

Das Peripheral Pin Select nehme ich für UTX bzw. RTX wie folgt vor:
1
// Peripheral Pin Select
2
    // URX
3
    TRISFbits.TRISF4 = 1;  // RF4 input - U2RX pin;    /*  Uart Rx is an input */
4
    RPINR19 = 0;
5
    RPINR19bits.U2RXR = 0b1100100; // RF4 pin - RP100 assigned to U2RX function
6
7
8
    // UTX
9
    TRISFbits.TRISF5 = 0; // RF5 output - U2TX pin;  /*  Uart Tx is an output */
10
    RPOR9 = 0;
11
    RPOR9bits.RP101R = 0b000011; // RF5 as U2TX; RP101 tied for UART2 transmit

Abschließend die UART Einstellung:
1
#define FCY 10500000ULL    // FCY = FOSC/2 unsigned long long
2
#define BAUDRATE 9600
3
#define BRGVAL ((FCY/BAUDRATE)/16)-1
4
5
// configure U2MODE
6
  U2MODEbits.UARTEN = 0;  // Bit15 TX, RX DISABLED, ENABLE at end of func
7
  //U2MODEbits.notimplemented;  // Bit14
8
  U2MODEbits.USIDL = 0;  // Bit13 Continue in Idle
9
  U2MODEbits.IREN = 0;  // Bit12 No IR translation
10
  U2MODEbits.RTSMD = 0;  // Bit11 Simplex Mode
11
  //U2MODEbits.notimplemented;  // Bit10
12
  U2MODEbits.UEN = 0;    // Bits8,9 TX,RX enabled, CTS,RTS not
13
  U2MODEbits.WAKE = 0;  // Bit7 No Wake up (since we don't sleep here)
14
  U2MODEbits.LPBACK = 0;  // Bit6 No Loop Back
15
  U2MODEbits.ABAUD = 0;  // Bit5 No Autobaud (would require sending '55')
16
    // Load a value into Baud Rate Generator.  Example is for 9600.
17
    // See section 19.3.1 of datasheet.
18
    //  U2BRG = (Fcy/(16*BaudRate))-1
19
    //  U2BRG = (10,5/(16*9600))-1, INPUT CLOCK Fcy = 10,5MHz
20
   
21
22
    // 1.
23
    U2MODEbits.BRGH = 0;  // Bit3 16 clocks per bit period, BRGH = 0: BRG generates 16 clocks per bit period (16x baud clock, Standard mode)
24
    U2BRG = BRGVAL; // Baud Rate setting for 9600
25
    // U2BRG = 67;  // 10Mhz osc, 9600 Baud, 8 Datenbit, 1 Stopbit, Kein Parity Bit, keine Flow Kontrolle
26
27
    // 9600 baud, 8 bits data, 1 stop bit, no parity, and no flow control
28
    // 2.
29
    U2MODEbits.PDSEL = 0;  // Bits1,2 8bit-data, No Parity, PDSEL = 0: 8-bit data, no parity
30
    U2MODEbits.STSEL = 0;  // Bit0 One Stop Bit, STSEL = 0: One Stop bit
31
32
    //  Later, receive interrupts are enabled. Transmit interrupts remain disabled.
33
    // 3.
34
    IEC1bits.U2TXIE = 0;  // disable Transmit Interrupts
35
    IEC1bits.U2RXIE = 0;  // disable Recieve Interrupts
36
37
    // Transmit Interrupts ganze Zeit disabled, received Interrupts später enabled -> main
38
    // 4.
39
40
    // Load all values in for U1STA SFR
41
  U2STAbits.UTXISEL1 = 0;  //Bit15 Interrupt when Char is transferred (1/2 config!)
42
  U2STAbits.UTXINV = 0;  //Bit14 N/A, IRDA config, hier: IREN = 0 -> UTXINV = 0:
43
  U2STAbits.UTXISEL0 = 0;  //Bit13 Other half of Bit15
44
  //U2STAbits.notimplemented = 0;  //Bit12
45
  U2STAbits.UTXBRK = 0;  //Bit11 Disabled
46
  U2STAbits.UTXEN = 0;  //Bit10 TX pins controlled by periph
47
  U2STAbits.UTXBF = 0;  //Bit9 *Read Only Bit*
48
  U2STAbits.TRMT = 0;  //Bit8 *Read Only bit*
49
  // U2STAbits.URXISEL = 0;  //Bits6,7 Int. on character recieved
50
  U2STAbits.ADDEN = 0;  //Bit5 Address Detect Disabled
51
  U2STAbits.RIDLE = 0;  //Bit4 *Read Only Bit*
52
  U2STAbits.PERR = 0;    //Bit3 *Read Only Bit*
53
  U2STAbits.FERR = 0;    //Bit2 *Read Only Bit*
54
  U2STAbits.OERR = 0;    //Bit1 *Read Only Bit*
55
  U2STAbits.URXDA = 0;  //Bit0 *Read Only Bit*
56
        
57
        U2STAbits.URXISEL = 0;      //  UARTx Receive Interrupt Mode Selection bits; 0x  = Interrupt flag bit is set when a character is received
58
        U2MODEbits.UEN = 0;     // Bits8,9 TX,RX enabled, CTS,RTS not, -> no Flo Control
59
60
61
    // 5.
62
    U2MODEbits.UARTEN = 1;  // 1 = UARTx is enabled; all UARTx pins are controlled by UARTx as defined by UEN<1:0>
63
    // The UTXEN bit should not be set until the UARTEN bit has been set; otherwise UART transmissions will not be enabled.
64
65
    // 6.
66
    U2STAbits.UTXEN = 1;    // Bit10 TX pins controlled by periph, UTXEN = 1:  Transmit  is  enabled,  U2TXIF is set

Ich versuche nun einen String einzu lesen über die beiden Funktionen:
1
void ConsolePut(char c)
2
{
3
        // while( !ConsoleIsPutReady() );
4
        while(!(U2STAbits.TRMT)); // 1  = Transmit  Shift  Register  is  empty  and  the  transmit  buffer  is  empty
5
//        while ( U2STAbits.UTXBF);   // wait while Tx buffer full
6
        // (i.e.,  the  last  transmission  has completed)
7
        U2TXREG = c;
8
}
9
void ConsolePutString(char* str)
10
{
11
    char c;
12
13
    while( (c = *str++) )
14
        ConsolePut(c);
15
}

Ich lese folgenden String ein:
1
ConsolePutString("$$$");

Als Antwort der WLAN Moduls würde ich den String "CMD" erwarten.
Wie kann ich überprüfen, ob ich diesen String empfangen habe?

Ich habe mir das so überlegt, dass ich das U2RXREG Register in einem 
Char speichere und diesen dann in einem Array ablege.
Das sieht dann im Code wie folgt aus:
1
char data;
2
char output[256]={0};
3
int y = 0;
4
5
while (1)
6
    {
7
8
            while(U2STAbits.URXDA) // 1  = Receive buffer has data; at least one more character can be read
9
            {
10
                data = U2RXREG;
11
                output[y++] = data;
12
13
            }
14
15
16
    }

Dieses Array kann ich jetzt vermutlich nur im Debugg- Modus auslesen. 
Ich hätte jetzt vermutet dass am Ende des Programms (d.h. nach einiger 
Wartezeit nach Senden des Arrays) sich die erwartete Antwort "CMD" des 
Moduls befinden müsste. Gibt es Möglichkeiten außerhalb des Debug Modus 
das Array auszulesen?

Gibt es andere Alternativen das Received Register auszulesen und zu 
illustrieren?

Vielen Dank schon mal!

von Hermann U. (Firma: www.pcb-devboards.de) (gera82)


Lesenswert?

Ist dein Aufbau korrekt, TX/RX Pins nicht verrauscht/kurzgeschlossen?
Was für ein µC Typ hast du? Guckmal die Errata, vielleicht steht ja was 
über UART2 drinne.

Gisti schrieb:
> Ich lese folgenden String ein:
> ConsolePutString("$$$");
> Als Antwort der WLAN Moduls würde ich den String "CMD" erwarten.
> Wie kann ich überprüfen, ob ich diesen String empfangen habe?

Kannst du das mit einem Oszilloskop überprüfen, damit kannst du Fehler 
auf Minimum einkreisen.
http://de.wikipedia.org/wiki/UART

Bitdauer korrekt, 104µs?

Gisti schrieb:
> Dieses Array kann ich jetzt vermutlich nur im Debugg- Modus auslesen.
Ja genau unter "Watch" kannst die output[256] Array ansehen.

Gisti schrieb:
> Gibt es Möglichkeiten außerhalb des Debug Modus
> das Array auszulesen?
Ja zum Beispiel am Display, wenn du ein angeschlossen hast ;-)

Gisti schrieb:
> Gibt es andere Alternativen das Received Register auszulesen
ja ich mach das im Interrupt, das musst du natürlich erst einschalten:
1
    IEC1bits.U2RXIE = 1;  // Recieve Interrupts

1
void __attribute__((__interrupt__,no_auto_psv)) _U2RXInterrupt(void)
2
{
3
  
4
5
  IFS1bits.U2RXIF = 0; // clear RX interrupt flag
6
7
/* Check for receive errors */
8
  if(U2STAbits.FERR == 1)
9
   {
10
    }
11
/* Must clear the overrun error to keep UART receiving */
12
  if(U2STAbits.OERR == 1)
13
    {
14
    U2STAbits.OERR = 0;
15
    }
16
   /* Get the data */
17
    if(U2STAbits.URXDA == 1)
18
     {
19
       ReceivedEncPosition[PAOi] = U2RXREG & 0b01111111; //7 bit
20
       PAOi++;
21
     
22
     }
23
 
24
}

Gruß
Hermann

: Bearbeitet durch User
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.