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非空标志 */
}
}
}
linux串口环形缓冲区,能不能讲解下串口环形缓冲区的概念?相关推荐
- Linux下串口编程入门
1. 串口简介 串行口是计算机一种常用的接口,具有连接线少,通讯简单,得到广泛的使用.常用的串口是 RS-232-C 接口(又称 EIA RS-232-C)它是在 1970 年由美国电子工业协会(EI ...
- Linux下串口编制【转】
本文转载自:http://www.cnblogs.com/colife/p/5531093.html 串行口是计算机一种常用的接口,具有连接线少,通讯简单,得到广泛的使用.常用的串口是RS-232-C ...
- DSP在SYS/BIOS下串口(UART)接收之环形队列
众所周知串口收/发数据是以字节为单位的位传输通信协议. 当串口接收数据按固定数据长度接收:则可能会由于传输过程中出现丢数据,发送端少发数据或多发数据导致接收错位无法正确获取数据. 为了解决数据接收错位 ...
- linux串口read几次才能接收完,linux下串口读写有关问题 read 一次读不全
当前位置:我的异常网» Linux/Unix » linux下串口读写有关问题 read 一次读不全 linux下串口读写有关问题 read 一次读不全 www.myexceptions.net 网 ...
- linux下串口通信程序,关于Linux下串口通信的一点心得
1. 打开串口 与其他的关于设备编程的方法一样,在 Linux 下,操作.控制串口也是通过操作起设备文件进行的.在 Linux 下,串口的设备文件是 /dev/ttyS0 或 /dev/ttyS1 等 ...
- linux实验串行端口程序设计,Linux下串口编程心得(转)
最近一段时间,需要完成项目中关于Linux下使用串口的一个部分,现在开帖记录过程点滴. 项目的要求是这样的,Qt应用程序主要完成数据采集和发送功能,一开始在google中海搜关键字"Qt串口 ...
- Linux下串口编程遇 接收数据错误问题及原因
近日在调试串口的时候发现,另一设备向我ARM板的串口发送0x0d,我接收之后变成了0x0a,这是问题一:另外当对方向我发送一串数据,如果其中有0x11,那么我总是漏收此数,这是问题二. 由于问题莫名其 ...
- Linux下串口编程基础
串口知识 串行接口 (SerialInterface) 是指数据一位一位地顺序传送,其特点是通信线路简单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了成本,特别适用 ...
- Linux下C语言串口应用编程,Linux下串口C语言编程
Linux下串口C语言编程 (5页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.9 积分 串口操作代码#include #include #inclu ...
最新文章
- JavaScript高级程序设计(1)
- Vue 字面量语法 vs 动态语法
- php json_encode后乱码,php json_encode 中文乱码的解决方法
- OpenStack Fernet Key Rotate
- [leetcode] 144.二叉树的前序遍历
- windows bat 批处理 !vm 合并快播文件
- ios 点生成线路 百度地图_iOS SDK | 百度地图API SDK
- Thunderspy: 7个硬件漏洞,影响9年来所有安装 Thunderbolt 的电脑
- systrace简介
- android view 3d,Android 使用ViewPager打造3D画廊效果
- ps剪贴蒙版教程(ps创建剪贴蒙版步骤)
- php中eregi,PHP 函数 eregi()
- 费马大定理四分之一解决
- Pycharm debug时变量无法立即显示,正在评估(evaluating )...
- 2021年过了大半了,脑机接口取得哪些进展?
- 越狱Season 1-Episode 9: Tweener
- python f{} 字符串用法详解(含冒号用法)
- 全球投资者聚焦阿里巴巴新零售:天猫力量定义商业未来
- MySQL经典练习题,看看你会几道?
- java8u221_jdk8u221下载|jdk-8u221-windows-x64 官方免费版 下载_当下软件园_软件下载