当前位置: 首页 > news >正文

串口环形缓冲区

文章目录

  • 一、串口环形缓冲区概念
  • 二、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例程&#xff08;1&#xff09;环形串口缓冲区结构体&#xff08;2&#xff09;串口环形缓冲区存和取数据&#xff08;3&#xff09;完整工程demo 一、串口环形缓冲区概念 串口环形缓冲区应用于嵌入式、物联网开发中处理接收串口数据…...

【腾讯云 Cloud Studio 实战训练营】基于Cloud Studio完成简易通讯录

目录 &#x1f506;Cloud Studio 简介 操作步骤 1.登录 2.创建工作空间 3.初始界面 4.开发空间 5.保存自定义模板 &#x1f506;简易通讯录 1.实验要求 2.操作环境 3.源代码介绍 3.1 定义通讯录类 3.2 定义通讯录列表 3.3 添加联系人功能 3.4 修改联系人 3.5 …...

【技术积累】Vue.js中的核心知识

Vue的生命周期 Vue中的生命周期是指组件从创建到销毁的整个过程中&#xff0c;会触发一系列的钩子函数 Vue2中的生命周期 Vue2中的生命周期钩子函数是在组件的不同阶段执行的特定函数。这些钩子函数允许开发者在组件的不同生命周期阶段执行自定义的逻辑。 Vue2中的生命周期钩…...

flutter开发实战-显示本地图片网络图片及缓存目录图片

flutter开发实战-显示本地图片网络图片及缓存目录图片 在最近开发中碰到了需要显示缓存目录图片&#xff0c;这里顺便整理一下&#xff0c;显示本地图片、网络图片、缓存目录图片的方法。 一、工程本地图片显示 1 在项目根目录下创建名为 images文件夹&#xff0c;也可以将i…...

面对未来的算法备案法规:企业需要做哪些准备?

在信息时代&#xff0c;算法已经成为我们生活的一部分&#xff0c;涵盖了诸如搜索引擎、社交媒体、电子商务、广告投放等各个方面。然而&#xff0c;随着算法的广泛应用&#xff0c;其带来的问题也日益凸显。这引发了全球范围内的关注&#xff0c;未来的算法备案法规正在酝酿之…...

iptables的备份和还原

iptables的备份和还原 1、写在命令行当中的都是临时设置 2、把规则配置写在服务的文件当中&#xff0c;形成永久有效 备份&#xff1a;把iptables里面所有的配置都保存在/opt/ky30.bak中 iptables-save > /opt/ky30.bak 例&#xff1a; 默认配置文件在/etc/sysconfig/ip…...

easyUI框架学习

文章目录 一、前言二、引入使用easyUI 三、用法3.1 Dialog&#xff08;对话框窗口&#xff09;3.1.1 示例13.1.2 示例2 3.2 Layout&#xff08;布局&#xff09;3.2.1 示例1——通过标签创建布局3.2.2 示例2—— 创建嵌套布局 3.3 DateBox&#xff08;日期输入框&#xff09;3.…...

加入气压计模组,星斗3号将实现快速三维定位

随着信息技术的飞速发展,人们的生活正在发生巨大改变,人们对基于位置服务的需求越来越迫切,尤其是室内位置服务。 室外定位系统中BDS系统、GPS系统等受室内复杂环境条件限制精度大幅下降甚至失效,难以在室内定位中发挥作用,而室内二维定位技术缺乏高程信息,也难以满足人们对室…...

华为HCIP第二节-------------------------ISIS

IS-IS&#xff08;Intermediate System to Intermediate System&#xff0c;中间系统到中间系统&#xff09;是ISO &#xff08;International Organization for Standardization&#xff0c;国际标准化组织&#xff09;为它的CLNP&#xff08;ConnectionLessNetwork Protocol&…...

在Mac系统下搭建Selenium环境并驱动Chrome浏览器

本文带领那些使用Mac的童鞋们实现Selenium驱动Chrome浏览器&#xff0c;虽然会有坑&#xff0c;但是我们可以凭借敏捷的身手躲过。下面就开始吧&#xff1a; 安装selenium 打开终端 ->pip安装&#xff08;安装命令&#xff1a;pip3 install selenium&#xff09; 安装浏览…...

通过RPM方式安装,升级,卸载,以及配置使用MySQL

通过RPM方式安装&#xff0c;升级&#xff0c;卸载&#xff0c;以及配置使用MySQL 一、下载 MySQL是一种开源的关系数据库管理系统&#xff0c;被广泛应用于各种业务应用中。本文将讲解如何下载和安装MySQL的rpm安装包。 下载rmp安装包有多种方式&#xff1a; 1、官网下载 …...

六边形架构和分层架构的区别?

六边形架构和分层架构是什么&#xff1f; 六边形架构&#xff08;Hexagonal Architecture&#xff09;和分层架构&#xff08;Layered Architecture&#xff09;是两种常见的软件架构模式。六边形架构强调将核心业务逻辑与外部依赖解耦&#xff0c;通过接口与外部世界进行通信。…...

一封来自Java学姐的信

黑马JavaEE学科学姐想对学弟学妹们说&#xff1a;勤学如春起之苗&#xff0c;不见其增&#xff0c;日有所长。 辍学如磨刀之石&#xff0c;不见其损&#xff0c;日有所亏。 学科 | JavaEE 校区 | 太原 亲爱的学弟学妹们&#xff0c;在学校“混日子”的时间很快就过去了&…...

Mybatis增强版MyBatis-Flex简介

Mybatis增强版&#xff1a;Mybatis-Plus(使用的最多&#xff0c;老牌Mybatis增强框架&#xff0c;2016年开源)、Fluent-MyBatis(阿里云开发的Mybatis增强框架&#xff0c;来自阿里云.云效产品团队)、Mybatis-Flex。 Flex英文单词意思是灵活&#xff0c;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项目&#xff0c;在启动类上添加注解SpringBootApplication &#xff0c;然后引入要自动注入的组件依赖&#xff0c;然后现application.properties中加上相应配置就可以自动注入这个组件&#xff0c;那么下面看看自动注入组件是如何实现的 一、S…...

短视频矩阵系统源码---开发技术源码能力

短视频矩阵系统开发涉及到多个领域的技术&#xff0c;包括视频编解码技术、大数据处理技术、音视频传输技术、电子商务及支付技术等。因此&#xff0c;短视频矩阵系统开发人员需要具备扎实的计算机基础知识、出色的编程能力、熟练掌握多种开发工具和框架&#xff0c;并掌握音视…...

可观测之调用链Skywalking

简介 分布式系统的应用程序性能监视工具&#xff0c;专为微服务、云原生架构和基于容器&#xff08;Docker、K8s、Mesos&#xff09;架构而设计。提供分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案。 多种监控手段。可以通过语言探针和 service mesh 获得监控…...

linux上适用的反汇编调试软件(对标od)

ubuntu下类似于od软件 经过搜索&#xff0c;在Ubuntu上选用edb-debugger进行动态调试&#xff0c; 下载链接: https://github.com/eteran/edb-debugger 但是依赖反汇编引擎: https://github.com/capstone-engine/capstone 安装 先安装capstone 先下载release的版本&#xf…...

基于高斯混合模型聚类的风电场短期功率预测方法(Pythonmatlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 2.1 Python 2.2 Matlab &#x1f389;3 参考文献 &#x1f308;4 Matlab代码、数据、文章讲解 &#x1f4a5;1 概述 文献来源&#xff1a; 摘要&#xff1a;对任意来流条件下的风电场发电功率进行准确预测,是提高电网对风电…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...

MySQL 主从同步异常处理

阅读原文&#xff1a;https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主&#xff0c;遇到的这个错误&#xff1a; Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一&#xff0c;通常表示&#xff…...

FOPLP vs CoWoS

以下是 FOPLP&#xff08;Fan-out panel-level packaging 扇出型面板级封装&#xff09;与 CoWoS&#xff08;Chip on Wafer on Substrate&#xff09;两种先进封装技术的详细对比分析&#xff0c;涵盖技术原理、性能、成本、应用场景及市场趋势等维度&#xff1a; 一、技术原…...

盲盒一番赏小程序:引领盲盒新潮流

在盲盒市场日益火爆的今天&#xff0c;如何才能在众多盲盒产品中脱颖而出&#xff1f;盲盒一番赏小程序给出了答案&#xff0c;它以创新的玩法和优质的服务&#xff0c;引领着盲盒新潮流。 一番赏小程序的最大特色在于其独特的赏品分级制度。赏品分为多个等级&#xff0c;从普…...

可视化图解算法48:有效括号序列

牛客网 面试笔试 TOP101 | LeetCode 20. 有效的括号 1. 题目 描述 给出一个仅包含字符(,),{,},[和],的字符串&#xff0c;判断给出的字符串是否是合法的括号序列 括号必须以正确的顺序关闭&#xff0c;"()"和"()[]{}"都是合法的括号序列&…...