圆形缓冲区指针不规则

时间:2009-12-01 02:38:21

标签: pointers microcontroller microchip circular-buffer uart

这是对此问题的跟进:Display previously received UART values

在微控制器上实现circular buffer之后,似乎指针存在问题。

在RS-232上发送: ADE1234
收到(缓冲区= 8): E24AE2 / E2AE24 (两者之间翻转) 已接收(缓冲区= 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];

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

接收中断

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

每1/256秒调用一次Detect_Cmd_RXD。在此期间,UART接收缓冲区中至少会发送7个值。

写入过程是否可能如此之快以至于它赶上了读指针?除了更频繁地调用Detect_Cmd_RXD之外,我还能做些什么来解决这个问题?

2 个答案:

答案 0 :(得分:1)

第一步:如果缓冲区溢出,则在中断例程中设置一个标志,并检查Detect_Cmd_RXD例程中是否超出。了解更改缓冲区大小如何影响溢出次数。

第二步:如果你达到一个缓冲区大小,没有溢出,但仍然有腐败,请仔细看看中断例程。 UART对访问寄存器的速度或操作顺序非常敏感。检查硬件数据表并验证您是否正确读取它 - 更好的是,找到一些与您想要做的类似的示例代码。当缓冲区大小为32时,重复的字符可能是您在状态位有机会稳定下来之前读取数据寄存器两次。

答案 1 :(得分:1)

不应该IFS0bits.U1RXIF = 0;在例程结束时设置?

Afaik它结束了中断并允许一个新的。