51单片机——串行口通信

news2024/9/25 19:18:39

目录

1、51单片机串口通信介绍

2、串行口相关寄存器 

2.1 、串行口控制寄存器SCON和PCON

2.1.1 SCON:串行控制寄存器 (可位寻址)

2.1.2 PCON:电源控制寄存器(不可位寻址)

2.2、串行口数据缓冲寄存器SBUF

2.3、从机地址控制寄存器SADEN和SADDR

2.4、与串行口中断相关的寄存器IE和IPH、IP

2.4.1 IE:中断允许寄存器(可位寻址) 

2.4.2  中断优先级控制寄存器IPH、IP

3、串行口通信实战篇


1、51单片机串口通信介绍

        STC89C52系列单片机内部集成有一个功能很强的全双工串行通信口,与传统8051单片机的串口完全兼容。设有2个互相独立的接收、发送缓冲器,可以同时发送和接收数据。发送缓冲器只能写入而不能读出,接收缓冲器只能读出而不能写入,因而两个缓冲器可以共用一个地址码(99H)。两个缓冲器统称串行通信特殊功能寄存器SBUF。
        串行通信设有4种工作方式,其中两种方式的波特率是可变的,另两种是固定的,以供不同应用场合选用。波特率由内部定时器/计数器产生,用软件设置不同的波特率和选择不同的工作方式。主机可通过查询或中断方式对接收/发送进行程序处理,使用十分灵活。
        STC89C52系列单片机串行口对应的硬件部分对应的管脚是P3.0/RxD和P3.1/TxD。
        STC89C52系列单片机的串行通信口,除用于数据通信外,还可方便地构成一个或多个并行I/O口,或作串一并转换,或用于扩展串行外设等。

        了解了51单片机串行通信的大概要点,接下来我们就要进入正题,如何使单片机进行主从机通信呢?当然也是要写驱动程序的,但是该如何写呢?肯定是要对单片机的串行口相关寄存器进行学习的。

2、串行口相关寄存器 

串行口相关寄存器如下表: 

表中其他相关的相信大家都能看得懂,但是这里还是要提一点的是MSB、LSB。

在串行口中,MSB和LSB分别是最高有效位(Most Significant Bit)和最低有效位(Least Significant Bit),它们是对于数据位的描述。
MSB:最高有效位,也被称为高位。在一个多位数据中,MSB是位值最高的一位,其权值最大。
LSB:最低有效位,也被称为低位。在一个多位数据中,LSB是位值最低的一位,其权值最小。
MSB和LSB是用于描述数据位的相对位置的术语。它们在串行通信中往往用于指示数据位从哪一端开始传输。
全称方面,MSB和LSB的全称并没有具体的术语,它们只是描述位的相对位置的标识符。它们的含义在不同的上下文中会有所变化,但通常是通用的、广泛接受的术语。所以这里大家对它有一个概念就行。那么接下来我们就对相关的寄存器进行学习。 

2.1 、串行口控制寄存器SCON和PCON

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

2.1.1 SCON:串行控制寄存器 (可位寻址)

首先,先来学习SCON串行控制寄存器,SCON是指串行控制寄存器(Serial Control Register)。SCON用于控制和配置串行通信接口的工作模式和参数。具体来说,SCON寄存器通常包含了一些位字段(bits)用于配置串行通信的相关设置,用于选择串行通信的工作方式和某些控制功能。其格式如下:

SM0、SM1——串行口工作模式选择位。

串行口工作模式的作用是定义和控制串行通信的方式和行为,通过选择不同的工作模式,可以适配不同的应用场景和需求,实现灵活的数据传输。通过选择合适的串行口工作模式,可以根据应用需求配置和控制串行通信的参数,实现可靠、高效的数据传输。

SM0和SM1串行口工作模式选择位的使用是需要条件的:

1、当PCON寄存器中的SMOD0/PCON.6位为1时,该位用于帧错误检测。当检测到一个无效停止位时,通过UART接收器设置该位。FE必须由软件清零。

2、当PCON寄存器中的SMOD0/PCON.6位为0时,SM0和SM1一起指定串行通信的工作模式,如下表所示。

其中SM0、SM1按下列组合确定串行口的工作模式: 

简化如下: 

SM0、SM1=00——>方式0——>同步移位寄存器。
SM0、SM1=01——>方式1——>10位异步收发 (8位数据) 波特率可变 (定时器1溢出率控制)。
SM0、SM1=10——>方式2——>11位异步收发 (9位数据) 波特率固定。
SM0、SM1=11——>方式3——>11位异步收发 (9位数据) 波特率可变 (定时器1溢出率控制)。

解读51单片机串行通信4种工作方式:

(1)方式0:同步移位寄存器输入/输出方式,常用于扩展I/O口。波特率固定为振荡频率的1/12,并不受PCON寄存器中SMOD位的影响。

(2)方式1:用于串行发送或接收,为10位通用异步接口。TXD与RXD分别用于发送与接收数据。收发一帧数据的格式为1位起始位、8位数据位(低位在前)、1位停止位,共10位。波特率由定时器T1的溢出率与SMOD值同时决定,即SMOD=1,则波特率加倍;SMOD=0,则波特率不加倍。

(3)方式2:用于串行发送或接收,为11位通用异步接口。TXD与RXD分别用于发送与接收数据。收发一帧数据的格式为1位起始位、8位数据位(低位在前)、1位可编程的第9数据位(也就是1位奇偶校验位)和1位停止位,共11位。波特率取决于PCON中SMOD位的值;即SMOD=1,则波特率加倍;SMOD=0,则波特率不加倍。

(4)方式3:用于串行发送或接收,为11位通用异步接口。TXD与RXD分别用于发送与接收数据。帧格式与方式2相同,波特率与方式1相同。

SM2——多机通信控制位。

SM2:允许方式2或方式3多机通信控制位。在方式2或方式3时,如SM2位为1,REN位为1,则从机处于只有接收到RB8位为1(地址帧) 时才激活中断请求标志位RI为1,并向主机请求中断处理。被确认为寻址的从机则复位SM2位为0,从而才接收RB8为0的数据帧。在方式1时,如果SM2位为1,则只有在接收到有效的停止位时才置位中断请求标志位RI为1;在方式0时,SM2 应为0。

REN——允许串行接收位,由软件置1或者清0。

REN: 允许/禁止串行接收控制位。由软件置位REN,即REN=1为允许串行接收状态,可启动串行接收器RxD,开始接收信息。软件复位REN,即REN=0,则禁止接收。

 TB8、RB8——控制和指示串行数据传输。

TB8:TB8(Transmit Bit 8),发送的第9位数据。

在方式2和方式3时,TB8 是要发送的第 9 位数据其值由软件置1或清 0。在双机串行通信时,一般作为奇偶校验位使用;在多机串行通信中用来表示主机发送的是地址顿还是数据,TB8=1为地址,TB8=0为数据。在方式0和方式1中,不使用TB8。

RB8:RB8(Receive Bit 8),接收的第9位数据。

在方式2和方式3时,RB8存放接收到的第9位数据。在方式1时,如SM2=0,RB8 是接收到的停止位。在方式0时,不使用 RB8。

TI ——发送中断标志位,需要在中断服务中软件清0。

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

RI——接收中断标志位,需要在中断服务中软件清0。 

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

SCON的所有位可通过整机复位信号复位为全“0”。SCON的字节地址尾98H,可位寻址,各位地址为98H~~9FH,可用软件实现位设置。当用指令改变SCON的有关内容时,其改变的状态将在下一条指令的第一个机器周期的S1P1状态发生作用。如果一次串行发送已经开始,则输出TB8将是原先的值,不是新改变的值。
串行通信的中断请求:当一帧发送完成,内部硬件自动置位TI,即TI=1,请求中断处理;当接收完一帧信息时,内部硬件自动置位RI,即RI=1,请求中断处理。由于TI和RI以“或逻辑”关系向主机请求中断,所以主机响应中断时事先并不知道是TI还是RI请求的中断,必须在中断服务程序中查询TI和RI进行判别,然后分别处理。因此,两人中断请求标志位均不能由硬件自动置位,必须通过软件清0,否则将出现一次请求多次响应的错误。 

2.1.2 PCON:电源控制寄存器(不可位寻址)

PCON通常指代特殊功能寄存器(Special Function Register)中的电源控制寄存器(Power Control Register)。电源控制寄存器PCON中的SMOD/PCON.7用于设置方式1、方式2、方式3的波特率是否加倍。

电源控制寄存器格式如下: 

电源控制寄存器与串行口通信相关的位就是B6、B7。

SMOD:波特率选择位。当用软件置位SMOD,即SMOD=1,则使串行通信方式1、2、3的波特率加倍;SMOD=0,则各工作方式的波特率不加倍。复位时SMOD=0。

SMOD0:帧错误检测有效控制位。当SMOD0=1,SCON寄存器中的SM0/FE位用于FE(帧错误检测)功能;当SMOD0=0,SCON寄存器中的SM0/FE位用于SM0功能,和SM1一起指定串行口的工作方式。复位时SMOD0=0。

2.2、串行口数据缓冲寄存器SBUF

对于串行口数据缓冲寄存器SBUF的理解如下:

STC89C52系列单片机的串行口缓冲寄存器(SBUF)的地址是99H,实际是2个缓冲器,写SBUF的操作完成待发送数据的加载,读SBUF的操作可获得已接收到的数据。两个操作分别对应两个不同的寄存器,1个是只写寄存器,1个是只读寄存器。
串行通道内设有数据寄存器。在所有的串行通信方式中,在写入SBUF信号的控制下,把数据装入相同的9位移位寄存器,前面8位为数据字节,其最低位为移位寄存器的输出位。根据不同的工作方式会自动将“1”或TB8的值装入移位寄存器的第9位,并进行发送。串行通道的接收寄存器是一个输入移位寄存器。在方式0时它的字长为8位,其他方式时为9位。当一帧接收完毕,移位寄存器中的数据字节装入串行数据缓冲器SBUF中,其第9位则装入SCON寄存器中的RB8位。如果由于SM2使得已接收到的数据无效时,RB8和SBUF中内容不变。
由于接收通道内设有输入移位寄存器和SBUF缓冲器,从而能使一帧接收完将数据由移位寄存器装入SBUF后,可立即开始接收下一帧信息,主机应在该帧接收结束前从SBUF缓冲器中将数据取走,否则前一帧数据将丢失。SBUF以并行方式送往内部数据总线。

2.3、从机地址控制寄存器SADEN和SADDR

为了方便多机通信,STC89C52系列单片机设置了从机地址控制寄存器SADEN和SADDR。其中SADEN是从机地址掩码寄存器(地址为B9H,复位值为00H),SADDR是从机地址寄存器(地址为A9H,复位值为00H)。这里我们用不到,就不做理解,大概了解就ok了。

2.4、与串行口中断相关的寄存器IE和IPH、IP

2.4.1 IE:中断允许寄存器(可位寻址) 

串行口中断允许位ES位于中断允许寄存器IE中,中断允许寄存器的格式如下:

EA:CPU的总中断允许控制位,EA=1,CPU开放中断,EA=0,CPU屏蔽所有的中断申请。EA的作用是使中断允许形成多级控制。即各中断源首先受EA控制;其次还受各中断源自己的中断允许控制位控制。

ES:串行口中断允许位,ES=1,允许串行口中断,ES=0,禁止串行口中断。

2.4.2  中断优先级控制寄存器IPH、IP

IPH代表的是"Interrupt Priority High",IP代表的是"Interrupt Priority"。它们分别对应中断优先级高位寄存器和中断优先级低位寄存器。这两个寄存器用于控制中断的优先级。通过设置IP和IPH寄存器的位,可以确定中断的相对优先级,从而决定中断的触发顺序。注意,当多个中断同时发生时,具有较高优先级的中断将先被处理。 

串行口中断优先级控制位PS/PSH位于中断优先级控制寄存器IP/IPH中,中断优先级控制寄存器的格式如下:

IPH:中断优先级控制寄存器高(不可寻址) 

IP:中断优先级控制寄存器低(可寻址) 

PSH,PS:串口1中断优先级控制位。
当PSH=0且PS=0时,串口1中断为最低优先级中断(优先级0)

当PSH=0且PS=1时,串口1中断为较低优先级中断(优先级1)

当PSH=1且PS=0时,串口1中断为较高优先级中断(优先级2)

当PSH=1且PS=1时,串口1中断为最高优先级中断(优先级3)

3、串行口通信实战篇

我们已经学习了51单片机串行口通信的相关寄存器,接下来,就要把所学知识运用和实战——编写串行口通信的驱动程序,这是最最重要的一步,很多人学会了理论,但是实践一窍不通,要坚决避免要这种情况。首先,我们肯定是要书写串行口的初始化的,但是要从哪一步开始呢?步骤如下:

 第一步:设置串行口控制寄存器SCON:①选择串行口工作方式1——>SM0/SCON.7=0,SM1/SCON.6=1;②多机通信控制位不需要——>SM2/SCON.5=0;③允许串行接收位需要(肯定是需要允许串行口处于接收状态的)——>REN/SCON.4=1;④控制和指示串行数据传输不需要——>TB8/SCON.3=0、RB8/SCON.2=0;⑤发送、接收中断标志位初始化需置零——>TI/SCON.1=0,RI/SCON.0=0;综合得:SCON=0x50;如下图:

第二步:设置电源控制寄存器PCON:这里我们需要注意的一点就是串行口与改寄存器有关的就是SMOD/PCON.7、SMOD0/PCON.6;①波特率选择位,选择波特率不加倍——>SMOD/PCON.7=0;②帧错误检测有效控制位,选择SCON寄存器中的SM0/FE位用于SM0功能,和SM1一起指定串行口的工作方式——>SMOD0/PCON.6=0;综合得:PCON&=0x7F(这里使用了位与的表示方法,等同于PCON=0x00);如下图:

第三步:因为串行口通信属于异步通信,通信双方各自约定通信速率,所以需要使用到定时器1溢出率,所以这里我们需要配置定时器1,那就是操作与定时器/计数器有关的两个寄存器——>定时器/计数器控制寄存器TCON、定时器/计数器工作模式寄存器TMOD(这两个寄存器上面没有讲,可以自己查询一下,因为是属于定时器/计数器的内容的)①先配置定时器/计数器控制寄存器TCON;既然用到定时器1,那么肯定是要开启定时器1的——TR

1/TCON.6=1,单纯的用到该位,其他位没有用到,就不需要动了;综合得:TR1=1;如下图:

 ②接下来配置定时器/计数器工作模式寄存器TMOD:GATE/TMOD.7控制定时器1,置1时只有在INT1脚为高及TR1控制位置1时才可打开定时器/计数器1,这里不需要——>GATE/TMOD.7=0;C/T/TMOD.6控制定时器1用作定时器或计数器,清零则用作定时器(从内部系统时钟输入),置1用作计数器(从T1/P3.5脚输入),这里也不需要——>C/T/TMOD.6=0;使用定时器1,并且设定定时器1位8位自动重装方式——>M1/TMOD.5=1,M0/TMOD.4=0;综合得:TMOD=0x20;如下图:

第四步:设定计数寄存器的初值:因为使用的是定时器1,需设定计数寄存器:TL1、TH1的初始值;这里我以单片机晶振为11.0592、波特率为9600bps为例(注意:不同晶振的初始值设定的会有不一样)——>TL1=0xFD、TH1=0xFD;定时器1计数寄存器的初值为:TL1=0xFD;TH1=0xFD;这里无图;

第五步:配置中断允许寄存器IE:①开启CPU的总中断允许控制位——>EA/IE.7=1;②开启串行口中断允许位——>ES/IE.4=1;③禁止定时器1中断——>ET1/IE.3=0;其他位都不需要,全部置零;综合得:IE=0x90(等同于:ET1=0;ES=1;EA=1);如下图:

 综合上述所有步骤,串口初始化,我们将它封装成一个函数,如下:

/**
  * @brief  串口初始化,9600bps@11.0592MHz
  * @param  无
  * @retval 无
  */
void Uart_Init(void)		//9600bps@11.0592MHz
{
    PCON &= 0x7F;		//波特率不倍速
    SCON = 0x50;		//8位数据,可变波特率
    TMOD &= 0x0F;		//清除定时器1模式位(可有可无)
    TMOD |= 0x20;		//设定定时器1为8位自动重装方式(位或也是一样的)
    TL1 = 0xFD;		    //设定定时初值
    TH1 = 0xFD;		    //设定定时器重装值
    TR1 = 1;		    //启动定时器1
    ET1 = 0;		    //禁止定时器1中断
    ES=1;		        //串口中断允许控制位
    EA=1;		        //中断允许总控制位
    //IE=0x90;          //也可这样代替倒数的三个,分别是ET1=0;ES=1;EA=1;
}

串行口数据缓冲寄存器SBUF、从机地址控制寄存器SADEN和SADDR、中断优先级控制寄存器IPH、IP初始化用不到,我们这里不需要配置。

 下面我们开始用我们写好的串行口初始化驱动程序进行实操了,实操内容为:电脑通过串口控制LED;程序如下:

#include <REGX52.H>

/**
  * @brief  串口初始化,9600bps@11.0592MHz
  * @param  无
  * @retval 无
  */
void Uart_Init(void)		//9600bps@11.0592MHz
{
    PCON &= 0x7F;		//波特率不倍速
    SCON = 0x50;		//8位数据,可变波特率
    TMOD &= 0x0F;		//清除定时器1模式位(可有可无)
    TMOD |= 0x20;		//设定定时器1为8位自动重装方式(位或也是一样的)
    TL1 = 0xFD;		    //设定定时初值
    TH1 = 0xFD;		    //设定定时器重装值
    TR1 = 1;		    //启动定时器1
    ET1 = 0;		    //禁止定时器1中断
    ES=1;		        //串口中断允许控制位
    EA=1;		        //中断允许总控制位
    //IE=0x90;          //也可这样代替倒数的三个,分别是ET1=0;ES=1;EA=1;
}
/**
  * @brief  串口发送一个字节数据
  * @param  Byte 要发送的一个字节数据
  * @retval 无
  */
void UART_SendByte(unsigned char Byte)
{
	SBUF=Byte;
	while(TI==0);
	TI=0;
}
void main()
{
	Uart_Init();		//串口初始化
	while(1);
}

void UART_Routine() interrupt 4
{
	if(RI==1)					//如果接收标志位为1,接收到了数据
	{
		P2=~SBUF;				//读取数据,取反后输出到LED
		UART_SendByte(SBUF);	//将受到的数据发回串口
		RI=0;					//接收标志位清0
	}
}

 将上面的代码例程的hex文件下载到我们单片机开发板中,就可以通过串口助手发送数据控制单片机的LED的亮灭了,前提是开发板和电脑已经建立起连接了,如下图:

 现象图如下:

通过上例:就发现了串行口数据缓冲寄存器SBUF是如此用的,写操作时,写入的是发送寄存器,读操作时,读出的是接收寄存器;意思就是,单片机要接收外部设备发送过来的数据时,就将SBUF赋值给一个变量,就如本例子的:P2=~SBUF; 读取数据,取反后输出到P2口;同理也是,单片机要将数据发送给外部设备,那么就将需要发送的数据赋值给SBUF就可以了,如本例子的:SBUF=Byte;将Byte的值赋值给SBUF就可以了;这个串口数据缓存寄存器就是这么用来着,很简单,相信看了就都懂的,串口通信能做很多有趣的事情,比如我们可以在单片机上装一个蓝牙,然后拿手机来远程控制单片机,这个时候我们就可以拿来做一个要控制不了,手机控制小车等等,具体的拓展看个人;

为了更加方便大家的理解,可以结合下图进行对51单片机串行口的理解:

51单片机串行口发送数据数字、字符、符号等等各个进制之间的关系如下图:

 突然想到一个问题,最后提醒一下大家,定时器/计数器的工作模式和串行口的工作模式不是同一个概念的,大家不要混淆了,有的人就很容易弄乱的。51单片机串行口就是这么简单,只要把几个相关寄存器的功能作用弄明白了,就按自己需求配置寄存器初始化就可以了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/809836.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

iOS - 解压ipa包中的Assert.car文件

项目在 Archive 打包后&#xff0c;生成ipa包 将 xxx.ipa文件修改为zip后缀即 xxx.zip &#xff0c;然后再双击解压&#xff0c;会生成一个 Payload 文件夹&#xff0c;里面一个文件 如下图&#xff1a; 然后显示改文件的包内容&#xff1a; 解压 Assets.car 文件的方式&…

基于x-scan的渲染算法

基于x-scan算法实现的z-buffer染色&#xff0c;.net core framework 3.1运行。 x-scan算法实现&#xff1a; public List<Vertex3> xscan() {List<Vertex3> results new List<Vertex3>();SurfaceFormula formula getFormula();Box rect getBound();for …

力扣 968. 监控二叉树

题目来源&#xff1a;https://leetcode.cn/problems/binary-tree-cameras/description/ C题解&#xff08;来源代码随想录&#xff09;&#xff1a;节点可以分为3个状态&#xff1a;0无覆盖&#xff1b;1有摄像头&#xff1b;2有覆盖。 要想放的摄像头最少&#xff0c;应当叶子…

无涯教程-jQuery - stop( clearQueue, gotoEnd)方法函数

stop([clearQueue&#xff0c;gotoEnd])方法停止所有指定元素上的所有当前正在运行的动画。 stop( [clearQueue, gotoEnd ]) - 语法 selector.stop( [clearQueue], [gotoEnd] ) ; 这是此方法使用的所有参数的描述- clearQueue - 这是可选的布尔参数。设置为true会清除动画…

绕过TLS/akamai指纹护盾

文章目录 前言TLS指纹什么是TLS指纹测试TLS指纹绕过TLS指纹使用原生urllib使用其他成熟库&#xff01;&#xff01;修改requests底层代码 Akamai指纹相关&#xff08;HTTP/2指纹&#xff09;什么是Akamai指纹测试Akamai指纹绕过Akamai指纹使用其他成熟库 实操参考 前言 有道是…

Eureka 学习笔记3:EurekaHttpClient

版本 awsVersion ‘1.11.277’ EurekaTransport 用于客户端和服务端之间进行通信&#xff0c;封装了以下接口的实现&#xff1a; ClosableResolver 接口实现TransportClientFactory 接口实现EurekaHttpClient 接口实现及其对应的 EurekaHttpClientFactory 接口实现 private …

【雕爷学编程】MicroPython动手做(16)——掌控板之图片图像显示2

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

第120天:免杀对抗-防朔源防流量防特征CDN节点SSL证书OSS存储上线

知识点 #知识点&#xff1a; 1、CS-CDN节点-防拉黑 2、CS-SSL证书-防特征 3、CS-OSS存储-防流量#章节点&#xff1a; 编译代码面-ShellCode-混淆 编译代码面-编辑执行器-编写 编译代码面-分离加载器-编写 程序文件面-特征码定位-修改 程序文件面-加壳花指令-资源 代码加载面-D…

springCloud Eureka注册中心配置详解

1、创建一个springBoot项目 2、在springBoot项目中添加SpringCloud依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>2021.0.3</version><type>…

IDEA 使用 maven 搭建 spring mvc

1. 创建项目 1.1 创建成功之后配置 Spring MVC 1.2 勾选 Spring MVC 2.更改配置文件 2.1 更改web.xml配置 更改为 <servlet-mapping><servlet-name>dispatcher</servlet-name><url-pattern>/</url-pattern></servlet-mapping>2.2 dispat…

CF1833 A-E

A题 题目链接&#xff1a;https://codeforces.com/problemset/problem/1833/A 基本思路&#xff1a;for循环遍历字符串s&#xff0c;依次截取字符串s的子串str&#xff0c;并保存到集合中&#xff0c;最后输出集合内元素的数目即可 AC代码&#xff1a; #include <iostrea…

Michael.W基于Foundry精读Openzeppelin第15期——SignedMath.sol

Michael.W基于Foundry精读Openzeppelin第15期——SignedMath.sol 0. 版本0.1 SignedMath.sol 1. 目标合约2. 代码精读2.1 max(int256 a, int256 b) && min(int256 a, int256 b)2.2 average(int256 a, int256 b)2.3 abs(int256 n) 0. 版本 [openzeppelin]&#xff1a;v…

final的使用以及权限修饰符

final表示最终的、不可改变的 final跟abstract不可以同时使用&#xff0c;因为二者是冲突的。final表示不可变&#xff0c;abstrac表示必须要重写、必须要变。 常见的四种用法 修饰一个类 格式&#xff1a; public final class 类名称{ }final修饰之后&#xff0c;这个类不能…

杂谈项——关于我在bw上的见闻,以及个人对二次元游戏行业方面的前瞻

君兮_的个人主页 勤时当勉励 岁月不待人 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;今天为大家带来一点不一样的&#xff0c;首先先光速叠一下甲&#xff1a; 在此说明博主并不是一个什么都知道的大佬&#xff0c;只是一个普通的老二次元以及期望以后能…

大数据-Spark批处理实用广播Broadcast构建一个全局缓存Cache

1、broadcast广播 在Spark中&#xff0c;broadcast是一种优化技术&#xff0c;它可以将一个只读变量缓存到每个节点上&#xff0c;以便在执行任务时使用。这样可以避免在每个任务中重复传输数据。 2、构建缓存 import org.apache.spark.sql.SparkSession import org.apache.s…

Xshell配置ssh免密码登录-公钥与私钥登录linux服务器

目录 简介 提示 方法步骤 步骤1&#xff1a;生成密钥公钥&#xff08;Public key&#xff09;与私钥(Private Key) 方法1&#xff1a;使用xshell工具 方法2&#xff1a;使用命令行 步骤2&#xff1a;放置公钥(Public Key)到服务器 方法1&#xff1a;&#xff08;我使用的是…

LeetCode551.Student-Attendance-Record-i<学生出勤记录 I>

题目&#xff1a; 思路&#xff1a; 遍历就完事了.连续三天不来return false; 超过两次缺勤 fasle; 代码是&#xff1a; //codeclass Solution { public:bool checkRecord(string s) {int n s.length();int abtimes0,latimes0;for(int i0;i<n;i){switch(s[i]){case(A):l…

总结942

5:40起床 6:00~7:00单词复习300个&#xff0c;记100个 7:15~8:00早读&#xff0c;《love is as strong as death》第一第二段 8:10~9:10三大计算回顾 9:15~10:06 习题880第一章基础选择纠错 10:10~10&#xff1a;30单词默写 10:30~11:40强化第一讲习题 11:40~12:30继续…

【雕爷学编程】MicroPython动手做(16)——掌控板之图片图像显示3

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

Android 设备兼容性使用详解

和你一起终身学习&#xff0c;这里是程序员Android 经典好文推荐&#xff0c;通过阅读本文&#xff0c;您将收获以下知识点: 一、设备兼容性分类二、硬件设备兼容三、软件 APP 兼容四、兼容不同语言五、兼容不同分辨率六、兼容不同屏幕方向布局七、兼容不同硬件 Feature八、兼容…