linux串口环形缓冲区,能不能讲解下串口环形缓冲区的概念?

有段串口收发程序,看起来费劲,感觉可能是环形收发,能不能普及下思路?

/* 变量声明 */

INT8U * p_uart1SendBuf;                                                                /* 串口发送缓冲区指针 */

INT8U xdata uc_uart1RecBuf[UART1_RECBUF_LEN];                /* 串口接收缓冲区 */

INT8U xdata uc_uart1SendBuf[UART1_SENDBUF_LEN];                /* 串口发送缓冲区 */

volatile INT8U pdata uc_uart1RecBufIndex;                        /* 串口接收缓冲区索引 */

volatile INT8U pdata uc_uart1RecDealIndex;                        /* 串口接收处理索引 */

volatile INT8U pdata uc_uart1SendBufIndex;                        /* 串口发送缓冲区索引 */

volatile INT8U pdata uc_uart1SendDealIndex;                        /* 串口发送处理索引 */

volatile INT8U pdata uc_uart1SendFifoLen;                        /* 发送FIFO队列中数据个数 */

volatile INT16U pdata us_uart1RecFifoLen;                        /* 接收FIFO队列中数据个数 */

volatile BOOLEAN b_uart1SendFifoFlag;                                /* 发送FIFO队列有数据标志 */

volatile BOOLEAN b_uart1RecFifoFlag;                                /* 接收FIFO队列有数据标志 */

BOOLEAN b_uart1Cmd;                                /* 串口1命令标志 */

INT8U        uc_uart1Cmd;                        /* 串口1命令 */

BOOLEAN        b_uart1Sending;                        /* 正在发送标志 */

/* 函数声明 */

void         uart1_ram_init(void);        /* 串口1变量初始化 */

void         timer1_init(void);                /* 波特率发生器(定时器1)初始化 */

void         uart1_init(void);                /* 串口1初始化 */

INT8U *        put_to_uart1_send_fifo(INT8U *,INT8U); //reentrant;        /* 串口1写发送FIFO程序 */

void         put_to_uart1_rec_fifo(void);                        /* 串口1写接收FIFO程序 */

#if TEST_UART1_ISR_PROG == 1

void uart1_isr_prog_test(INT8U);                /* 串口服务程序的测试代码(仅调试时用) */

#endif

/*

******************************************************************************************

** 函数名称 : uart1_ram_init()

** 函数功能 : 串口1使用的变量的初始化

** 入口参数 : 无

** 出口参数 : 无

** 函数说明 : 无

******************************************************************************************

*/

void uart1_ram_init(void)

{

uc_uart1RecBufIndex = 0x00;

uc_uart1RecDealIndex = 0x00;

uc_uart1SendBufIndex = 0x00;

uc_uart1SendDealIndex = 0x00;

uc_uart1SendFifoLen = 0x00;

us_uart1RecFifoLen = 0x00;

b_uart1SendFifoFlag = FALSE;

b_uart1RecFifoFlag = FALSE;

b_uart1Cmd = FALSE;

uc_uart1Cmd = 0x00;

b_uart1Sending = FALSE;

}

/*

******************************************************************************************

** 函数名称 : timer1_init()

** 函数功能 : 定时器1初始化程序

** 入口参数 : 无

** 出口参数 : 无

** 函数说明 : 定时器1作为串口1的波特率发生器

**             定时器1设置1T时钟周期,定时器1使用模式2,8位重载模式

**             同时禁止定时器1中断

******************************************************************************************

*/

void timer1_init(void)

{

AUXR |= TMR1_1T;                        // 设置是1T还是12T(设置为12T)(复位后默认为12T)

TMOD &= ~TMR1_CFG_BIT;                //清除定时器1模式位

TMOD |= TMR1_TIMER | TMR1_8BIT_MODE ;                                //设定定时器1为8位自动重装方式

TL1 = 0xFD;                //设定定时初值

TH1 = 0xFD;                //设定定时器重装值

ET1 = 0;                //禁止定时器1中断

TR1 = 1;                //启动定时器1

}

/*

******************************************************************************************

** 函数名称 : uart1_init()

** 函数功能 : 串口1的初始化程序

** 入口参数 : 无

** 出口参数 : 无

** 函数说明 : 串口1以定时器1作为波特率发生器

**             串口1设置为115200bps(默认),8位数据,无效验位

******************************************************************************************

*/

void uart1_init(void)                //115200bps@11.0592MHz

{

uart1_ram_init();        /* 串口1变量初始化 */

PCON &= 0x7f;                /* 波特率不倍速 */

SCON = 0x50;                /* 8位数据,可变波特率 */

AUXR &= 0xfe;                /* 串口1选择定时器1为波特率发生器 */

timer1_init();                /* 作为波特率发生器的定时器1的初始化 */

/* 设置串口1中断优先级 */

if (UART1_PRIO & 0x02)

{

IPH |= PSH;

}

else

{

IPH &= ~PSH;

}

if (UART1_PRIO & 0x01)

{

PS = 1;

}

else

{

PS = 0;

}

ES = 1;                /* 打开串口1中断 */

}

/*

******************************************************************************************

** 函数名称 : uart1_isr_prog_test()

** 函数功能 : 串口1中断服务程序的测试代码

** 入口参数 : 无

** 出口参数 : 无

** 函数说明 : 无

******************************************************************************************

*/

#if TEST_UART1_ISR_PROG == 1

void uart1_isr_prog_test(INT8U cmd)

{

b_uart1Cmd = TRUE;

uc_uart1Cmd = cmd;

}

#endif

/*

******************************************************************************************

** 函数名称 : uart1_isr()

** 函数功能 : 串口1中断服务程序

** 入口参数 : 无

** 出口参数 : 无

** 函数说明 : 串口1的中断号为4

******************************************************************************************

*/

void uart1_isr(void) interrupt 4

{

if (RI)

{

RI = 0;        /* 清除中断 */

/* 把接收的数据写入FIFO缓冲区 */

if ( (uc_uart1RecDealIndex + UART1_RECBUF_LEN) != uc_uart1RecBufIndex )

{

uc_uart1RecBuf[uc_uart1RecBufIndex++ & (UART1_RECBUF_LEN - 1)] = SBUF;                /* 数据写入接收FIFO队列 */

us_uart1RecFifoLen++;                /* 接收FIFO数量增加 */

b_uart1RecFifoFlag = TRUE;        /* 接收FIFO非空标志 */

/* 如果FIFO缓冲区超过设计值时则产生中断 */

if (us_uart1RecFifoLen >= UART1_REC_INT_LEN)

{

/* 人工触发定时器中断 */

#if UART2_DEAL_PROG_TIMER_INDEX == 0

TF0 = TRUE;

#else

TF1 = TRUE;

#endif

}

}

#if TEST_UART1_ISR_PROG == 1

uart1_isr_prog_test(SBUF);

#endif

}

if(TI)

{

TI = 0;

/* 判断发送FIFO是否为空 */

if (uc_uart1SendFifoLen != 0)

{

SBUF = uc_uart1SendBuf[uc_uart1SendDealIndex++ & (UART1_SENDBUF_LEN - 1)];        /* 发送FIFO中的数据 */

//SBUF = p_uart1SendBuf++;

uc_uart1SendFifoLen--;        /* 发送FIFO数目减1 */

if (!uc_uart1SendFifoLen )        /* 判断发送FIFO是否为空 */

{

b_uart1SendFifoFlag = FALSE;        /* 清除发送FIFO非空标志 */

}

}

else

{

b_uart1Sending = FALSE;

}

}

}

/*

******************************************************************************************

** 函数名称 : put_to_uart1_send_fifo()

** 函数功能 : 串口发送FIFO数据队列程序

** 入口参数 : 需要写入发送FIFO队列的数据指针pBuf,写入数目length

** 出口参数 : 返回剩余的未写入发送FIFO队列的数据的指针

** 返回值定义

**  0 全部数据均写入FIFO

**  其它值 下一个未写入的数据的指针

******************************************************************************************

*/

INT8U *        put_to_uart1_send_fifo(INT8U * pBuf,INT8U length)  //reentrant

{

INT8U        len;

INT8U        cnt;

while(1)

{

len = length;

cnt = 0;

// 数据加入缓冲区

while(length)

{

if ( (uc_uart1SendDealIndex + UART1_SENDBUF_LEN) != uc_uart1SendBufIndex )

{

uc_uart1SendBuf[uc_uart1SendBufIndex++ & (UART1_SENDBUF_LEN - 1)] = *pBuf;

pBuf++;

cnt++;

length--;

}

else

{

break;

}

}

if (len != length)

{

ES = 0;                /* 关串口1中断 */

uc_uart1SendFifoLen += cnt;                        /* 把保存数目叠加进去 */

b_uart1SendFifoFlag = TRUE;                        /* 设置缓冲区有数据标志 */

/* 如果没有正在发送中,则要启动发送 */

if (!b_uart1Sending)

{

start_uart1_send();

}

ES = 1;        /* 开串口1中断 */

}

if (length == 0)

{

break;

}

}

if (!length)

{

return        length;                /* 返回未加入发送FIFO缓冲区的数目 */

}

else

{

return pBuf;

}

}

/* 启动串口1发送 */

void        start_uart1_send(void)

{

if (uc_uart1SendFifoLen != 0)

{

SBUF = uc_uart1SendBuf[uc_uart1SendDealIndex++ & (UART1_SENDBUF_LEN - 1)];        /* 发送FIFO中的数据 */

uc_uart1SendFifoLen--;        /* 发送FIFO数目减1 */

b_uart1Sending = TRUE;

if (!uc_uart1SendFifoLen )        /* 判断发送FIFO是否为空 */

{

b_uart1SendFifoFlag = FALSE;        /* 清除发送FIFO非空标志 */

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值