2009-12-01 11 views
1

Это вопрос по этому вопросу: Display previously received UART values.Ошибки указателя кругового буфера

После реализации на микроконтроллере circular buffer, кажется, что проблема с указателями.

Отправлено RS-232: ADE1234
Полученное (буфер = 8): E24AE2/E2AE24 (переворачивается между двумя) Received (буфер = 16): D234E1 (A пропускается, так как это синхро байт)
Полученное (RX_BufSize = 32): DE1223/DEE123/DE1234/DE12E1 (переворачивает случайным образом)
Ожидаемое получить: DE1234

инициализации значения

// 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]; 

отладки на ЖК-дисплее

//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); 

Прием прерывания

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

функции от источника

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 называется каждый 1/256-й секунды. За это время в буфере приема UART будет отправлено не менее 7 значений.

Возможно ли, что процесс записи будет настолько быстрым, что он поймает курсор чтения? Что я могу сделать для решения этой проблемы, кроме вызова Detect_Cmd_RXD чаще?

+2

использование блокировка механизм? –

+0

Какова ваша скорость в бодах? – mocj

+0

Ну, вовремя не получилось. Поэтому я только что вызвал «Detect_Cmd_RXD» около 7 раз в T3Interrupt. Спасибо за ваши ответы. – JcMaco

ответ

1

Первый шаг: установить флаг в процедуре прерывания, если буфер переполнен, и проверить перерасход в подпрограмме Detect_Cmd_RXD. Посмотрите, как изменение размера буфера влияет на количество перерасходов.

Второй шаг: если вы доберетесь до размера буфера, в котором нет перерасхода, и все еще есть коррупция, внимательно ознакомьтесь с процедурой прерывания. UART могут быть весьма чувствительны к тому, как быстро вы получаете доступ к своим регистрам или к порядку операций. Проверьте техническое описание оборудования и убедитесь, что вы читаете его правильно - еще лучше, найдите код примера, который делает похожие вещи, что вы хотите сделать. Повторяющиеся символы, когда размер буфера равен 32, может быть, вы дважды читаете регистр данных, прежде чем бит состояния сможет остановиться.

1

Не должно IFS0bits.U1RXIF = 0; быть установленным в конце процедуры?

Afaik завершает прерывание и разрешает новый.

 Смежные вопросы

  • Нет связанных вопросов^_^