【问题标题】:How to receive a string properly from UART如何从 UART 正确接收字符串
【发布时间】:2012-04-20 10:40:08
【问题描述】:

我发送这样的字符串: $13,-14,283,4,-4,17,6,-240,-180#

但是由于缓冲区“过载”而没有显示,我如何才能接收整个字符串,或者如何在读取每个字节后清除它?

// get a character string 
char *getsU2(char *s, int len) { 
    char *p = s; // copy the buffer pointer 
    do {
        *s = getU2(); // get a new character 
        if (( *s=='\r') || (*s=='\n')) // end of line... 
            break; // end the loop s++;

        // increment the buffer pointer 
        len--;
    } while (len>1); // until buffer is full 

    *s = '\0'; // null terminate the string 

    return p; // return buffer pointer
} 


// get a character string
char *getsU2(char *s, int len) { 
    char *p = s; // copy the buffer pointer 
    do {
        *s = getU2(); // get a new character 

        if (( *s=='\r') || (*s=='\n')) // end of line... 
            break; // end the loop 

        s++;     

        // increment the buffer pointer 
        len--; 
    } while (len>1); // until buffer is full

    *s = '\0'; // null terminate the string      

    return p;    // return buffer pointer
}



char getU2(void) { 
if(U2STAbits.OERR == 1) 
{     U2STAbits.OERR = 0; } 
while (!U2STAbits.URXDA);    // wait for new character to arrive return U2RXREG;
                             // read character from the receive buffer }

getsU2(buffer,sizeof(buffer));

【问题讨论】:

  • 请熟悉缩进(为你做了一个编辑),为自己选择一个好的编码风格。
  • 这是用于微控制器的吗?什么时候出现“缓冲区过载”的错误?
  • 看起来 getU2 代码片段可能不完整。我没有看到退货声明。 “buffer”变量的声明是什么?

标签: c string buffer pic uart


【解决方案1】:

尝试使用 UART 接收中断。下面的代码适用于 PIC24H;适当修改。

在你的初始化函数中:

IFS0bits.U1RXIF = 0;        // clear rx interrupt flag
IFS0bits.U1TXIF = 0;        // clear tx interrupt flag

IEC0bits.U1RXIE = 1;        // enable Rx interrupts
IPC2bits.U1RXIP = 1;
IEC0bits.U1TXIE = 1;        // enable tx interrupts
IPC3bits.U1TXIP = 1;   

创建一个将字节放入缓冲区或队列的中断处理程序:

void __attribute__((__interrupt__, auto_psv)) _U1RXInterrupt(void)
{
    char bReceived;

    // Receive Data Ready
    // there is a 4 byte hardware Rx fifo, so we must be sure to get all read bytes    
    while (U1STAbits.URXDA)
    {
        bReceived = U1RXREG;

        // only usethe data if there was no error
        if ((U1STAbits.PERR == 0) && (U1STAbits.FERR == 0))
        {
             // Put your data into a queue
             FIFOPut(bReceived);

        }

    }    

    IFS0bits.U1RXIF = 0;        // clear rx interrupt flag 
}

您的队列代码如下所示:

#define FIFO_SIZE 64

char pbBuffer[FIFO_SIZE];
char *pbPut;
char *pbGet;

void FIFOInit(void)
{
    pbPut = pbBuffer;
    pbGet = pbBuffer;
}

void FIFOPut(char bInput)
{
    *pbPut = bInput;
    pbPut++;

    if (pbPut >= (pbBuffer + FIFO_SIZE))
        pbPut = pbBuffer;
}

char FIFOGet(void)
{
    char bReturn;

    bReturn = *pbGet;
    pbGet++;

    if (pbGet>= (pbBuffer + FIFO_SIZE))
        pbGet= pbBuffer;
}   

显然,应该加强 FIFO 功能以防止溢出、在空队列上返回错误等。

【讨论】:

  • 此外,您应该在中断和正常代码之间共享的任何变量上添加 volatile 关键字。 (这里不是问题,因为变量 pbBuffer 从未被编辑过,但一般来说)
猜你喜欢
  • 1970-01-01
  • 2015-12-17
  • 2017-05-11
  • 2017-10-20
  • 1970-01-01
  • 1970-01-01
  • 2018-12-16
  • 2021-07-17
  • 1970-01-01
相关资源
最近更新 更多