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

/* 变量声明 */

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非空标志 */

}

}

}

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

  1. Linux下串口编程入门

    1. 串口简介 串行口是计算机一种常用的接口,具有连接线少,通讯简单,得到广泛的使用.常用的串口是 RS-232-C 接口(又称 EIA RS-232-C)它是在 1970 年由美国电子工业协会(EI ...

  2. Linux下串口编制【转】

    本文转载自:http://www.cnblogs.com/colife/p/5531093.html 串行口是计算机一种常用的接口,具有连接线少,通讯简单,得到广泛的使用.常用的串口是RS-232-C ...

  3. DSP在SYS/BIOS下串口(UART)接收之环形队列

    众所周知串口收/发数据是以字节为单位的位传输通信协议. 当串口接收数据按固定数据长度接收:则可能会由于传输过程中出现丢数据,发送端少发数据或多发数据导致接收错位无法正确获取数据. 为了解决数据接收错位 ...

  4. linux串口read几次才能接收完,linux下串口读写有关问题 read 一次读不全

    当前位置:我的异常网» Linux/Unix » linux下串口读写有关问题 read 一次读不全 linux下串口读写有关问题 read 一次读不全 www.myexceptions.net  网 ...

  5. linux下串口通信程序,关于Linux下串口通信的一点心得

    1. 打开串口 与其他的关于设备编程的方法一样,在 Linux 下,操作.控制串口也是通过操作起设备文件进行的.在 Linux 下,串口的设备文件是 /dev/ttyS0 或 /dev/ttyS1 等 ...

  6. linux实验串行端口程序设计,Linux下串口编程心得(转)

    最近一段时间,需要完成项目中关于Linux下使用串口的一个部分,现在开帖记录过程点滴. 项目的要求是这样的,Qt应用程序主要完成数据采集和发送功能,一开始在google中海搜关键字"Qt串口 ...

  7. Linux下串口编程遇 接收数据错误问题及原因

    近日在调试串口的时候发现,另一设备向我ARM板的串口发送0x0d,我接收之后变成了0x0a,这是问题一:另外当对方向我发送一串数据,如果其中有0x11,那么我总是漏收此数,这是问题二. 由于问题莫名其 ...

  8. Linux下串口编程基础

    串口知识 串行接口 (SerialInterface) 是指数据一位一位地顺序传送,其特点是通信线路简单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了成本,特别适用 ...

  9. Linux下C语言串口应用编程,Linux下串口C语言编程

    Linux下串口C语言编程 (5页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.9 积分 串口操作代码#include #include #inclu ...

最新文章

  1. JavaScript高级程序设计(1)
  2. Vue 字面量语法 vs 动态语法
  3. php json_encode后乱码,php json_encode 中文乱码的解决方法
  4. OpenStack Fernet Key Rotate
  5. [leetcode] 144.二叉树的前序遍历
  6. windows bat 批处理 !vm 合并快播文件
  7. ios 点生成线路 百度地图_iOS SDK | 百度地图API SDK
  8. Thunderspy: 7个硬件漏洞,影响9年来所有安装 Thunderbolt 的电脑
  9. systrace简介
  10. android view 3d,Android 使用ViewPager打造3D画廊效果
  11. ps剪贴蒙版教程(ps创建剪贴蒙版步骤)
  12. php中eregi,PHP 函数 eregi()
  13. 费马大定理四分之一解决
  14. Pycharm debug时变量无法立即显示,正在评估(evaluating )...
  15. 2021年过了大半了,脑机接口取得哪些进展?
  16. 越狱Season 1-Episode 9: Tweener
  17. python f{} 字符串用法详解(含冒号用法)
  18. 全球投资者聚焦阿里巴巴新零售:天猫力量定义商业未来
  19. MySQL经典练习题,看看你会几道?
  20. java8u221_jdk8u221下载|jdk-8u221-windows-x64 官方免费版 下载_当下软件园_软件下载

热门文章

  1. Python re模块将字符串分割为列表
  2. Android之帮助文档
  3. 计算机缺考学校知道吗,计算机二级机考缺考成绩单会不会显示缺考啊
  4. 博客园修改页面显示样式
  5. 微信小程序用户拒绝授权之后重新调用
  6. Power Query获取整理多来源数据
  7. 一个逐页抓取网站小说的爬虫
  8. Java多线程系列--“JUC锁”10之 CyclicBarrier原理和示例
  9. Android HorizontalScrollView布局
  10. drupal ajax json异步调用