Hallo Zusammen Ich habe seit kurzen mit dem PIC32 begonnen und arbeite nach einander so manches Beispiel von Microchip durch. Ein Example mit einem UART habe ich auch zum laufen gebracht. Hier wird die UART mit 0 (Null) bezeichnet, erstens einmal gibt es beim oben angegebenen PIC keine Uart0, sondern diese heißen U1A,U1B,U2A,U2B,U3A,U3B. Durch die Port-Einstellungen konnte ich jedoch herausfinden dass es sich um die RF4 (RX) und RF5 (TX) handelt. Nun möcht ich ein weiteres Beispiel testen und hier wird der UART1 verwendet, nachfolgend der Code. Im Library Guide gibt es nur UART1 und 2 von z.B. der Funktion OpenUART1. Es muss doch eine Möglichkeit geben die UART's den Hardware Ein- Ausgängen zuzuorden. In den verschieden Beschreibungen konnte ich auch keine Hinweise finden. Bitte um Hilfe. Danke. Lg. Johann K /********************************************************************* * * DMA Uart echo example file * ********************************************************************* * FileName: uart_echo.c * Dependencies: plib.h * * Processor: PIC32MX * * Complier: MPLAB C32 v1 or higher * MPLAB IDE v8 or higher * Company: Microchip Technology Inc. * * Software License Agreement * * The software supplied herewith by Microchip Technology Incorporated * (the “Company”) for its PIC Microcontroller is intended * and supplied to you, the Company’s customer, for use solely and * exclusively on Microchip PIC Microcontroller products. * The software is owned by the Company and/or its supplier, and is * protected under applicable copyright laws. All rights are reserved. * Any use in violation of the foregoing restrictions may subject the * user to criminal sanctions under applicable laws, as well as to * civil liability for the breach of the terms and conditions of this * license. * * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES, * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. * * * Author Date Comment *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * $Id: dma_api_example.c 4261 2007-08-22 16:32:28Z aura $ * ********************************************************************/ #include <stdlib.h> #include <time.h> #include <plib.h> // prototypes void DmaDoUartEchoExample(int pbClk); // some local data int DmaIntFlag; // flag used in interrupts // Configuration Bit settings #pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_2 #if defined (_32MX460F512L_) || defined (_32MX360F512L_) || defined (_32MX795F512L_) #define SYS_FREQ (80000000L) #elif defined (_32MX220F032D_) || defined (_32MX250F128D_) #define SYS_FREQ (40000000L) #endif #define BAUDRATE 57600 // serial baudrate /********************************************************************* * Function: int main(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: Examples for the usage of the DMA Peripheral Lib * * Note: None. ********************************************************************/ int main(void) { int pbClk; // the PB frequency // Configure the device for maximum performance but do not change the PBDIV // Given the options, this function will change the flash wait states, RAM // wait state and enable prefetch cache but will not change the PBDIV. // The PBDIV value is already set via the pragma FPBDIV option above.. pbClk=SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE); // receive some data from the UART port and echo it back DmaDoUartEchoExample(pbClk); return 1; } /********************************************************************* * Function: void DmaDoUartEchoExample(int pbClk) * * PreCondition: None * * Input: pbClk - the PB frequency * * Output: None * * Side Effects: None * * Overview: Examples for receiving some data from the UART and echoing it back using the DMA Peripheral Lib. * The received data is expected to end with a CR and has to be less than DmaGetMaxTxferSize() bytes in length. * We'll enable the DMA interrupts to signal us when the transfer is done. * * Note: None. ********************************************************************/ void DmaDoUartEchoExample(int pbClk) { char dmaBuff[256+1]; // we'll store the received data here DmaChannel chn=DMA_CHANNEL1; // DMA channel to use for our example // NOTE: the ISR setting has to match the channel number OpenUART1(UART_EN, UART_RX_ENABLE|UART_TX_ENABLE, pbClk/16/BAUDRATE-1); // selected baud rate, 8-N-1 putsUART1("\r\nType up to 256 characters long string followed by Enter key...\r\n\r\n"); // configure the channel DmaChnOpen(chn, DMA_CHN_PRI2, DMA_OPEN_MATCH); DmaChnSetMatchPattern(chn, '\r'); // set \r as ending character // set the events: we want the UART2 rx interrupt to start our transfer // also we want to enable the pattern match: transfer stops upon detection of CR DmaChnSetEventControl(chn, DMA_EV_START_IRQ_EN|DMA_EV_MATCH_EN|DMA_EV_START_IRQ(_UART1_RX_IRQ)); // set the transfer source and dest addresses, source and dest sizes and the cell size DmaChnSetTxfer(chn, (void*)&U1RXREG, dmaBuff, 1, sizeof(dmaBuff), 1); DmaChnSetEvEnableFlags(chn, DMA_EV_BLOCK_DONE); // enable the transfer done interrupt: pattern match or all the characters transferred // enable system wide multi vectored interrupts INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR); INTEnableInterrupts(); INTSetVectorPriority(INT_VECTOR_DMA(chn), INT_PRIORITY_LEVEL_5); // set INT controller priority INTSetVectorSubPriority(INT_VECTOR_DMA(chn), INT_SUB_PRIORITY_LEVEL_3); // set INT controller sub-priority INTEnable(INT_SOURCE_DMA(chn), INT_ENABLED); // enable the chn interrupt in the INT controller DmaIntFlag=0; // clear the interrupt flag // enable the chn DmaChnEnable(chn); // let the user know that he has to enter a string // for example, you could do something like: // printf("\r\nType a string less than 256 characters followed by Enter key...Will echo it using the DMA\r\n\r\n"); // wait for the data to come in while(!DmaIntFlag); // just block here. In a real application you can do some other stuff while the DMA transfer is taking place // ok, we've received the data in the buffer putsUART2("\r\nReceived the character string. Now echoing it back...\r\n\r\n"); // now the TX part // reconfigure the channel DmaChnOpen(chn, DMA_CHN_PRI2, DMA_OPEN_MATCH); // set the events: now the start event is the UART tx being empty // we maintain the pattern match mode DmaChnSetEventControl(chn, DMA_EV_START_IRQ_EN|DMA_EV_MATCH_EN|DMA_EV_START_IRQ(_UART1_TX_IRQ)); // set the transfer source and dest addresses, source and dest size and cell size DmaChnSetTxfer(chn, dmaBuff, (void*)&U1TXREG, sizeof(dmaBuff), 1, 1); DmaChnSetEvEnableFlags(chn, DMA_EV_BLOCK_DONE); // enable the transfer done interrupt: pattern match or all the characters transferred INTEnable(INT_SOURCE_DMA(chn), INT_ENABLED); // enable the chn interrupt in the INT controller DmaIntFlag=0; // clear the interrupt flag DmaChnStartTxfer(chn, DMA_WAIT_NOT, 0); // force the DMA transfer: the UART2 tx flag it's already been active // wait for data to be output while(!DmaIntFlag); // just block here // DMA Echo is complete INTEnable(INT_SOURCE_DMA(chn), INT_DISABLED); // disable further interrupts from the DMA controller putsUART1("\r\nEcho back completed...\r\n\r\n"); } // handler for the DMA channel 1 interrupt void __ISR(_DMA1_VECTOR, ipl5) DmaHandler1(void) { int evFlags; // event flags when getting the interrupt INTClearFlag(INT_SOURCE_DMA(DMA_CHANNEL1)); // release the interrupt in the INT controller, we're servicing int evFlags=DmaChnGetEvFlags(DMA_CHANNEL1); // get the event flags if(evFlags&DMA_EV_BLOCK_DONE) { // just a sanity check. we enabled just the DMA_EV_BLOCK_DONE transfer done interrupt DmaIntFlag=1; DmaChnClrEvFlags(DMA_CHANNEL1, DMA_EV_BLOCK_DONE); } }
Hallo Johann, Klatec schrieb: > Ich habe seit kurzen mit dem PIC32 begonnen und arbeite nach einander so > manches Beispiel von Microchip durch. Ein Example mit einem UART habe > ich auch zum laufen gebracht. Hier wird die UART mit 0 (Null) > bezeichnet, erstens einmal gibt es beim oben angegebenen PIC keine > Uart0, sondern diese heißen U1A,U1B,U2A,U2B,U3A,U3B. Durch die > Port-Einstellungen konnte ich jedoch herausfinden dass es sich um die > RF4 (RX) und RF5 (TX) handelt. Also UART0 finde ich tatsächlich sehr merkwürdig, denn normalerweise sollte es ja bei UART1 beginnen. Was war das denn für ein Beispiel? Original von Microchip? evtl ein sehr altes? Oder wurde irgendetwas anderes umdefiniert...? Aber um zur aktuellen Frage zu kommen: Hinsichtlich der Bezeichnungen wirfst du gerade glaueb ich nur die Modulbezeichnung und die Pinnahmen durcheinander. Der PIC32MX795L hat 6 UARTS die mit UART1... UART6 benannt sind. (Wobei die höheren Modulnummern abgespeckte Module bezeichnen die nur benutzt werden können wenn die unteren Module auch nur im Basismode ohne Hardwareflusssteuerung verwendet werden) Zu diesen Modulen gehören dann die mit UxTX und UxRX bezeichneten IO Pins. Beispielsweise besitzt das Modul UART1 die IOs !U1CTS, !U1RTS, U1RX, U1TX. Klatec schrieb: > Nun möcht ich ein weiteres Beispiel testen und hier wird der UART1 > verwendet, nachfolgend der Code. Im Library Guide gibt es nur UART1 und > 2 von z.B. der Funktion OpenUART1. > Es muss doch eine Möglichkeit geben die UART's den Hardware Ein- > Ausgängen zuzuorden. In den verschieden Beschreibungen konnte ich auch > keine Hinweise finden. Bitte um Hilfe. Ja, die Gibt es. Zum einen kannst du ja an den Nummern erkennen welche IOs zu welchem UART Modul gehören. UART1 alles was mit U1xxx anfängt, UART2 alles mit U2xxx usw.! Damit man aber nicht alleine anhand des Pin-Diagramms alles durchsuchen muss, was ja auch nicht ganz leicht ist da einige Anschlüsse ja einige Mehrfachfunktionen haben, gibt es im Übersichtsdatenblatt (PIC32MX5XX/6XX/7XX Family Data Sheet)eine entsprechende Tabelle. Die UARTs findest du dabei auf Seite 36. Für die 100Pin TQFP -wenn du das P32ESK hast ist ja ein 100TQFP da verbaut- ist dabei die zweite Spalte relevant. ICh habe dir aber jetzt auch mal nur den für dich relevanten TEil ausgeschnitten und freigestellt angehanden. Für dein konkretes Beispiel wird ja der UART1 verwendet. Relevant sind also die Anschlussfunktionen U1RX und U1TX. In der Tabelle erkennt man dann das dies die Anschlüsse Nummer 52 & 53 sind. Da findet man dann auch die Info welches Modul in deinem vorher erwähnten Beispiel mit dem obskuren UART0 genutzt wurde. Du sagtest du hast die RF4 & RF5 ermittelt, das sind die Anschlüsse 59 & 50. Laut Liste UART2 zugeordnet. (Nur als Hinweis am Rande: Genau genommen ist es nicht ganz korrekt wenn man sagt der UART nutzt RF x..., denn die normale Adressierbare IO Funktion ist nur eine von mehreren möglichen Funktionen. Der PIN kann also ENTWEDER RF x ODER UARTx sein... - Allerdings weiß wohl trotzdem jeder was gemeint ist ;-) und das geht schon in die Erbsenzählerei) Ach Ja: Definiert sind diese Bezeichnungen in den Headerdateien zum Prozessor - beispielsweise P32MX795F512L.H und dem Header zur Libfunktion, hier UART.h Aber das kann man auch einfach als gegeben hinnehmen. Gruß Carsten P.S.: Nur um darauf hinzuweisen: Dieses Demot nutzt die UART Funktionen, allerdings ist es weniger dazu gedacht als UART Beispiel zu dienen sondern soll in erster Linie als Referenz für DMA Transfer herhalten.
Hallo Carsten Danke vorerst für deine ausführliche Antwort. Nach dem du etwas von Seite 36 geschrieben hast, bin ich auf die Suche eines anderen Datenplattes gegeangen, denn ich habe meins von RS-Comp. Beim Microchip habe ich dann jenes gefunden wo die UART so bezeichnet sind wie du beschrieben hast. Ich habe den ext. Stecker auf einen Testprint gelötet und habe nur einige Anschlüsse zur Verfügung und unter diesen (angepasst auf das Beispiel davor) ist auch die U2. Wenn ich nun die U2 nehme sollte das ganze funktionieren. Nachfolgend ein Teil des Codes vom vorigen Beispiel. In der Variable 'int uartN' (wird der Funktion übergeben) ist eine 0 gestanden und ich habe angenommen es handlet sich um die UART0, könnte es auch der Kanal DMAUART 0 sein? Aber dann weiß ich nicht wie die UART Nr. zugewiesen wird. *********************************************************************** DMAUART_RES DMAUARTConfigure( int uartN, DMAUART_CONF_RXTX enRxTx, int bRate, int nBits, DMAUART_PARITY pType, DMAUART_STOP stopBits) // configures vuart uartN // enRxTx - enables RX/TX // bRate - baud rate (must be standard value) // nBits - number of bits (5-9 typ.) // pType - parity (if present, parity odd/even) // stopBits - number of stop bits (1-2) { uart_cfg *p = &u[uartN]; // 1. disable the RX and TX before modifying parameters p->txon = 0; p->rxon = 0; // 2. init input/output masks p->imask=(1<<DMAUART_RX_PIN); p->omask=(1<<DMAUART_TX_PIN); // 3. init FIFO buffers p->ib=ibuffers[uartN]; p->ibr=p->ibw=0; // initially empty p->ob=obuffers[uartN]; p->obr=p->obw=0; // 4. check and set the baudrate p->brate = DMAUART_TBASE/bRate; if (p->brate*bRate != DMAUART_TBASE) { return DMAUART_RES_BR_ERROR; // error if not exact multiple } p->oskip = p->brate * DMAUART_OVS; // 5. check and set the total number of bits p->wsize=nBits; // count start+wsize+parity+stop p->nbits=1+nBits+(stopBits+1); if(pType != DMAUART_PARITY_NONE) { p->nbits += 1; } if ( p->nbits>16) { return DMAUART_RES_BITNO_ERROR; // error too many bits } // 6. store parameters p->parity = (pType != DMAUART_PARITY_NONE); p->odd = (pType & DMAUART_PARITY_ODD) != 0; p->stop = stopBits; // 0 = 1 STOP, 1 = 2 STOP // 7. clear all error flags p->p_error=0; // parity p->f_error=0; // framing p->o_error=0; // overrun // 8. init RX state machine p->bitcount=0; p->majority=0; p->value=0; p->bitvalue=0; p->state=S_START; p->skip=1; // 9. init TX state machine p->tskip = 1; p->tbit = 1; // start high p->tstate = T_IDLE; p->tgap=2; // default gap between consecutive // 10. enable the RX and TX as requested p->txon = (enRxTx & DMAUART_CONF_TX_ENABLE) != 0; p->rxon = (enRxTx & DMAUART_CONF_RX_ENABLE) != 0; DMAUART_IP; mCNClearIntFlag(); mCNOpen(CN_ON, CN_ENABLE(DMAUART_RX_CN), 0); ConfigIntCN(DMAUART_IPL | CHANGE_INT_ON); return DMAUART_RES_OK; } // openDMAUART
So jetzt habe ich vergessen was ich noch fragen wollte. Und zwar sind im Library Guide z.B. nur UART1 und 2 angeführt, siehe Auszug unten. Was ist mit 3, 4, 5, 6? Wenn ich z.B U3 nehme kommt ein Fehler Build. bitte. Danke. ****** OpenUART1 OpenUART2 Description: This macro configures the UART module Include: plib.h Prototype: void OpenUART1(unsigned int config1, unsigned int config2, unsigned int ubrg); void OpenUART2(unsigned int config1, unsigned int config2, unsigned int ubrg); Arguments: config1 *******
Hallo Johann, Klatec schrieb: > In der Variable 'int uartN' (wird der Funktion übergeben) ist eine 0 > gestanden und ich habe angenommen es handlet sich um die UART0, könnte > es auch der Kanal DMAUART 0 sein? > Aber dann weiß ich nicht wie die UART Nr. zugewiesen wird. Wo hast du das Beispiel genau her? Ich kann mich Irren, aber vom Programmierstil sieht es für mich etwas anders aus als die gewohnten Microchip Beispiele. ZUdem müsste ich mir das gesamte Programm ansehen. Wenn ich den von dir geposteten Codeabschnitt ansehe, dann wird in diesem Abschnitt m.E. gar keine DIREKTE Adressierung der Hardware vorgenommen. Wenn ich das jetzt richtig deute scheint die Konfiguration der UART Schnittstelle in einem Array aus Strukturen abgelegt zu sein und diese Funktion dient zur Änderung der dort abgelegten Werte. "uartN" ist dabei meiner Meinung nach nur ein INDEX der angibt welche Struktur aus dem Array nun angesprochen wird. Und der Index beginnt ja immer bei NULL. > uart_cfg *p = &u[uartN]; Hier wird dann wohl der ZEiger auf die jeweilige Struktur erzeugt. Und mit diesem Zeiger wird dann im folgenden auf die einzelnen Elemente der Struktur zugegriffen. Beispielsweise mit: > p->txon = 0; > p->rxon = 0; Die Zuordnung welche jeweilige Struktur(durch den Index adressiert) nun für welche UART Schnittstelle gilt wird dann wohl in der Funktion realisiert die dann die einzelnen Elemente wieder ausliest und zwecks Konfiguration Interpretiert. DAs kann völlig unabhängig von den Indexnummer sein. Aber im genaues dazu zu sagen müsste ich das gaze Programm sehen. (Man könnte das natürlich auch passend machen, dann müsste nur die Nummer NULL unbelegt bleiben was bedeutet das etwas Speicher verschwendet wird da die zugehörige Struktur trotzdem angelegt werden muss) Klatec schrieb: > So jetzt habe ich vergessen was ich noch fragen wollte. > Und zwar sind im Library Guide z.B. nur UART1 und 2 angeführt, siehe > Auszug unten. Was ist mit 3, 4, 5, 6? Wenn ich z.B U3 nehme kommt ein > Fehler Build. Ich habe noch nie mehr als zwei UARTs beim PIC32 benutzt, daher kann ich jetzt auch nur vermuten. Aber ich vermute das in der Lib einfach nur zwei UART Module vorgesehen sind. Wenn dies so ist, dann müsstest du für die Verwendung der höheren UART-Nummern die entsprechenden Routinen selbst bauen. Das ist aber auch keine HExerei. Gruß Carsten
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.