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; }
-----