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

【51单片机】串口通信原理 + 使用

学习使用的开发板:STC89C52RC/LE52RC
编程软件:Keil5
烧录软件:stc-isp

开发板实图:
在这里插入图片描述

文章目录

  • 串口
    • 硬件电路
    • UART
    • 串口相关寄存器
  • 编码
    • 单片机通过串口发送数据
    • 电脑通过串口发送数据控制LED灯

串口

  • 串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信
  • 单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大的扩展了单片机的应用范围,增强了单片机系统的硬件实力
    51单片机内部自带UART(Universal Asynchronous Receiver Transmitter,通用异步收发器),可实现单片机的串口通信

在这里插入图片描述

硬件电路

简单双向串口通信有两根通信线(发送端TXD(Transmit Exchange Data)和接收端RXD(Receive Exchange Date))

TXD和RXD要交叉连接,设备1的TXD连接设备2的RXD,设备1的RXD连接设备2的TXD
在这里插入图片描述
当只要单向传输数据时,可以只有一根通信线

GND是一定要连接的,若两个设备都可以各自供电,则不需要连接VCC

电平标准不一致时,还需要加电平转换芯片


电平标准

电平标准是数据1和数据0的表达方式,是传输线缆中人为规定的电压与数据的对应关系,串口常用的电平标准有如下三种:

  • TTL电平:+5V表示1,0V表示0,一般用于单片机
  • RS232电平:-3 ~ -15V 表示1,+3 ~ +15V 表示0,一般用于电脑
  • RS485电平:两线压差 +2 ~ +6V 表示1,-2 ~ -6V 表示0(差分信号),一般用于CAN总线

前两个通信距离都较近,一般只有十几米,距离过远传输的数据就很容易出错;而RS485通信距离远,信号可靠性高,传输距离可达1KM以上


相关术语

  • 全双工:通信双方可以在同一时刻互相传输数据

在这里插入图片描述

  • 半双工:通信双方可以互相传输数据,但同时间只能有一段发送,另一端接收,必须分时复用一根数据线

在这里插入图片描述

  • 单工:通信双方只能一方发送到另一方,不能反向传输。比如遥控器控制电视,只能遥控器向电视发送数据
    在这里插入图片描述
  • 异步:通信双方各自约定通信速率
  • 同步:通信双方靠一根时钟线来约定通信速率

数据传输是依靠高低电平的,也就是电平协议。比如如下两个数据
在这里插入图片描述
看电平都是从高电平变为低电平,但是如果通信速率不一样,则获取的数据不一样
在这里插入图片描述
通信速率快,10可能会被解析为1100;通信速率慢,1100也可能会被解析为10。

所以约定好通信速率很重要

  • 总线:连接各个设备的数据传输线路(类似一条马路,把路边的住户连接起来,使住户可以相互交流)

在这里插入图片描述


常见通信接口比较

在这里插入图片描述

  • UART:为本节学习的串口通信接口
  • I2C:板子上的C24C02使用该串口
  • SPI:板子上的DS1302使用非标准SPI
  • 1-Wire:板子上的DS18B20使用该串口

常见的还有CAN总线USB,CAN总线常用于汽车领域


UART

51单片机的UART

STC89C52有1个UART,RXD和TXD分别和P3.0和P3.1这两个I/O口共用同一个引脚
在这里插入图片描述

STC89C52的UART有四种工作模式:
模式0:同步移位寄存器
模式1:8位UART,波特率可变(常用)
模式2:9位UART,波特率固定
模式3:9位UART,波特率可变


串口参数及时序图

  • 波特率:串口通信的速率(发送和接收各数据位的间隔时间)
  • 校验位:用于数据验证,一定程序可以知道数据是否错误,也需要双方提前协商统一校验。常用的校验如01校验奇偶校验9位UART就是多了一位校验位
  • 停止位:用于数据帧间隔,发送多个数据,如何间隔两个数据,就使用停止位
    波特率就是上述异步双方要约定好的如何对数据进行采样

串口收发数据,都是从低位开始
在这里插入图片描述

串口模式图

简单的串口模式图

在这里插入图片描述

UART是集成在单片机内部的,通过TXD引脚发送数据,RXD引脚接收数据

UART可以分为三个部分,中间为定时器T1——控制波特率;左侧绿框的SBUF用于收发数据;右侧为中断系统

SBUF:串口数据缓存寄存器,物理上是两个独立的寄存器,但占用相同的地址。写操作时,写入的是发送寄存器,读操作时,读出的是接收寄存器

完整的串口和中断系统模式图如下:

在这里插入图片描述

下面通过介绍相关寄存器来讲述串口通信的原理

串口相关寄存器

在这里插入图片描述

串行口控制寄存器SCON和PCON

STC89C52系列单片机的串行口设有两个控制寄存器:串行控制寄存器SCON波特率选择特殊功能寄存器PCON

PCON
电源控制寄存器,可能是电源控制还有剩下比特位,所以波特率选择和帧错误控制位也集成其中,减少资源消耗
格式如下:
在这里插入图片描述
我们只要关注SMODSMOD0 即可

  • SMOD:波特率选择位。当软件置SMOD = 1时,使串行通信方式1、2、3的波特率加倍;SMOD = 0,则不加倍。复位时SMOD = 0
  • SMOD0:帧错误检测有效控制位。当SMOD = 1,SCON寄存器中的 SM0/FE 位于 FE(帧错误检测)功能;当SMOD0 = 0,SCON的SM0/FE 用于 和 SM1 组合指定串行口的工作模式。复位时 SMOD0 = 0

SCON
用于选择串行通信的工作方式和某些控制功能,格式如下:
在这里插入图片描述

  • SM0/FE:当PCON寄存器的 SMOD0/FE = 1时,该位用于帧错误检测。当检测到一个无效停止位时,通过UART接收器设置该位,必须由软件清零;当SMOD0/FE = 0,该位和 SM1 组合指定工作模式

在这里插入图片描述

  • REN:允许/禁止串行接收控制位。由软件置位,若REN = 1即允许串行接收数据;REN = 0则禁止接收

  • SM2:允许方式2或方式3多机通信控制位

  • TB8:在方式2或方式3,为要发送的第9位数据,按需要由软件置位或清0。可用作数据的校验位或多机通信中表示地址帧/数据帧的标志位。

  • RB8:在方式2或方式3,是接收到的第9位数据。在方式1,若SM2=0,则RB8是接收到的停止位。方式0不用RB8。

  • TI:发送中断请求标志位。在方式0,当串行发送数据第8位结束时,由内部硬件置TI = 1,向主机请求中断,响应中断后必须用软件复位,即TI = 0。在其他方式中,则在停止位开始发送时由内部硬件置位必须用软件复位TI = 0

  • RI:接收中断请求标志位。在方式0,当串行接收到第8位结束时由内部硬件自动置位 RI = 1 ,向主机请求中断,响应中断后必须用软件复位,即RI=0。在其他方式中,串行接收到停止位的中间时刻由内部硬件置位,即RI=1,必须由软件复位,即RI=0

IE
中断允许寄存器
在这里插入图片描述
其中我们只关注EAES

  • EA:CPU的总中断允许控制位,EA = 1,CPU开放中断;EA = 0,CPU屏蔽所有中断请求
  • ES:串行口中断允许位,ES = 1,允许串行口中断;ES = 0,禁止串行口中断

在这里插入图片描述

注意:接收中断和发送中断共用一个中断,在中断处理函数中还需要通过RITI 的置位判断本次中断是接收中断还是发送中断


最后我们回归模式图,讲解一下串口通信的流程

在这里插入图片描述

发送数据
通过总线将数据写入SBUF,定时器1控制波特率。通过TXD发送数据,当发送数据结束时(方式0为发完8位数据,其他方式为发送停止位时),将 TI = 1,发送中断请求
接收数据
RXD接收数据,通过定时器1控制波特率,对接收数据进行采样,存放在SBUF,当接收数据结束(方式0当串行发送数据第8位结束时,在其他方式中,则在停止位开始发送时由内部硬件置位),将 RI = 1,发出中断请求

注意TIRI 都需要由软件置0

编码

经过上述学习,我们已经对串口有了一定的了解,接下来就是实现串口通信

单片机通过串口发送数据

我们使用UART串口通信,首先要进行初始化,如:选择工作方式,初始化中断系统,设置波特率,初始化定时器

选择工作模式
涉及到SCONPCON

首先是PCON的SMOD0,当 SMOD0 = 0 时,SMOD 的 SM0 才会被用来选择工作方式
其次,我们选择 8位UART,波特率可变模式,即方式1,SCON的SM0 = 0,SM1 = 1
最后,如果要允许串口接收数据,还需要置SCON的REN = 1


初始化中断系统

首先,初始化串口收发数据的中断请求标志位,SCON的 TIRI,由硬件置1,我们初始化时清零即可:TI = 0, RI = 0
到此,SCON的设置就结束了
总结一下,SM0 = 0, SM1 = 1, REN = 1/0, TI = 0, RI = 0,其他默认为0即可,所以SCON = 0x40/0x50

然后是中断开关
在这里插入图片描述

ES = 1, EA = 1

SCON = 0x50;	//选择工作方式 & 允许串口接收数据
PCON |= 0x80;	//使SM0为选择工作方式
//中断开关
ES = 1;			//串口中断开关
EA = 1;			//总中断开关

初始化定时器

初始化定时器可参看【51单片机】定时器
此处定时器1选择工作模式2——8位自动重装

8位自动重装
一次只对TL1或TH1计数加一
当一个溢出后,直接使用另一个计数单元的初值

//设置定时器1
TMOD &= 0x0F;	//高4位清零
TMOD |= 0x20;	//0010,模式3——8位自动重载
TR1 = 1;		//启用定时器T1
ET1 = 0;		//禁止定时器T1中断	
//定时器初值
TL1 = 0xF3;		//设定定时初值
TH1 = 0xF3;		//设定定时器重装值

设置波特率
我们设置波特率为4800
设置波特率需要通过设置定时器1的初始值

TL1 = 0xF3;		//设定定时初值
TH1 = 0xF3;		//设定定时器重装值

讲解一下为什么定时器初值是这个

假设系统频率为12MHz,使用12T模式,则定时器频率为12 / 12 = 1MHz,即每1us,计数单元加1。

使用8位自动重装,256时会溢出,0xF3 = 243,256 - 243 = 13。所以定时器溢出需要13us

溢出率:1 / 13 = 0.07692

使用SMOD = 1,波特率加倍(不除2)
在这里插入图片描述

还需要 0.07692 / 16 = 0.0048076923MHz
转化为Hz:4807.6923Hz,这个就是波特率
会存在一定误差

也可参看如下计算
在这里插入图片描述


到此,串口的初始化就完成了
完整代码如下:

/*** @brief		初始化串口* @parm		无* @retval		无*/
void UART_Init()
{//SCON高4位分别为SM0、SM1、SM2、REN//SM0和SM1控制串口模式,选择01——8位UART,波特率可变//REN接收使能,REN = 0禁止接收,REN = 1允许接收//所以设置0101 0000SCON = 0x50;//PCON包含波特率和电源设置//前两位为SMOD和SMOD0//SMOD = 1波特率加倍,SMOD = 0,波特率不加倍//SMOD0是帧错误的,此处不用//所以设置1000 0000PCON |= 0x80;//设置定时器1TMOD &= 0x0F;	//高4位清零TMOD |= 0x20;	//0010,模式3——8位自动重载TR1 = 1;		//启用定时器T1ET1 = 0;		//禁止定时器T1中断	//定时器初值TL1 = 0xF4;		//设定定时初值TH1 = 0xF4;		//设定定时器重装值//中断开关ES = 1;			//串口中断开关EA = 1;			//总中断开关
}

博主的单片机系统频率为11.0592MHz
可以使用STC-ICP生成波特率设置代码

在这里插入图片描述

注意:配置一定要选择正确;代码中的AUXR寄存器为高版本单片机才有的,低版本不认识这个寄存器,可以直接删掉


串口发送数据通过赋值SBUF,数据发送完后,硬件置位TI = 1,需要我们手动对TI清零
代码如下:

/*** @brief 		通过串口发送一个字节数据* @parm		Byte:要发送字节数据* @retval		无*/
void UART_SendByte(unsigned char Byte)
{SBUF = Byte;while(TI == 0);//数据发送完,硬件置1TI = 0;		//软件置0
}

模块化编程,完整代码如下:

延时模块——控制串口发送数据速率
Delay.h

#ifndef __DELAY_H__
#define __DELAT_H__void Delayms(unsigned int xms);//等待指定毫秒#endif

Delay.c

#include <INTRINS.h>
/*** @brief  延迟一定时间* @parm	延迟的时间,单位是毫秒,范围:0 ~ 65535* @retval	无*/
void Delayms(unsigned int xms)		//@11.0592MHz
{while(xms--){unsigned char i, j;_nop_();i = 2;j = 199;do{while (--j);} while (--i);}	
}

UART串口模块

UART.h

#ifndef __UART_H__
#define __UART_H__void UART_Init();
void UART_SendByte(unsigned char Byte);#endif

UART.c

#include <REGX52.H>
/*** @brief		初始化串口* @parm		无* @retval		无*/
void UART_Init()
{//SCON高4位分别为SM0、SM1、SM2、REN//SM0和SM1控制串口模式,选择01——8位UART,波特率可变//REN接收使能,REN = 0禁止接收,REN = 1允许接收//所以设置0101 0000SCON = 0x50;//PCON包含波特率和电源设置//前两位为SMOD和SMOD0//SMOD = 1波特率加倍,SMOD = 0,波特率不加倍//SMOD0是帧错误的,此处不用//所以设置1000 0000PCON |= 0x80;//设置定时器1TMOD &= 0x0F;	//高4位清零TMOD |= 0x20;	//0010,模式3——8位自动重载TR1 = 1;		//启用定时器T1ET1 = 0;		//禁止定时器T1中断	//定时器初值TL1 = 0xF4;		//设定定时初值TH1 = 0xF4;		//设定定时器重装值//中断开关ES = 1;			//串口中断开关EA = 1;			//总中断开关
}
/*** @brief 		通过串口发送一个字节数据* @parm		Byte 要发送字节数据* @retval		无*/
void UART_SendByte(unsigned char Byte)
{SBUF = Byte;while(TI == 0);//数据发送完,硬件置1TI = 0;		//软件置0
}///**
//  * @brief 		接收数据 模版
//  * @parm			无
//  * @retval		无
//  */
//void UART_Routine() interrupt 4
//{
//	if(RI == 1)//检测是否是接收数据中断
//	{
//		RI = 0;//软件置0
//	}
//}

主程序——每隔一秒通过串口发送递增数据

#include <REGX52.H>
#include "UART.h"
#include "Delay.h"
/*** @brief		通过串口每隔1s发送递增的数据 范围:0 ~ 255* @parm		无* @retval		无*/
void SendIncreasingNum()
{static unsigned char num;UART_SendByte(num++);Delayms(1000);
}void main()
{UART_Init();while(1){SendIncreasingNum();}
}

使用STC-IST串口助手 查看效果

在这里插入图片描述
注意:下面一行的配置要正确

电脑通过串口发送数据控制LED灯

电脑发送数据给单片机需要USB转串口,自带的USB线就已经实现了这一转换,所以我们直接编写单片机通过串口接收数据的逻辑即可。

串口接收数据会存放在SBUF,接收完毕后会将RI置1,发出中断请求,中断号为4,然后需要手动清零RI

代码如下:

void UART_Routine() interrupt 4
{if(RI == 1)//检测是否是接收数据中断{P2 = SBUF;RI = 0;//软件置0}
}

注意P2寄存器用于控制LED亮灭,为0亮起,为1熄灭

还可以将数据重新返回给电脑,同样使用DelayUART 模块,只有main.c不同

main.c

#include <REGX52.H>
#include "UART.h"
#include "Delay.h"
/*** @brief 		接收数据,亮相应的灯,并返回数据* @parm		无* @retval		无*/
void UART_Routine() interrupt 4
{if(RI == 1)//检测是否是接收数据中断{P2 = SBUF;UART_SendByte(SBUF);RI = 0;//软件置0}
}
void main()
{UART_Init();while(1){}
}

效果如下:
我们通过串口助手,发送 0xAA = 1010 1010

在这里插入图片描述

LED灯效果如下:

在这里插入图片描述


以上就是本篇博客的所有内容,感谢你的阅读
如果觉得本篇文章对你有所帮助的话,不妨点个赞支持一下博主,拜托啦,这对我真的很重要。
在这里插入图片描述

相关文章:

【51单片机】串口通信原理 + 使用

学习使用的开发板&#xff1a;STC89C52RC/LE52RC 编程软件&#xff1a;Keil5 烧录软件&#xff1a;stc-isp 开发板实图&#xff1a; 文章目录 串口硬件电路UART串口相关寄存器 编码单片机通过串口发送数据电脑通过串口发送数据控制LED灯 串口 串口是一种应用十分广泛的通讯接…...

优选算法第五讲:位运算模块

优选算法第五讲&#xff1a;位运算模块 1.常见的位运算总结2.判断字符是否唯一3.丢失的数字4.两整数之和5.只出现一次的数字II6.消失的两个数字 1.常见的位运算总结 2.判断字符是否唯一 链接: link class Solution { public:bool isUnique(string astr) {if(astr.size() >…...

【07】Maven项目多环境打包配置

&#xff08;1&#xff09;Web项目使用Maven进行多模块划分开发之后&#xff0c;面临一个问题&#xff0c;即如何加载不同环境的配置文件打包发布到不同的环境中&#xff1f; &#xff08;2&#xff09;不同的环境有开发环境、测试环境、线上生产环境等。 &#xff08;3&#x…...

嵌入式Linux入门具备:C语言基础与基本驱动学习(2):Linux GIibc IO基础

标准IO 标准 I/O 虽然是对文件 I/O 进行了封装&#xff0c;但事实上并不仅仅只是如此&#xff0c;标准 I/O 会处理很多细节&#xff0c;譬如分配 stdio 缓冲区、以优化的块长度执行 I/O 等&#xff0c;这些处理使用户不必担心如何选择使用正确的块长度。I/O 库函数是构建于文件…...

【微服务】Docker 容器化

一、初识Docker 1. 为什么需要 Docker 大型项目组件较多&#xff0c;运行环境也较为复杂&#xff0c;部署时会遇到一些问题&#xff1a; 依赖关系复杂&#xff0c;容易出现兼容性的问题开发、测试、生产环境有差异 Docker 如何解决依赖的兼容问题 将应用的Libs&#xff08;…...

[前端] 为网站侧边栏添加搜索引擎模块

前言 最近想给我的个人网站侧边栏添加一个搜索引擎模块&#xff0c;可以引导用户帮助本站SEO优化&#xff08;让用户可以通过点击搜索按钮完成一次对本人网站的搜索&#xff0c;从而实现对网站的搜索引擎优化&#xff09;。 最开始&#xff0c;我只是想实现一个简单的百度搜索…...

解决CORS (跨源资源共享) 错误

问题引入 前端代码 <template><div id"hello-vue" class"demo">{{ message }}</div><el-button type"primary" click"handleClick">我是一个按钮</el-button></template><script setup>//加…...

Redis 实现分布式缓存

一、引言 在当今互联网时代&#xff0c;随着业务的不断发展和用户量的持续增长&#xff0c;系统的性能和可扩展性成为了关键挑战。分布式缓存作为一种重要的技术手段&#xff0c;能够有效地缓解数据库压力、提高系统响应速度、增强系统的可扩展性。Redis 作为一种高性能的内存数…...

Chrome与火狐哪个浏览器的移动版本更流畅

在当今的数字化时代&#xff0c;移动设备已经成为我们生活中不可或缺的一部分。而浏览器作为我们访问互联网的重要工具&#xff0c;其性能和用户体验直接影响到我们的使用感受。本文将对比Chrome和火狐&#xff08;Firefox&#xff09;两款主流浏览器的移动版本&#xff0c;探讨…...

7篇Python爬虫实例,直接代码可运行,全网最全,注释超详细(适合收藏)——2、爬取图片信息。

7篇Python爬虫实例&#xff0c;可直接运行&#xff0c;适合收藏 python爬虫7篇实例&#xff0c;分七个文章进行发布&#xff1b;第二篇&#xff1a;爬取图片信息。 爬取图片信息&#xff0c;并将每张图片都下载下来。 爬虫主要三部分&#xff1a; 1、获取数据 2、数据解析 3、…...

25.停车场管理系统(基于web的Java项目)

目录 1.系统的受众说明 2.相关技术与方法 3.系统分析 3.1 可行性分析 3.1.1 技术可行性 3.1.2 经济可行性 3.1.3 操作可行性 3.2 需求分析 3.2.1 系统功能描述 3.2.2 用例图分析 4. 系统设计 4.1 系统类分析 5. 系统详细设计与实现 5.1 用户登录 5.2 系统信…...

展览搭建公司怎么跟展会主办打好交道

与展会主办打好交道的重要性 首先&#xff0c;我们得明白&#xff0c;展览搭建公司为何要跟展会主办打交道。简单地说&#xff0c;展会主办拥有大量的参展商信息。这些参展商是展览搭建公司潜在的客户群体&#xff0c;与主办打好交道&#xff0c;就等于拿到了通向这些客户的 “…...

软件开发方法

软件开发方法是一种用于指导软件开发过程的系统性方法,它涵盖了从需求分析、设计、编码、测试到维护的整个软件生命周期。软件开发方法通常包括一系列的步骤、技术和工具,以确保软件的质量、可维护性和可扩展性。 常见的软件开发方法有瀑布模型、敏捷开发、螺旋模型等。这些…...

「Mac畅玩鸿蒙与硬件24」UI互动应用篇1 - 灯光控制小项目

本篇将带领你实现一个互动性十足的灯光控制小项目&#xff0c;用户可以通过点击按钮来控制灯光的开关。该项目将涉及状态管理、动态图片加载以及按钮交互&#xff0c;是学习鸿蒙应用开发的重要基础。 关键词 UI互动应用状态管理动态图片加载用户交互 一、功能说明 在这个灯光…...

十二:java web(4)-- Spring核心基础

目录 创建项目 Spring 核心基础 Spring 容器 Spring 容器的作用 Spring 容器的工作流程 Bean Bean 的生命周期 IOC&#xff08;控制反转&#xff09;与依赖注入&#xff08;DI&#xff09; 控制反转的概念 依赖注入的几种方式&#xff08;构造器注入、Setter 注入、接…...

new和malloc有什么区别,他们的用法是什么?malloc分配失败会导致什么问题

1) new和malloc的区别&#xff0c;和他们的用法 new 和 malloc 主要有以下区别&#xff1a; 一、性质和来源 new &#xff1a;是 C 的运算符&#xff0c;在操作时会调用构造函数进行对象的初始化。它是 C 语言层面的操作&#xff0c;能更好地与 C 的面向对象特性结合。 malloc …...

了解SQLExpress数据库

SQLExpress&#xff08;Microsoft SQL Server Express&#xff09;是由微软公司开发的一款免费且轻量级的数据库管理系统。以下是关于SQLExpress的详细解释&#xff1a; 一、定义与特点 定义&#xff1a; SQLExpress是Microsoft SQL Server的一个缩减版或基础版&#xff0c;旨在…...

geoserver创建一个根据属性显示不同形状的点样式

geoserver创建一个根据属性显示不同形状的点样式 三角形 -triangle 圆形 - circle 正方形 - square 星形 - star 十字形 - cross 菱形 -diamond 代码&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <StyledLayerDescriptor version"…...

中国遗传学会2024全国学术研讨会在长沙成功召开

2024年11月3日至6日&#xff0c;备受瞩目的中国遗传学会2024全国学术研讨会在长沙盛大召开&#xff0c;此次盛会由中国遗传学会携手湖南省遗传学会共同主办&#xff0c;中南大学与南华大学共同承办。大会以“遗传学&#xff1a;前沿与交叉”为主题&#xff0c;吸引了来自全国各…...

Android Studio 多工程公用module引用

在Android Studio中&#xff0c;如果有多个工程需要共享同一个module&#xff0c;你可以通过以下步骤来实现module的公用&#xff1a; 1.将你想共享的module移动到一个单独的目录&#xff0c;比如一个新建的"libraries"文件夹。 2.修改module的build.gradle文件&am…...

(实战)WebApi第9讲:EFCore性能优化(IQueryable延迟查询、取消跟踪机制)

一、例子是第8讲的四、6&#xff08;EFCore的静态化处理 &#xff09;&#xff1a;分析ToList() ToList()在下图绿色框内。 二、在没有最终取数据的时候&#xff0c;使用 IQueryable<T> 延迟执行查询 &#xff08;1&#xff09;在没有最终取数据的时候&#xff0c;不要使…...

Java实现pdf转图片

第一步 <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.32</version> <!-- 请检查最新版本 --> </dependency> 第二步 package com.example.demo.file.pdf;import or…...

健身房管理新纪元:SpringBoot技术应用

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 图4-1系统工作原理…...

Java之字符串分割转换List

Java之字符串分割转换List 字符串分割成数组然后转换成List有多种方式&#xff0c;以下是每种方式的示例&#xff0c;推荐Java8的新特性Stream。 使用Java8的新特性Stream API String str "aaa,bbb,ccc"; // 使用Arrays.stream() List<String> list1 …...

RabbitMQ如何保证发送的消息可靠(RabbitMQ的Confirm模式和2.Return模式)

RabbitMQ如何保证发送的消息可靠&#xff08;RabbitMQ的Confirm模式和2.Return模式&#xff09; 1、RabbitMQ消息Confirm模式&#xff08;保证从生产者到交换机的消息可靠&#xff09;1.1、Confirm模式简介1.2、具体代码实现1.2.1、application.yml 开启确认模式1.2.2、生产者方…...

适配器模式:类适配器与对象适配器

适配器模式是一种结构性设计模式&#xff0c;旨在将一个接口转换成客户端所期望的另一种接口。它通常用于解决由于接口不兼容而导致的类之间的通信问题。适配器模式主要有两种实现方式&#xff1a;类适配器和对象适配器。下面&#xff0c;我们将详细探讨这两种方式的优缺点及适…...

volatile原理

volatile原理 volatile的底层实现原理是内存屏障,Memory Barrier(Memory Fence) 对volatile变量的写指令后会加入写屏障 对volatile变量的读指令前会加入读屏障 如何保证可见性 写屏障保证在该屏障之前的,对共享变量的改动,都同步到主存当中 public void actor2(I_Resu…...

【AI神器】SD(Stable Diffusion)一键安装包

是否还在无法使用Stable Diffusion 而烦恼&#xff0c;今天就给大家带来sd的私有化部署&#xff0c;一键安装包 https://pan.quark.cn/s/c16aa752ac6a 当然对电脑配置略微有些要求&#xff1a; 首先&#xff0c;本地安装对电脑配置有一些基本要求&#xff0c; 本地电脑安装…...

lanqiaoOJ 1112:小王子双链表 ← STL list

【题目来源】https://www.lanqiao.cn/problems/1112/learning/【题目描述】 小王子有一天迷上了排队的游戏&#xff0c;桌子上有标号为 1-10 的 10 个玩具&#xff0c;现在小王子将他们排成一列&#xff0c;可小王子还是太小了&#xff0c;他不确定他到底想把那个玩具摆在哪里&…...

C#WPF之快速理解MVVM模式

MVVM是一种设计模式&#xff0c;特别适用于WPF等XAML-based的应用程序开发。MVVM模式主要包含三个部分&#xff1a;Model&#xff08;模型&#xff09;、View&#xff08;视图&#xff09;和ViewModel&#xff08;视图模型&#xff09;。 Model&#xff08;模型&#xff09;&a…...