【问题标题】:Circular buffer pointer irregularities循环缓冲区指针异常
【发布时间】:2009-12-01 02:38:20
【问题描述】:

这是对这个问题的跟进: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];
        }
    }
}

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

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

【问题讨论】:

  • 好吧,我没能及时找到解决方案。所以我只是在 T3Interrupt 中调用了大约 7 次“Detect_Cmd_RXD”。感谢您的回复。

标签: pointers microcontroller microchip circular-buffer uart


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2015-02-04
      • 2017-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多