有段串口收发程序,看起来费劲,感觉可能是环形收发,能不能普及下思路?
/* 变量声明 */
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非空标志 */
}
}
}