串口缓冲设计

一般情况下串口的收发都是按一个一个字节收发的。这样做通常会比较麻烦,为了方便使用常常会设计缓冲区使读写变的方便。

在中断里面将数据进行保存

void USART0_IRQHandler(void) interrupt 4
{
    bf_uint8_t oldSFRS;
    bf_uint8_t temp;

    oldSFRS = SFRS;

    temp = EA;
    EA = 0;
    
    SFRS = 0;
    if (RI == 1)
    {
        g_uartRxBuffer[g_uartRxAvailLength++] = SBUF;

        g_uartNewCharRcvd = 1;
        
        //clr_SCON_RI;
        SCON &= CLR_BIT0;
    }

    EA = temp;

    SFRS = oldSFRS;
}

那么我们怎么判断接收到的数据是否已经完全了呢?
我们可以通过设置系统时钟增加的时候来进行处理。

void SysTick_Handler(void) interrupt 5
{
    bf_uint8_t temp;

    temp = EA;
    EA = 0;
    
    s_sysRefClockTick++;

    // TIP: 出于空间资源的开销考虑,在这边直接耦合了串口接收超时检测逻辑,
    //        同时为了直观可读,在这边直接展开实现代码,对应的封装更好的版本有:可以将此代码以宏的形式替换掉。
    {
#if 1
        if (ES == 1)
        {
            if (g_uartNewCharRcvd)
            {
                // 为节省资源,g_uartNewCharRcvd设计为一个bit变量,因此最长超时接近2个tick
                g_uartNewCharRcvd = 0;
            }
            else
            {
                if (0 != g_uartRxAvailLength)
                {
                    // 数据接收超时,表示一帧数据已就绪,关闭串口接收中断,待处理完毕,通过调用UART_ReinitRxBuffer重新等待新数据
                    g_uartDataReady = 1;
                    ES = 0;
                }
            }
        }
#endif    
    }

huu红山竹
4 声望2 粉丝

study