Problème UART Rx Tx dsPIC
Répondre à la discussion
Affichage des résultats 1 à 10 sur 10

Problème UART Rx Tx dsPIC



  1. #1
    AxS44

    Problème UART Rx Tx dsPIC


    ------

    Bonjour,

    Alors voilà je travaille sur un dsPIC33FJ256GP710A avec la carte Explorer 16 et l'ICD 3 sur MPLAB X IDE. J'ai utilisé un code example pour démarrer ce programme et mon objectif est de faire fonctionner l'UART2 afin de communiquer en RS232 vers l'ordinateur. Cela se décompose comme tel :

    -Recevoir des paramètres lorsque le programme démarre

    - Communiquer un ensemble de caractères toutes les secondes

    A priori l'envoi d'informations au PC fonctionne, je l'ai testé en isolant les autres parties du programme. Cela fonctionne grâce au timer 2. Pour info je travaille avec Realterm.

    Mais le problème vient de la réception des paramètres envoyés par le PC. Concrètement, j'attend un bit de start $ pour commencer à enregistrer les valeurs reçues et j'arrête lorsque je reçois le caractère &. Ensuite je les transmet au PC juste pour vérifier, avec le Tx. Mais tout cela ne fonctionne pas et je ne trouve pas pourquoi. Peut-être que ma structure n'est pas autorisée ...

    J'ai du mal à trouver une structure fonctionnelle sur le site de Microchip, beaucoup utilisent le DMA ou bien sont trop simples et n'envoient ou reçoivent qu'un seul caractère à la fois.

    Merci d'avance pour votre aide

    Voici mon code

    Code:
    #include <p33FJ256GP710A.h>
    #include<stdbool.h>
    #define FP 40000000
    #define BAUDRATE 115200
    #define BRGVAL ((FP/BAUDRATE)/16)-1
    
    _FOSCSEL(FNOSC_PRI); 								// utilisation du quartz de 8MHz externe
    _FOSC(FCKSM_CSECMD & OSCIOFNC_OFF  & POSCMD_XT); 	// pin OS2 garder pour l'horlohe et oscillateur XT
    _FWDT(FWDTEN_OFF);
    
    								// Clock Switching is enabled and Fail Safe Clock Monitor is disabled
    								// OSC2 Pin Function: OSC2 is Clock Output
    								// Primary Oscillator Mode: XT Crystanl
    
    #pragma config JTAGEN = OFF
    bool Config_OK=0, Start=0;
    int z=1, i=1, j=0;
    char bufferTx[10];
    char bufferRx[10];
    void init_timer2(void);
    void init_osci(void);
    void InitUART2(void);
    void InitPorts(void);
    
    char temp_buffer;
    
    
    
    int main(void) {
    
    	init_osci();	// This is the PLL settings
    
    	InitUART2();	// Initialize UART2 for 115200,8,N,1 TX/RX
    
    	InitPorts();	// LEDs outputs, Switches Inputs
    
            init_timer2();
    
                                bufferTx[0]='$';
                                bufferTx[1]='1';
                                bufferTx[2]='2';
                                bufferTx[3]='3';
                                bufferTx[4]='4';
                                bufferTx[5]='5';
                                bufferTx[6]='6';
                                bufferTx[7]='7';
                                bufferTx[8]='8';
                                bufferTx[9]='9';
    
                               while(!Config_OK)
    
                                {
                                    while(!U2STAbits.TRMT);
                                    if ((U2STAbits.URXDA==1)&&(Start==0)) // test si bit disponible pour la réception
                                    {
                                        temp_buffer=U2RXREG;
                                        if (temp_buffer=='$')
                                        {
                                            Start=1;                        // On commence à enregistrer les valeurs reçues
                                            bufferRx[0]=temp_buffer;
                                        }
                                    }
                                    if ((U2STAbits.URXDA==1)&&(Start==1))  // test si bit disponible pour la réception et si on détecté le bit de start
                                    {
                                        temp_buffer=U2RXREG;
                                        if (temp_buffer=='&')               // symbole de fin
                                        {
                                            Config_OK=1;
                                        }
                                        bufferRx[i]=temp_buffer;
                                    }
                                    i++;
    
    
                                }
    
                                //on remet les valeurs reçues sur le buffer à envoyer afin de vérifier
                                for (j=0;j<i;j++)
                                {
                                    bufferTx[j]=bufferRx[j];
                                }
                                       if (IEC1bits.U2TXIE == 0)
                                            {
                                                IFS1bits.U2TXIF = 0;
                                                IEC1bits.U2TXIE = 1;
                                                U2TXREG = bufferTx[0];
    
                                            }
            T2CONbits.TON = 1; // on active le timer 2 pour la communication
    
    	while(1) {	// The ever versatile Infinite Loop!
                        }
    }
    
    
    void init_osci(void)
    {
    	//--- configuration de l'oscillateur interne à 40Mhz ---//
    	// utilisation fomrules du datasheet du DSPic33FJ256GP710A --> page 146
    	// Fcy = Fosc / 2 ; Fosc = Fin(M/(N1 N2))
    	// Fin = 8Mhz --> Fosc = 16Mhz --> Fcy = 8Mhz
    	//OSCCONbits.COSC 	= 3;		// sélection de l'oscillateur XT
    	//OSCCONbits.CLKLOCK	= 0;		// l'horloge et la PLL peuvent être modifié
    
    	//CLKDIVbits.ROI	= 0; 			// pas d'effet si il y a interruption
    	//CLKDIVbits.DOZE	= 0; 			// pas de réduction sur l'horloge Fcy /1
    	//CLKDIVbits.DOZEN	= 0;
    	CLKDIVbits.PLLPRE 	= 0; 			// N1 = 2
            CLKDIVbits.PLLPOST 	= 0; 			// N2 = 2
    
    	PLLFBDbits.PLLDIV 	= 38;			// M = 40
    
    	__builtin_write_OSCCONH(0x03); 		// fonction appelant du code assembleur
    										// configuration du registre NOSC (OSCCON) -->
    										// 011 = Primary Oscillator with PLL (XTPLL, HSPLL, ECPLL)
    	__builtin_write_OSCCONL(0x01);		// Active la commutation de la clock
    	while(OSCCONbits.COSC != 0b011); 	//
            // Wait for PLL to lock
            while(OSCCONbits.LOCK!= 1) {};
    }
    
    
    void InitUART2() {
    	// This is an EXAMPLE, so brutal typing goes into explaining all bit sets
    
    	// The HPC16 board has a DB9 connector wired to UART2, so we will
    	// be configuring this port only
    
    	// configure U2MODE
    	U2MODEbits.UARTEN = 0;	// Bit15 TX, RX DISABLED, ENABLE at end of func
    	//U2MODEbits.notimplemented;	// Bit14
    	U2MODEbits.USIDL = 0;	// Bit13 Continue in Idle
    	U2MODEbits.IREN = 0;	// Bit12 No IR translation
    	U2MODEbits.RTSMD = 0;	// Bit11 Simplex Mode
    	//U2MODEbits.notimplemented;	// Bit10
    	U2MODEbits.UEN = 0;		// Bits8,9 TX,RX enabled, CTS,RTS not
    	U2MODEbits.WAKE = 0;	// Bit7 No Wake up (since we don't sleep here)
    	U2MODEbits.LPBACK = 0;	// Bit6 No Loop Back
    	U2MODEbits.ABAUD = 0;	// Bit5 No Autobaud (would require sending '55')
    	U2MODEbits.URXINV = 0;	// Bit4 IdleState = 1  (for dsPIC)
    	U2MODEbits.BRGH = 0;	// Bit3 16 clocks per bit period
    	U2MODEbits.PDSEL = 0;	// Bits1,2 8bit, No Parity
    	U2MODEbits.STSEL = 0;	// Bit0 One Stop Bit
    
    	// Load a value into Baud Rate Generator.  Example is for 9600.
    	// See section 19.3.1 of datasheet.
    	//  U2BRG = (Fcy/(16*BaudRate))-1
    	//  U2BRG = (37M/(16*9600))-1
    	//  U2BRG = 240
    	U2BRG = BRGVAL;	// 40Mhz osc, 9600 Baud,
    
    	// Load all values in for U1STA SFR
    	U2STAbits.UTXISEL1 = 0;	//Bit15 Int when Char is transferred (1/2 config!)
    	U2STAbits.UTXINV = 0;	//Bit14 N/A, IRDA config
    	U2STAbits.UTXISEL0 = 0;	//Bit13 Other half of Bit15
    	//U2STAbits.notimplemented = 0;	//Bit12
    	U2STAbits.UTXBRK = 0;	//Bit11 Disabled
    	U2STAbits.UTXEN = 0;	//Bit10 TX pins controlled by periph
    	U2STAbits.UTXBF = 0;	//Bit9 *Read Only Bit*
    	U2STAbits.TRMT = 0;	//Bit8 *Read Only bit*
    	U2STAbits.URXISEL = 0;	//Bits6,7 Int. on character recieved
    	U2STAbits.ADDEN = 0;	//Bit5 Address Detect Disabled
    	U2STAbits.RIDLE = 0;	//Bit4 *Read Only Bit*
    	U2STAbits.PERR = 0;		//Bit3 *Read Only Bit*
    	U2STAbits.FERR = 0;		//Bit2 *Read Only Bit*
    	U2STAbits.OERR = 0;		//Bit1 *Read Only Bit*
    	U2STAbits.URXDA = 0;	//Bit0 *Read Only Bit*
    
    	IPC7 = 0x4400;	// Mid Range Interrupt Priority level, no urgent reason
    
    	IFS1bits.U2TXIF = 0;	// Clear the Transmit Interrupt Flag
    	IEC1bits.U2TXIE = 0;	// Enable Transmit Interrupts
    	IFS1bits.U2RXIF = 0;	// Clear the Recieve Interrupt Flag
    	IEC1bits.U2RXIE = 1;	// Enable Recieve Interrupts
    
    	U2MODEbits.UARTEN = 1;	// And turn the peripheral on
    
    	U2STAbits.UTXEN = 1;
    	// I think I have the thing working now.
    }
    
    void InitPorts() {
    
        AD1PCFGL=1;
        AD1PCFGH=1;
        TRISD = 0;
    
        TRISA = 0;
    
            
    }
    
     void init_timer2(void) {
    
    	//--- registre de configuration du Timer1 ---//
    	T2CONbits.TON = 0; 			             // désactiver le timer pour la configuration
          
    	//--- registre de configuration du Timer1 ---//
    	T2CONbits.TCS = 0; 			// clock interne
    	//T2CONbits.TSYNC = 0; 		// synchroniser la clock externe
    	T2CONbits.TCKPS = 3; 		// prédivseur régler à 256 --> 8Mhz/256 = 31250Hz --> 32us
    
    	TMR2 = 0; 					// mise à zéro du registre lié au timer
    
    	PR2 = 65000; 				// période du timer --> 100us/32us = 15625
    
     	//--- registres des configurations des interruptions liées au Timer1 ---//
    	IPC1bits.T2IP = 3; 			// choix de la priorité --> ici la plus élevée 7 = 111
    	IFS0bits.T2IF = 0; 			// remise à zéro de l'interruption
    	IEC0bits.T2IE = 1; 			// activation de l'interruption lié au Timer1
    
     	T2CONbits.TON = 0; 			// activer le timer3
    
     }
    
    void __attribute__((__interrupt__,__auto_psv__)) _T2Interrupt(void)
        {
    
        _T2IF = 0;
        _LATA1=~_LATA1;
       while(!U2STAbits.TRMT);
           if (IEC1bits.U2TXIE == 0)
                 {
                      IFS1bits.U2TXIF = 0;
                      IEC1bits.U2TXIE = 1;
                      U2TXREG = bufferTx[0];
    
                 }
        TMR2=0;
        T2CONbits.TON = 1;
    
        }
    
    void __attribute__ ((interrupt, no_auto_psv)) _U2RXInterrupt(void) {
    	//LATA = U2RXREG;
    	IFS1bits.U2RXIF = 0;
    }
    
    void __attribute__ ((interrupt, no_auto_psv)) _U2TXInterrupt(void) {
    
        U2TXREG = bufferTx[z];
    
        z++;
        if(z>=i)
        {
            z=1;
            IEC1bits.U2TXIE = 0;
        }
        IFS1bits.U2TXIF = 0;
    }

    -----

  2. #2
    AxS44

    Re : Problème UART Rx Tx dsPIC

    ====up=====

  3. #3
    spown

    Re : Problème UART Rx Tx dsPIC

    Bonjour/bonsoir AxS44 et tout le groupe,

    Le '$' est envoyé par commande, ou une application? ou ça bloque exactement ?

    Est ce que tu sais c'est quoi le rôle d’interruption et comment ça fonctionne ? ( je t'invite à bien comprendre via les exemples de uchip et leur datasheet, c'est leur point fort d'ailleurs )

    Bref, le traitement d'acquisition de donner doit être fait dans U2RXInterrupt ( le plus bref possible )( pourquoi tu ignores U1RX.. ?? )

    Pour moi l'interruption de TX sert à rien ( dans ton cas bien sur ), tu peux vérifier avec cette commande 'while (U1STAbits.UTXBF); ' que c'est envoyer et that's it !
    Ton code est un peu mal structurer, dans le main quand le pic envoi un bit mais ton i va s' incrémenter!!

    tu veux faire quoi avec ça while(!U2STAbits.TRMT); dans une procédure de réception ??

    Bon j'ai pas tout verifié.... ( le temps passe vite )

  4. #4
    AxS44

    Re : Problème UART Rx Tx dsPIC

    Bonjour spown,

    Le '$' peut-être mis de côté, c'était juste pour représenter le fait que lorsque j'enverrai des informations à mon uC via une interface (que je devrai faire plus tard) il y aura un bit de start pour signaler au uC que la chaîne de caractère arrive (mais tu dois connaître ça).
    Je ne suis pas spécialiste du tout des uC mais c'est le sujet principal de mon stage et j'en ai appris beaucoup déjà. Mais concernant les interruptions je pense avoir suffisamment compris le fonctionnement.
    Et du coup ce matin j'ai essayé une autre structure avec le traitement de la donnée dans l'interruption de Rx, où je met le caractère dans un tableau "buffer". Mais je n'arrive toujours pas à remplir correctement ce buffer, lorsque je vérifie son contenu en mode debugger les caractères ne correspondent pas. Je mettrai mon code à la fin du message.
    En fait j'utilise l'UART 2 car sur la carte explorer il correspond à la sortie RS232 : )
    Et je ne comprend pas comment while (U1STAbits.UTXBF); ' permet de vérifier ? Je sais qu'il indique si le buffer est plein ou non, mais je pensais que le buffer ne se remplissait pas étant donné qu'on prend la valeur dans U2RXREG à chaque fois qu'un caractère arrive il me semble (tout ça n'est pas clair pour moi c'est pour ça que je n'arrive pas à le faire fonctionner).
    Je me doute que ma structure est loin d'être optimisée, en fait ce n'est pas la seule que j'ai essayée donc je l'ai faite un peu rapidement.
    Avec le while(!U2STAbits.TRMT); je pensais attendre que la transmission d'avant soit terminée, par prudence, car j'ai vu ça dans un code example mais peut-être que ça ne concerne que l'envoi Tx ?

    C'est déjà très sympa de ta part, merci beaucoup, ce stage est extrêmement important pour moi et même décisif donc je veux vraiment atteindre l'objectif !

    Alexis

    Code:
    #include <p33FJ256GP710A.h>
    
    #define FP 40000000
    #define BAUDRATE 115200
    #define BRGVAL ((FP/BAUDRATE)/16)-1
    
    _FOSCSEL(FNOSC_PRI); 							
    _FOSC(FCKSM_CSECMD & OSCIOFNC_OFF  & POSCMD_XT); 	
    _FWDT(FWDTEN_OFF);
    
    
    
    #pragma config JTAGEN = OFF
    
    
    int compteur=0;
    char bufferOut[16];
    char buffer;
    
    // Globally Defined Methods
    void IOInit();
    void UARTInit();
    
    int main()
    {
    	IOInit();				 //Initialize Switch and LED I/O
    					
        UARTInit();              //Initialize the UART converter
    
    	while(1)
    	{
    		if (!PORTDbits.RD6)				// poll for pressing S3
    		{
    
    		compteur=0;
    		}
    	}
    
    return 0;
    }
    
    void UARTInit()
    {
    
    	U2BRG = BRGVAL;					// 9600
    
    	U2MODEbits.UARTEN = 1;		// UART2 is Enabled
    	U2MODEbits.USIDL = 0;		// Continue operation at Idlestate
    	U2MODEbits.IREN = 0;		// IrDA En/Decoder is disabled
    	U2MODEbits.RTSMD = 0; 		// flow control mode
    	U2MODEbits.UEN = 0b01;		// UTX, RTX, U2CTS, U2RTS are enable and on use.
    	U2MODEbits.WAKE = 0;		// Wake-up on start bit is enabled
    	U2MODEbits.LPBACK = 0;		// Loop-back is disabled
    	U2MODEbits.ABAUD = 0;		// auto baud is disabled
    
    	U2MODEbits.BRGH = 0;		// low boud rate
    	U2MODEbits.PDSEL = 0b00; 	// 8bit no parity
    	U2MODEbits.STSEL = 0;		// one stop bit
    
    
    	U2STAbits.UTXISEL1 = 0b00;
    	U2STA =0;			// clear TXINV by bit masking
    	U2STAbits.UTXBRK = 0;		// sync break tx is disabled
    	U2STAbits.UTXEN = 1;		//transmit  is enabled
    	U2STAbits.URXISEL = 0b00;	// interrupt flag bit is set when RXBUF is filled whith 1 character
    	U2STAbits.ADDEN = 0;		// address detect mode is disabled
    
    	IFS1bits.U2RXIF = 0;		// clear interrupt flag of rx
    	IEC1bits.U2RXIE = 1;		// enable rx recieved data interrupt
    }
    
    void IOInit()
    {
    	TRISDbits.TRISD6 = 1;		//  PORTD<6> as input, SW3.
    	AD1PCFGL = 0xFFFF;
            AD1PCFGH = 0xFFFF;
    	TRISA = 0xFF00;	        	// PORTA<7:0> as output for LED.
    }
    
    void __attribute__((interrupt, shadow, no_auto_psv)) _U2RXInterrupt()
    {
            IFS1bits.U2RXIF = 0;
    
        	if( compteur < 16 )			// read RX regbuffer if output buffer is not yet full
    	{
    		buffer = U2RXREG;
    		bufferOut[compteur] = buffer;
    		compteur++;
    	}
    	else
            {
                buffer = U2RXREG;
            }						
    }

  5. A voir en vidéo sur Futura
  6. #5
    RISC

    Re : Problème UART Rx Tx dsPIC

    Salut,

    Tu trouveras un exemple de code pour la carte EXPLORER16 qui tourne sur une multitude de processeurs (changer la configuration pour avoir celle de ton dsPIC). De tête il y a un morceau de code pour communiquer avec l'UART :
    http://www.microchip.com/Development...artNO=DM240001
    Dans le family Reference Manual dédié à l'UART il y a un exemple de code pour paramétrer l'UART sans utiliser le DMA
    Tu peux également utiliser les exemples de code pour chacun des périphériques : http://www.microchip.com/codeexamples

    a+
    Dernière modification par RISC ; 20/05/2015 à 20h38.

  7. #6
    spown

    Re : Problème UART Rx Tx dsPIC

    Bonsoir/bonjour,

    Bon pour résumer, t'as dit que l’émission marche ? genre tu reçois des caractères sur ton PC via Realterm ?? ( ton baud rate is 115000 ?)
    (U1STAbits.UTXBF) n'as rien avoir avec U2RXREG ( registre de réception ), prend le temps pour lire ton datasheet.
    Pour l'envoie c'est simple tu peux mettre ça par exemple :

    Code:
    void Send_UART2(char c)
    {
       	while (U2STAbits.UTXBF); // bref, tout simplement  tu dis  à la stupide  puce  d’attendre  jusqu’à qu'elle vide  son registre  d'envoi  puis  tu mettras  ton caractère.  
        U2TXREG = c;
    }
    Avant de commencer à remplir des tableaux , il faut s'assurer que la réception fonctionne correctement avec un seul caractère ( le principe en informatique , c'est d'aller pas à pas )

    Bref , essaye tout simplement ça :

    Code:
    void __attribute__((interrupt, shadow, no_auto_psv)) _U2RXInterrupt()
    {
            buffer = U2RXREG;
            Send_UART2( buffer ); // tu devrais avoir un eco sur  ton écran
    	
           IFS1bits.U2RXIF = 0; 					
    }
    Au final, il te manque TRISF=0x0010; // pour U2RX sur RF4

  8. #7
    AxS44

    Re : Problème UART Rx Tx dsPIC

    Je viens de régler mon problème... Désolé de vous avoir pris du temps pour ça, j'ai seulement oublié l'initialisation de la clock dans le deuxième programme, là où j'ai mis le traitement de la donnée dans l'interruption de Rx. A force de changer mon code j'oublie les bases... Et pour info j'avais bien commencé pas à pas, en envoyant un caractère à la fois, grâce au code example, mais je n'arrivais pas à passer à l'étape suivante.
    J'arrive donc maintenant à remplir mon tableau avec des caractères envoyés chacun leur tour : )
    En revanche une question à propos de ça me préocuppe, car lorsque dans Realterm j'écris plusieurs caractères à la suite dans le panneau d'envoi, la communication ne fonctionne pas bien. Par exemple, si je met la chaîne de caractère "abc" puis que je fais "send ascii", mon tableau va contenir "a / 0 / ? / V / ÿ" dans les cinq premières cases. En gros je suis obligé d'envoyer un caractère à la fois. Est-ce normal ?
    Car dans l'interface que je devrais réaliser, les caractères seront envoyés à la suite dans le programme, et non un par un avec un certain temps entre chaque... Non ?

    Merci encore
    Alexis

  9. #8
    spown

    Re : Problème UART Rx Tx dsPIC

    Vérifies si le 'baud rate' est le même pour le pic et Real. C'Est quoi la priorité pour ton UART ? pour te suivre il faut re-poster le code qui fonctionne avec un par un .

    T'es pas obligé d'envoyer un par un , sauf si ton uC est long par rapport au traitement de donner à la réception. Dans ce cas là, il faut gérer le flux de transmission ( d’ailleurs c'est pour ça il existe CTS et RTS )

  10. #9
    AxS44

    Re : Problème UART Rx Tx dsPIC

    Oui le baud rate est à 115200 pour le dsPIC, Realterm et je l'ai même changé dans les "COM" du PC dans panneau de configuration. Je me doute qu'il y a un soucis mais je ne comprend pas pourquoi, la priorité est à 4 pour Tx et Rx et 3 pour le timer3 qui permet de déclencher Tx. Ci-dessous le code qui fonctionne actuellement, où le Rx s'occupe de recevoir les caractères un par un et de remplir un tableau de 10 caractères, et où le timer 3 déclenche le Tx environ toutes les secondes et affiche ce tableau sur Realterm (au début il est vide, autrement dit rempli de caractères NUL). Merci encore

    Alexis


    Code:
    #include <p33FJ256GP710A.h>
    #include<stdbool.h>
    #define FP 40000000
    #define BAUDRATE 115200
    #define BRGVAL ((FP/BAUDRATE)/16)-1
    
    _FOSCSEL(FNOSC_PRI); 								// utilisation du quartz de 8MHz externe
    _FOSC(FCKSM_CSECMD & OSCIOFNC_OFF  & POSCMD_XT); 	// pin OS2 garder pour l'horlohe et oscillateur XT
    _FWDT(FWDTEN_OFF);
    
    								// Clock Switching is enabled and Fail Safe Clock Monitor is disabled
    								// OSC2 Pin Function: OSC2 is Clock Output
    								// Primary Oscillator Mode: XT Crystanl
    
    #pragma config JTAGEN = OFF
    bool Config_OK=0, Start=0;
    int z=1, i=1, j=0, count_1s=0;
    char bufferTx[10];
    char bufferRx[10];
    void init_timer3(void);
    void init_osci(void);
    void InitUART2(void);
    void InitPorts(void);
    int compteur=0;
    char buffer;
    
    char temp_buffer;
    
    
    
    int main(void) {
    
    	init_osci();	// This is the PLL settings
    
    	InitUART2();	// Initialize UART2 for 9600,8,N,1 TX/RX
    
    	InitPorts();	// LEDs outputs, Switches Inputs
    
            init_timer3();
    
                           
    	while(1) {	// The ever versatile Infinite Loop!
                        }
    }
    
    
    void init_osci(void)
    {
    	//--- configuration de l'oscillateur interne à 40Mhz ---//
    	// utilisation fomrules du datasheet du DSPic33FJ256GP710A --> page 146
    	// Fcy = Fosc / 2 ; Fosc = Fin(M/(N1 N2))
    	// Fin = 8Mhz --> Fosc = 16Mhz --> Fcy = 8Mhz
    	//OSCCONbits.COSC 	= 3;		// sélection de l'oscillateur XT
    	//OSCCONbits.CLKLOCK	= 0;		// l'horloge et la PLL peuvent être modifié
    
    	//CLKDIVbits.ROI	= 0; 			// pas d'effet si il y a interruption
    	//CLKDIVbits.DOZE	= 0; 			// pas de réduction sur l'horloge Fcy /1
    	//CLKDIVbits.DOZEN	= 0;
    	CLKDIVbits.PLLPRE 	= 0; 			// N1 = 2
            CLKDIVbits.PLLPOST 	= 0; 			// N2 = 2
    
    	PLLFBDbits.PLLDIV 	= 38;			// M = 40
    
    	__builtin_write_OSCCONH(0x03); 		// fonction appelant du code assembleur
    										// configuration du registre NOSC (OSCCON) -->
    										// 011 = Primary Oscillator with PLL (XTPLL, HSPLL, ECPLL)
    	__builtin_write_OSCCONL(0x01);		// Active la commutation de la clock
    	while(OSCCONbits.COSC != 0b011); 	//
            // Wait for PLL to lock
            while(OSCCONbits.LOCK!= 1) {};
    }
    
    
    void InitUART2() {
    	// This is an EXAMPLE, so brutal typing goes into explaining all bit sets
    
    	// The HPC16 board has a DB9 connector wired to UART2, so we will
    	// be configuring this port only
    
    	// configure U2MODE
    	U2MODEbits.UARTEN = 0;	// Bit15 TX, RX DISABLED, ENABLE at end of func
    	//U2MODEbits.notimplemented;	// Bit14
    	U2MODEbits.USIDL = 0;	// Bit13 Continue in Idle
    	U2MODEbits.IREN = 0;	// Bit12 No IR translation
    	U2MODEbits.RTSMD = 0;	// Bit11 Simplex Mode
    	//U2MODEbits.notimplemented;	// Bit10
    	U2MODEbits.UEN = 0;		// Bits8,9 TX,RX enabled, CTS,RTS not
    	U2MODEbits.WAKE = 0;	// Bit7 No Wake up (since we don't sleep here)
    	U2MODEbits.LPBACK = 0;	// Bit6 No Loop Back
    	U2MODEbits.ABAUD = 0;	// Bit5 No Autobaud (would require sending '55')
    	U2MODEbits.URXINV = 0;	// Bit4 IdleState = 1  (for dsPIC)
    	U2MODEbits.BRGH = 0;	// Bit3 16 clocks per bit period
    	U2MODEbits.PDSEL = 0;	// Bits1,2 8bit, No Parity
    	U2MODEbits.STSEL = 0;	// Bit0 One Stop Bit
    
    	// Load a value into Baud Rate Generator.  Example is for 9600.
    	// See section 19.3.1 of datasheet.
    	//  U2BRG = (Fcy/(16*BaudRate))-1
    	//  U2BRG = (37M/(16*9600))-1
    	//  U2BRG = 240
    	U2BRG = BRGVAL;	// 40Mhz osc, 9600 Baud,
    
    	// Load all values in for U1STA SFR
    	U2STAbits.UTXISEL1 = 0;	//Bit15 Int when Char is transferred (1/2 config!)
    	U2STAbits.UTXINV = 0;	//Bit14 N/A, IRDA config
    	U2STAbits.UTXISEL0 = 0;	//Bit13 Other half of Bit15
    	//U2STAbits.notimplemented = 0;	//Bit12
    	U2STAbits.UTXBRK = 0;	//Bit11 Disabled
    	U2STAbits.UTXEN = 0;	//Bit10 TX pins controlled by periph
    	U2STAbits.UTXBF = 0;	//Bit9 *Read Only Bit*
    	U2STAbits.TRMT = 0;	//Bit8 *Read Only bit*
    	U2STAbits.URXISEL = 0;	//Bits6,7 Int. on character recieved
    	U2STAbits.ADDEN = 0;	//Bit5 Address Detect Disabled
    	U2STAbits.RIDLE = 0;	//Bit4 *Read Only Bit*
    	U2STAbits.PERR = 0;		//Bit3 *Read Only Bit*
    	U2STAbits.FERR = 0;		//Bit2 *Read Only Bit*
    	U2STAbits.OERR = 0;		//Bit1 *Read Only Bit*
    	U2STAbits.URXDA = 0;	//Bit0 *Read Only Bit*
    
    	IPC7bits.U2RXIP=4;	// Mid Range Interrupt Priority level, no urgent reason
            IPC7bits.U2TXIP=4;
    
    	IFS1bits.U2TXIF = 0;	// Clear the Transmit Interrupt Flag
    	IEC1bits.U2TXIE = 0;	// Enable Transmit Interrupts
    	IFS1bits.U2RXIF = 0;	// Clear the Recieve Interrupt Flag
    	IEC1bits.U2RXIE = 1;	// Enable Recieve Interrupts
    
    	U2MODEbits.UARTEN = 1;	// And turn the peripheral on
    
    	U2STAbits.UTXEN = 1;
    	// I think I have the thing working now.
    }
    
    void InitPorts() {
    
        AD1PCFGL=1;
        AD1PCFGH=1;
        TRISD = 0;
    
        TRISA = 0;
    
            
    }
    
     void init_timer3(void) {
    
    	//--- registre de configuration du Timer1 ---//
    	T3CONbits.TON = 0; 			             // désactiver le timer pour la configuration
          
    	//--- registre de configuration du Timer1 ---//
    	T3CONbits.TCS = 0; 			// clock interne
    	//T2CONbits.TSYNC = 0; 		// synchroniser la clock externe
    	T3CONbits.TCKPS = 3; 		// prédivseur régler à 256 --> 8Mhz/256 = 31250Hz --> 32us
    
    	TMR3 = 0; 					// mise à zéro du registre lié au timer
    
    	PR3 = 15.625; 				// période du timer --> 100us/32us = 15625
    
     	//--- registres des configurations des interruptions liées au Timer1 ---//
    	IPC2bits.T3IP = 3; 			// choix de la priorité --> ici la plus élevée 7 = 111
    	IFS0bits.T3IF = 0; 			// remise à zéro de l'interruption
    	IEC0bits.T3IE = 1; 			// activation de l'interruption lié au Timer1
    
     	T3CONbits.TON = 1; 			// activer le timer3
    
     }
    
    void __attribute__((__interrupt__,__auto_psv__)) _T3Interrupt(void)
        {
        int i;
        _T3IF = 0;
       
        count_1s++;
    
        for (i=0;i<10;i++)
        {
            bufferTx[i]=bufferRx[i];
        }
        if (count_1s==1000)
        {
            _LATA0=1;
       while(!U2STAbits.TRMT);
           if (IEC1bits.U2TXIE == 0)
                 {
                      IFS1bits.U2TXIF = 0;
                      IEC1bits.U2TXIE = 1;
                      U2TXREG = bufferTx[0];
                      _LATA1=~_LATA1;
                 }
       count_1s=0;
        }
       
        TMR3=0;
        T3CONbits.TON = 1;
    
        }
    
    void __attribute__ ((interrupt, no_auto_psv)) _U2RXInterrupt(void) {
    	//LATA = U2RXREG;
    	IFS1bits.U2RXIF = 0;
              				
    	buffer = U2RXREG;
    	bufferRx[compteur] = buffer;
    	compteur++;
    
            if( compteur>=10 )
                    {
                        compteur=0;
                    }
    }
    
    void __attribute__ ((interrupt, no_auto_psv)) _U2TXInterrupt(void) {
    
        U2TXREG = bufferTx[z];
    
        z++;
        if(z>=10)
        {
            _LATA0=0;
            z=1;
            IEC1bits.U2TXIE = 0;
        }
        IFS1bits.U2TXIF = 0;
    }
    Dernière modification par AxS44 ; 26/05/2015 à 13h29.

  11. #10
    AxS44

    Re : Problème UART Rx Tx dsPIC

    Finalement le problème est résolu, j'ai réessayé et je ne sais pas vraiment ce que j'ai changé mais ça fonctionne. J'ai réglé le baud rate dans les deux onglets où c'est possible, "Port" et "Echo Port". Je n'avais pas touché à ce dernier avant mais je ne voyais pas son utilité, peut-être qu'il était nécessaire de le régler aussi. Merci encore de votre aide

    Alexis

Discussions similaires

  1. Dspic + UART + dma et décalage
    Par nordiste dans le forum Électronique
    Réponses: 15
    Dernier message: 22/08/2012, 07h40
  2. Problème avec le dsPIC
    Par invite5989396e dans le forum Électronique
    Réponses: 18
    Dernier message: 08/04/2010, 17h38
  3. [dsPIC]-la famille des dsPIC chauffe t'elle??
    Par jorg1n dans le forum Électronique
    Réponses: 7
    Dernier message: 02/07/2009, 06h50
  4. Programmation dsPIC sous mikroC for dsPIC
    Par invitec63490c6 dans le forum Électronique
    Réponses: 8
    Dernier message: 10/03/2009, 08h31
  5. Problème UART AVR
    Par inviteee2a87e5 dans le forum Électronique
    Réponses: 2
    Dernier message: 07/01/2009, 09h27
Découvrez nos comparatifs produits sur l'informatique et les technologies.