1

这是对这个问题的跟进:显示以前收到的 UART 值

在微控制器上实现循环缓冲区后,指针似乎有问题。

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

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

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

4

2 回答 2

1

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

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

于 2009-12-01T10:33:21.973 回答
1

不应该 IFS0bits.U1RXIF = 0; 设置在例程的末尾?

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

于 2009-12-03T13:14:47.120 回答