串口环形缓冲区
文章目录
- 一、串口环形缓冲区概念
- 二、STC12例程
- (1)环形串口缓冲区结构体
- (2)串口环形缓冲区存和取数据
- (3)完整工程demo
一、串口环形缓冲区概念
串口环形缓冲区应用于嵌入式、物联网开发中处理接收串口数据量过大的问题。串口环形缓冲简单理解就是建立一个数组,将串口的数据存到数组里缓存,待空闲时处理。而缓存区越大,那么可以缓存的数据就越多。

环形串口缓冲区建立的数组还要再定义一个头和一个尾。这时有三种情况:
1、当头等于尾时,我们便知道此时环形串口缓冲区无数据,此时不进行读操作。
2、有数据来时,数组存储数据,并且头按数据的长度向前移动,空闲时尾开始取数据,直到尾等于头为止。
3、当头存到数组长度的最后一位时,返回数组第一位开始存数据。
因为头开始存数据到最后一位时,便有返回数组第一位开始存数据,此时我们就可以想象这个数据是一个类似甜甜圈的环形,这便是串口环形缓冲区。
二、STC12例程
要想写串口环形缓冲区,首先需要初始化串口和接收中断处理,保证串口收发正常,初始化串口部分默认大家都懂了,直接略过,我自己编写的例程使用STC12,因为STC12单片机是51单片机的升级版本,几乎学过51单片机的都能看得懂,比较简单,现在企业的开发标配是STM32了,这时只需移植过去即可。我提供两种MCU的串口初始化供大家参考:
STM32F1x固件库函数学习笔记(一)
STC12C5A60S2串口通信(使用独立波特率发生器)
(1)环形串口缓冲区结构体
串口初始化好后,建立一个环形缓冲区结构体
//环形缓冲区结构体
typedef struct
{uint8_t head_count; //头计数uint8_t tail_count; //尾计数uint8_t buf[UART_RX_MAX]; //缓冲区数组
}UART_S;
下一步,我们便可以定义结构体变量初始化结构体
UART_S uart;//定义串口缓冲区结构体变量//串口环形缓冲区初始化
void uart_Buffer_Init(void)
{int i;uart.head_count = 0;uart.tail_count = 0;for(i=0; i<UART_RX_MAX; i++){uart.buf[i] = 0x00;}
}
(2)串口环形缓冲区存和取数据
下面就是串口环形缓冲代码里比较关键的部分,分别写一个放数据和取数据的函数。
放数据的函数逻辑是有数据来时,将数据存入串口环形缓冲区,当存到数组的最后一位时,返回从第一位存起。
取数据的逻辑是先进行一个判断,当判断缓冲区的头和尾不一样时,这时认为缓冲区有数据,我们便开始从缓冲环形缓冲区里取数据,当取到数组最后一位时,返回数组第一位,从第一位开始取数据。
//往缓冲器里放数据
void uart_buf_put(uchar ch)
{uart.buf[uart.head_count++] = ch;if(uart.head_count == UART_RX_MAX){uart.head_count = 0;}
}//判断缓冲区是否有数据
int fifo_is_empty(void)
{if(uart.head_count != uart.tail_count)//判断如果头不等于尾{return 0;//有数据}else return 1;//无数据
}//从缓冲区取数据
int uart_buf_get(uchar *ch)
{if(fifo_is_empty() == 0)//如果有数据{*ch = uart.buf[uart.tail_count++];//取数据if(uart.tail_count == UART_RX_MAX){uart.tail_count = 0;} return 1;//返回成功}else return 0;//返回失败
}
下一步我们再写一个读数据的函数,一个简单的串口环形缓冲区就写完了,我们使用的时候只需把存数据放到中断里,然后在主函数里取数据就行了。
//读数据
void debug_read(void)
{uchar ch;/*如果有数据就一直取,直到取完为至*/while(!fifo_is_empty()){if(uart_buf_get(&ch)){putchar(ch);}}
}void main()
{UartInit();//初始化串口uart_Buffer_Init();//初始化串口环形缓冲区while(1){debug_read();}
}//串口中断处理函数
void uart_Interrupt() interrupt 4
{unsigned char UartData;//单字节串口数据if(RI){RI = 0;UartData = SBUF;uart_buf_put(UartData);//往串口缓冲区存数据}
}
(3)完整工程demo
#include <STC12C5A60S2.h>//宏定义
#define uchar unsigned char
#define uint unsigned int#define UART_RX_MAX 255 //数组最大值//环形缓冲区结构体
typedef struct
{uchar head_count; //头计数uchar tail_count; //尾计数uchar buf[UART_RX_MAX]; //缓冲区数组
}UART_S;UART_S uart;//定义串口缓冲区结构体变量//串口初始化,晶振11.0592,波特率9600
void UartInit(void) //9600bps@11.0592MHz
{PCON &= 0x7F; //波特率不倍速SCON = 0x50; //8位数据,可变波特率AUXR |= 0x04; //独立波特率发生器时钟为Fosc,即1TBRT = 0xDC; //设定独立波特率发生器重装值AUXR |= 0x01; //串口1选择独立波特率发生器为波特率发生器AUXR |= 0x10; //启动独立波特率发生器EA = 1;//开总中断ES = 1;//开串口中断
}//向串口发送一个字符
void putchar(char ch)
{SBUF = ch;while(!TI);TI = 0;
}//向串口发送一段字符串
//void prints(char *s)
//{
// while(*s != '\0')//发送字符串,直到遇到0才结束
// {
// SBUF = *s++;
// while(!TI);
// TI = 0;
// }
//}//串口环形缓冲区初始化
void uart_Buffer_Init(void)
{int i;uart.head_count = 0;uart.tail_count = 0;for(i=0; i<UART_RX_MAX; i++){uart.buf[i] = 0x00;}
}//往缓冲器里放数据
void uart_buf_put(uchar ch)
{uart.buf[uart.head_count++] = ch;if(uart.head_count == UART_RX_MAX){uart.head_count = 0;}
}//判断缓冲区是否有数据
int fifo_is_empty(void)
{if(uart.head_count != uart.tail_count)//判断如果头不等于尾{return 0;//有数据}else return 1;//无数据
}//从缓冲区取数据
int uart_buf_get(uchar *ch)
{if(fifo_is_empty() == 0)//如果有数据{*ch = uart.buf[uart.tail_count++];//取数据if(uart.tail_count == UART_RX_MAX){uart.tail_count = 0;} return 1;//返回成功}else return 0;//返回失败
}//读数据
void debug_read(void)
{uchar ch;/*如果有数据就一直取,直到取完为至*/while(!fifo_is_empty()){if(uart_buf_get(&ch)){putchar(ch);}}
}void main()
{UartInit();//初始化串口uart_Buffer_Init();//初始化串口环形缓冲区while(1){debug_read();}
}//串口中断处理函数
void uart_Interrupt() interrupt 4
{unsigned char UartData;//单字节串口数据if(RI){RI = 0;UartData = SBUF;uart_buf_put(UartData);//往串口缓冲区存数据}
}

相关文章:
串口环形缓冲区
文章目录 一、串口环形缓冲区概念二、STC12例程(1)环形串口缓冲区结构体(2)串口环形缓冲区存和取数据(3)完整工程demo 一、串口环形缓冲区概念 串口环形缓冲区应用于嵌入式、物联网开发中处理接收串口数据…...
【腾讯云 Cloud Studio 实战训练营】基于Cloud Studio完成简易通讯录
目录 🔆Cloud Studio 简介 操作步骤 1.登录 2.创建工作空间 3.初始界面 4.开发空间 5.保存自定义模板 🔆简易通讯录 1.实验要求 2.操作环境 3.源代码介绍 3.1 定义通讯录类 3.2 定义通讯录列表 3.3 添加联系人功能 3.4 修改联系人 3.5 …...
【技术积累】Vue.js中的核心知识
Vue的生命周期 Vue中的生命周期是指组件从创建到销毁的整个过程中,会触发一系列的钩子函数 Vue2中的生命周期 Vue2中的生命周期钩子函数是在组件的不同阶段执行的特定函数。这些钩子函数允许开发者在组件的不同生命周期阶段执行自定义的逻辑。 Vue2中的生命周期钩…...
flutter开发实战-显示本地图片网络图片及缓存目录图片
flutter开发实战-显示本地图片网络图片及缓存目录图片 在最近开发中碰到了需要显示缓存目录图片,这里顺便整理一下,显示本地图片、网络图片、缓存目录图片的方法。 一、工程本地图片显示 1 在项目根目录下创建名为 images文件夹,也可以将i…...
面对未来的算法备案法规:企业需要做哪些准备?
在信息时代,算法已经成为我们生活的一部分,涵盖了诸如搜索引擎、社交媒体、电子商务、广告投放等各个方面。然而,随着算法的广泛应用,其带来的问题也日益凸显。这引发了全球范围内的关注,未来的算法备案法规正在酝酿之…...
iptables的备份和还原
iptables的备份和还原 1、写在命令行当中的都是临时设置 2、把规则配置写在服务的文件当中,形成永久有效 备份:把iptables里面所有的配置都保存在/opt/ky30.bak中 iptables-save > /opt/ky30.bak 例: 默认配置文件在/etc/sysconfig/ip…...
easyUI框架学习
文章目录 一、前言二、引入使用easyUI 三、用法3.1 Dialog(对话框窗口)3.1.1 示例13.1.2 示例2 3.2 Layout(布局)3.2.1 示例1——通过标签创建布局3.2.2 示例2—— 创建嵌套布局 3.3 DateBox(日期输入框)3.…...
加入气压计模组,星斗3号将实现快速三维定位
随着信息技术的飞速发展,人们的生活正在发生巨大改变,人们对基于位置服务的需求越来越迫切,尤其是室内位置服务。 室外定位系统中BDS系统、GPS系统等受室内复杂环境条件限制精度大幅下降甚至失效,难以在室内定位中发挥作用,而室内二维定位技术缺乏高程信息,也难以满足人们对室…...
华为HCIP第二节-------------------------ISIS
IS-IS(Intermediate System to Intermediate System,中间系统到中间系统)是ISO (International Organization for Standardization,国际标准化组织)为它的CLNP(ConnectionLessNetwork Protocol&…...
在Mac系统下搭建Selenium环境并驱动Chrome浏览器
本文带领那些使用Mac的童鞋们实现Selenium驱动Chrome浏览器,虽然会有坑,但是我们可以凭借敏捷的身手躲过。下面就开始吧: 安装selenium 打开终端 ->pip安装(安装命令:pip3 install selenium) 安装浏览…...
通过RPM方式安装,升级,卸载,以及配置使用MySQL
通过RPM方式安装,升级,卸载,以及配置使用MySQL 一、下载 MySQL是一种开源的关系数据库管理系统,被广泛应用于各种业务应用中。本文将讲解如何下载和安装MySQL的rpm安装包。 下载rmp安装包有多种方式: 1、官网下载 …...
六边形架构和分层架构的区别?
六边形架构和分层架构是什么? 六边形架构(Hexagonal Architecture)和分层架构(Layered Architecture)是两种常见的软件架构模式。六边形架构强调将核心业务逻辑与外部依赖解耦,通过接口与外部世界进行通信。…...
一封来自Java学姐的信
黑马JavaEE学科学姐想对学弟学妹们说:勤学如春起之苗,不见其增,日有所长。 辍学如磨刀之石,不见其损,日有所亏。 学科 | JavaEE 校区 | 太原 亲爱的学弟学妹们,在学校“混日子”的时间很快就过去了&…...
Mybatis增强版MyBatis-Flex简介
Mybatis增强版:Mybatis-Plus(使用的最多,老牌Mybatis增强框架,2016年开源)、Fluent-MyBatis(阿里云开发的Mybatis增强框架,来自阿里云.云效产品团队)、Mybatis-Flex。 Flex英文单词意思是灵活,Mybatis-Flex官方文档中多…...
MFC第二十一天 CS架构多页面开发与数据交互、CImageList图像列表介绍 、CListCtrl-SetItem设置列表项的方法
文章目录 CImageList图像列表介绍CListCtrl图标的原理CListCtrl列表图标设置CListCtrl-SetItem设置列表项的方法 CS架构多页面开发与数据交互添加用户实现向导多页数据交互pch.hCLientXq.h CAppCPage1.hCPage1.cppCPage2.hCPage2.cppCWorkerDlg .hCWorkerDlg.cpp 多页数据修改C…...
spring boot--自动化注入组件原理、内嵌tomcat-1
前言 我们知道开发spring boot项目,在启动类上添加注解SpringBootApplication ,然后引入要自动注入的组件依赖,然后现application.properties中加上相应配置就可以自动注入这个组件,那么下面看看自动注入组件是如何实现的 一、S…...
短视频矩阵系统源码---开发技术源码能力
短视频矩阵系统开发涉及到多个领域的技术,包括视频编解码技术、大数据处理技术、音视频传输技术、电子商务及支付技术等。因此,短视频矩阵系统开发人员需要具备扎实的计算机基础知识、出色的编程能力、熟练掌握多种开发工具和框架,并掌握音视…...
可观测之调用链Skywalking
简介 分布式系统的应用程序性能监视工具,专为微服务、云原生架构和基于容器(Docker、K8s、Mesos)架构而设计。提供分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案。 多种监控手段。可以通过语言探针和 service mesh 获得监控…...
linux上适用的反汇编调试软件(对标od)
ubuntu下类似于od软件 经过搜索,在Ubuntu上选用edb-debugger进行动态调试, 下载链接: https://github.com/eteran/edb-debugger 但是依赖反汇编引擎: https://github.com/capstone-engine/capstone 安装 先安装capstone 先下载release的版本…...
基于高斯混合模型聚类的风电场短期功率预测方法(Pythonmatlab代码实现)
目录 💥1 概述 📚2 运行结果 2.1 Python 2.2 Matlab 🎉3 参考文献 🌈4 Matlab代码、数据、文章讲解 💥1 概述 文献来源: 摘要:对任意来流条件下的风电场发电功率进行准确预测,是提高电网对风电…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
