2009-12-01 6 views
1

Ceci est une suite à cette question: Display previously received UART values. Après la mise en œuvre d'un circular buffer sur le microcontrôleur, il semble qu'il y ait un problème avec les pointeurs.Irrégularités de pointeur de tampon circulaire

envoyé sur RS-232: ADE1234
Reçu (tampon = 8): E24AE2/E2AE24 (flips entre les deux) Reçu (tampon = 16): D234E1 (A est ignoré, étant donné que il est un octet de synchro)
reçu (RX_BufSize = 32): DE1223/DEE123/DE1234/DE12E1 (retourne au hasard)
prévue reçoivent:

DE1234

Initialisation

// Source: Thème 207 BTS électronique – Académie de Strasbourg 
#define RX_BufSize 8   // Taille du Buffer_RX 
char Buffer_RX[RX_BufSize];  // Buffer circulaire de réception 
char *ptrRX_WRdata = Buffer_RX; // Pointeur d'écriture dans Buffer_RX 
char *ptrRX_RDdata = Buffer_RX; // Pointeur de lecture dans Buffer_RX 
unsigned char Buffer_Cmd[7]; 

valeurs de débogage affichées sur l'écran LCD

//Printed debug values. Decoded output is seen via U2buf 
disp_string(-62, 17, 0, "Ply2"); 
char U2buf[] = {slave_command, slave_pal_d, slave_bal_x, 
       slave_bal_y, slave_point_a, slave_point_b, '\0'}; 
disp_string(-37, 17, 1, U2buf); 

char U3buf[] = {Buffer_RX[0], Buffer_RX[1], Buffer_RX[2], 
        Buffer_RX[3], Buffer_RX[4], Buffer_RX[5], 
        Buffer_RX[6], Buffer_RX[7], '\0'}; 
disp_string(-37, 27, 1, U3buf); 

char U4buf[] = {Buffer_Cmd[0], Buffer_Cmd[1], Buffer_Cmd[2], 
        Buffer_Cmd[3], Buffer_Cmd[4], Buffer_Cmd[5], 
        Buffer_Cmd[6], '\0'}; 
disp_string(-37, 7, 1, U4buf); 

interruption de réception

void _ISR _NOPSV _U1RXInterrupt(void){ 
IFS0bits.U1RXIF = 0;  
while(U1STAbits.URXDA){ 
     *ptrRX_WRdata++=U1RXREG; 
     if (ptrRX_WRdata == Buffer_RX+RX_BufSize) ptrRX_WRdata = Buffer_RX; 
    } 
    if (U1STAbits.OERR){ 
     U1STAbits.OERR = 0; 
    } 
} 

Fonctions de la source

int ReadRXD(char *c){ 
    if (ptrRX_RDdata==ptrRX_WRdata) return(0); // Pas de caractère reçu 
    else{ 
     *c=*ptrRX_RDdata++; 
     if (ptrRX_RDdata==Buffer_RX+RX_BufSize) ptrRX_RDdata=Buffer_RX; 
     return(1); 
    } 
} 


void Detect_Cmd_RXD(void){ 
    int i; 
    char c; 
    if (!ReadRXD(&c)) return; 
    ACL_XY_AFFICHER_CARACTERE(5, 3,256+'Z',1); 
    ACL_XY_AFFICHER_CARACTERE(25, 3,256+c,1); 
    for (i=1; i<7; i++) Buffer_Cmd[i-1]=Buffer_Cmd[i]; 
    Buffer_Cmd[6]=c; 
    if (Buffer_Cmd[0]=='A'){ //&& (Buffer_Cmd[4]==0xAA)){ 
     ACL_XY_AFFICHER_CARACTERE(15, 3,256+'Q',1); 

     slave_command = Buffer_Cmd[1]; 
     slave_pal_d = Buffer_Cmd[2]; 
     if (system_player == 2){ 
      slave_bal_x = Buffer_Cmd[3]; 
      slave_bal_y = Buffer_Cmd[4]; 
      slave_point_a = Buffer_Cmd[5]; 
      slave_point_b = Buffer_Cmd[6]; 
     } 
    } 
} 

Detect_Cmd_RXD est appelé à chaque 1/256e de seconde. Pendant ce temps, au moins 7 valeurs auront été envoyées dans le tampon de réception UART.

Est-il possible que le processus d'écriture soit si rapide qu'il rattrape le pointeur de lecture? Que puis-je faire pour résoudre ce problème en plus d'appeler Detect_Cmd_RXD plus souvent?

+2

utiliser un mécanisme de verrouillage? –

+0

Quel est votre débit en bauds? – mocj

+0

Eh bien, je ne pouvais pas trouver une solution à temps. J'ai donc appelé "Detect_Cmd_RXD" environ 7 fois dans T3Interrupt. Merci pour vos réponses. – JcMaco

Répondre

1

Première étape: Définir un indicateur dans la routine d'interruption si le tampon dépasse et vérifier les dépassements dans la routine Detect_Cmd_RXD. Voyez comment changer la taille de la mémoire tampon affecte le nombre de dépassements.

Deuxième étape: Si vous arrivez à une taille de buffer où il n'y a pas de dépassement, et où la corruption persiste, jetez un coup d'œil à la routine d'interruption. Les UART peuvent être très sensibles à la rapidité avec laquelle vous accédez à leurs registres ou à l'ordre des opérations. Vérifiez la fiche de données du matériel et vérifiez que vous la lisez correctement - mieux encore, trouvez un exemple de code qui fait des choses similaires à ce que vous voulez faire. Les caractères répétés lorsque la taille de la mémoire tampon est 32 peuvent être que vous lisez le registre de données deux fois avant que le bit d'état ait eu une chance de s'installer.

1

Ne devrait pas IFS0bits.U1RXIF = 0; être fixé à la fin de la routine? Afaik met fin à l'interruption et permet une nouvelle.

Questions connexes