【51单片机】串口通信实验(包括波特率如何计算)

目录

  • 串口通信实验
    • 通信的基本概念
      • 串行通信与并行通信
      • 异步通信与同步通信
      • 单工、 半双工与全双工通信
      • 通信速率
    • 51单片机串口介绍
      • 串口介绍
      • 串口通信简介
      • 串口相关寄存器
      • 串口工作方式
        • 方式0
        • 方式1
        • 方式 2 和方式 3
      • 串口的使用方法(计算波特率)
    • 硬件设计
    • 软件设计
      • 1、向单片机发送数据 0x11
      • 2、向单片机发送一个不断加1的数
      • 3、通过电脑端发送一个数据去点亮led灯

****

串口通信实验

本节来学习 51 单片机的串口通信。 开发板上集成了 1 个串口通信电路, 是 USB 转串口模块, 它既可下载程序也可实现串口通信功能。 本节要实现的功能是:51 单片机通过串口(UART) 实现与 PC 机对话,51 单片机的串口收到 PC 机发来的数据后原封不动的返回给 PC 机显示。

通信的基本概念

51 单片机不仅可以实现串口通信, 还可以通过 IO 口模拟实现多种其他通信, 比如 SPI、 IIC 等, 学习这些通信前, 我们很有必要了解下通信的基本概念。 通信的方式可以分为多种, 按照数据传送方式可分为串行通信和并行通信。 按照通信的数据同步方式, 可分为异步通信和同步通信。 按照数据的传输方向又可分为单工、 半双工和全双工通信。 下面我们就来简单介绍这几种通信方式。

串行通信与并行通信

(1)串行通信
串行通信是指使用一条数据线, 将数据一位一位地依次传输, 每一位数据占据一个固定的时间长度。 其只需要少数几条线就可以在系统间交换信息, 特别适用于计算机与计算机、 计算机与外设之间的远距离通信。 如下图所示:
在这里插入图片描述
串行通信的特点: 传输线少, 长距离传送时成本低,且可以利用电话网等现成的设备, 但数据的传送控制比并行通信复杂。

(2)并行通信
并行通信通常是将数据字节的各位用多条数据线同时进行传送, 通常是 8位、16 位、32 位等数据一起传输。 如下图所示:
在这里插入图片描述
并行通信的特点: 控制简单、 传输速度快; 由于传输线较多, 长距离传送时成本高且接收方的各位同时接收存在困难, 抗干扰能力差。

异步通信与同步通信

(1)异步通信
异步通信是指通信的发送与接收设备使用各自的时钟控制数据的发送和接收过程。 为使双方的收发协调, 要求发送和接收设备的时钟尽可能一致。
异步通信是以字符(构成的帧) 为单位进行传输, 字符与字符之间的间隙(时间间隔) 是任意的, 但每个字符中的各位是以固定的时间传送的, 即字符之间不一定有“位间隔” 的整数倍的关系, 但同一字符内的各位之间的距离均为“ 位间隔” 的整数倍。 如下图所示:
在这里插入图片描述
异步通信的特点: 不要求收发双方时钟的严格一致, 实现容易, 设备开销较小, 但每个字符要附加 2~3 位用于起止位, 各帧之间还有间隔, 因此传输效率不高。
(2)同步通信
同步通信时要建立发送方时钟对接收方时钟的直接控制, 使双方达到完全同步。 此时, 传输数据的位之间的距离均为“位间隔” 的整数倍, 同时传送的字符间不留间隙, 即保持位同步关系, 也保持字符同步关系。 发送方对接收方的同步可以通过两种方法实现。 如下图所示:
在这里插入图片描述

单工、 半双工与全双工通信

(1) 单工通信
单工是指数据传输仅能沿一个方向, 不能实现反向传输。 如下图所示:
在这里插入图片描述
(2) 半双工通信
半双工是指数据传输可以沿两个方向, 但需要分时复用一根数据线进行。 如下图所示:
在这里插入图片描述
(3) 全双工通信
全双工是指数据可以同时进行双向传输。 如下图所示:
在这里插入图片描述

通信速率

衡量通信性能的一个非常重要的参数就是通信速率, 通常以比特率(Bitrate)来表示。 比特率是每秒钟传输二进制代码的位数, 单位是: 位/ 秒(bps) 。 如每秒钟传送 240 个字符, 而每个字符格式包含 10 位(1 个起始位、 1 个停止位、8 个数据位), 这时的比特率为:
                                                  10 位× 240 个/秒 = 2400 bps

在后面会遇到一个“波特率” 的概念, 它表示每秒钟传输了多少个码元。 而码元是通信信号调制的概念, 通信中常用时间间隔相同的符号来表示一个二进制数字, 这样的信号称为码元。 如常见的通信传输中, 用 0V 表示数字 0, 5V 表示数字 1, 那么一个码元可以表示两种状态 0 和 1, 所以一个码元等于一个二进制比特位, 此时波特率的大小与比特率一致; 如果在通信传输中, 有 0V、 2V、4V 以及 6V 分别表示二进制数 00、 01、 10、 11, 那么每个码元可以表示四种状态, 即两个二进制比特位, 所以码元数是二进制比特位数的一半, 这个时候的波特率为比特率的一半。 由于很多常见的通信中一个码元都是表示两种状态,所以我们常常直接以波特率来表示比特率。

51单片机串口介绍

串口介绍

串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单可实现两个设备的互相通信。

在这里插入图片描述
在这里插入图片描述
前两种电平的传输距离超过十几米错误率就很高了,而RS485电平传输距离可以达到千米以上。

常见的通信接口比较
在这里插入图片描述

串口通信简介

串口通信(Serial Communication), 是指外设和计算机间通过数据信号线、地线等按位进行传输数据的一种通信方式, 属于串行通信方式。 串口是一种接口标准, 它规定了接口的电气标准, 没有规定接口插件电缆以及使用的协议。
(1)接口标准
串口通信的接口标准有很多, 有 RS-232CRS-232RS-422ARS-485 等。常用的是 RS-232RS-485RS-232 其实是 RS-232C 的改进, 原理是一样的。这里我们就以 RS-232C 接口进行讲解。RS-232C 是 EIA(美国电子工业协会) 1969 年修订 RS-232C 标准。 RS-232C定义了数据终端设备(DTE) 与数据通信设备(DCE) 之间的物理接口标准。RS-232C 接口规定使用 25 针连接器, 简称 DB25, 连接器的尺寸及每个插
针的排列位置都有明确的定义, 如下图所示:
在这里插入图片描述

RS-232C 还有一种 9 针的非标准连接器接口, 简称 DB9。 串口通信使用的大多都是 DB9 接口。 DB25DB9 接头有公头和母头之分, 其中带针状的接头是公头, 而带孔状的接头是母头。 9 针串口线的外观图如下图所示:

在这里插入图片描述

从上图中可以看到公头和母头的管脚定义顺序是不一样, 这一点需要特别注意。 这些管脚都有什么作用呢? 9 针串口和 25 针串口常用管脚的功能说明如下图所示:
在这里插入图片描述

在串口通信中, 通常我们只使用 2、 3、 5 三个管脚, 即 TXD(transmit exchange data)RXDSGND,其他管脚功能大家看不明白也没关系。RS-232C 对逻辑电平也做了规定, 如下:
在 TXD 和 RXD 数据线上:
1.逻辑 1 为-3~-15V 的电压
2.逻辑 0 为 3~15V 的电压

在 RTS、 CTS、 DSR、 DTR 和 DCD 等控制线上:
1.信号有效( ON 状态) 为 3~15V 的电压
2.信号无效( OFF 状态) 为-3~-15V 的电压

由此可见, RS-232C 是用正负电压来表示逻辑状态, 与晶体管-晶体管逻辑集成电路(TTL) 以高低电平表示逻辑状态的规定正好相反。 而我们 51 单片机使用的就是 TTL 电平, 所以要实现 51 单片机与计算机的串口通信, 需要进行 TTLRS-232C 电平转换, 通常使用的电平转换芯片是 MAX232。

在串口通信中通常 PC 机的 DB9 为公头, 单片机上使用的串口 DB9 为母头,通过一根直通串口线进行相连。 在 9 针串口线实物图即为直通型串口线, 串口线(COM) 母头连接计算机 DB9 的公头, 串口线公头连接单片机上使用的 DB9 母头, 这样就是将 2、 3、 5 管脚直接相连。 如果你要实现两台计算机串口通信,那么就需要一根交叉串口线, 将 2 对 3、 3 对 2、 5 对 5 连接, 交叉串口线一般两头都是母头。

串口通信中还需要注意的是, 串口数据收发线要交叉连接, 计算机的 TXD 要对应单片机的 RXD, 计算机的 RXD 要对应单片机的 TXD, 并且共 GND, 如下图:
在这里插入图片描述
有的朋友就会问了, 在计算机与单片机进行串口通信时, 使用的不是直通线吗, 这时候怎么让 TXD 与 RXD 交叉连接? 前面我们说了单片机处理的是 TTL电平, 需要使用 RS232 电平转换芯片, 将 RS232 电平转换芯片串行数据输出管脚交叉连接在 DB9 母头上即可, 本章后面硬件设计部分会介绍。
(2)通信协议
RS232 的通信协议比较简单, 通常遵循 96-N-8-1 格式。“96” 表示的是通信波特率为 9600。 串口通信中通常使用的是异步串口通信, 即没有时钟线, 所以两个设备要通信, 必须要保持一致的波特率, 当然, 波特率常用值还有 4800、 115200 等。

“N” 表示的是无校验位, 由于串口通信相对更容易受到外部干扰导致传输数据出现偏差, 可以在传输过程加上校验位来解决这个问题。 校验方法有奇校验(odd)、 偶校验(even)、 0 校验(space)、 1 校验(mark)以及无校验(noparity)。具体的介绍, 大家可以百度串口通信了解。

8”表示的是数据位数为 8 位, 其数据格式在前面介绍异步通信中已讲过。当然数据位数还可以为 5、 6、 7 位长度。“1” 表示的是 1 位停止位, 串口通讯的一个数据包从起始信号开始, 直到停止信号结束。 数据包的起始信号由一个逻辑 0 的数据位表示, 而数据包的停止信号可由 0.5、 1、 1.5 或 2 个逻辑 1 的数据位表示, 只要双方约定一致即可。

(3) 串口内部结构

在这里插入图片描述

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

上图中右边的 TXDRXD 为单片机 IO 口, TXD 对应的是 P3.1 管脚, RXD 对应的是 P3.0 管脚。 其内部工作方式在后面小节会介绍。

串口相关寄存器

在这里插入图片描述
下面介绍部分寄存器

(1) 串口控制寄存器 SCON
在这里插入图片描述
SM0 和 SM1 为工作方式选择位:
在这里插入图片描述

SM2: 多机通信控制位, 主要用于方式 2 和方式 3。 当 SM2=1 时可以利用收到的 RB8 来控制是否激活 RI(RB8=0 时不激活 RI, 收到的信息丢弃; RB8=1 时收到的数据进入 SBUF, 并激活 RI, 进而在中断服务中将数据从 SBUF 读走) 。 当SM2=0 时, 不论收到的 RB8 为 0 和 1, 均可以使收到的数据进入 SBUF, 并激活 RI(即此时 RB8 不具有控制 RI 激活的功能) 。 通过控制 SM2, 可以实现多机通信。

REN: 允许串行接收位。 由软件置 REN=1, 则启动串行口接收数据; 若软件置REN=0, 则禁止接收。

TB8: 在方式 2 或方式 3 中, 是发送数据的第 9 位, 可以用软件规定其作用。可以用作数据的奇偶校验位, 或在多机通信中, 作为地址帧/数据帧的标志位。在方式 0 和方式 1 中, 该位未用到。

RB8: 在方式 2 或方式 3 中, 是接收到数据的第 9 位, 作为奇偶校验位或地址帧/数据帧的标志位。 在方式 1 时, 若 SM2=0, 则 RB8 是接收到的停止位。

TI(transmit interrupt): 发送中断标志位。 在方式 0 时, 当串行发送第 8 位数据结束时, 或在其它方式, 串行发送停止位的开始时, 由内部硬件使 TI 置 1, 向 CPU 发中断申请。在中断服务程序中, 必须用软件将其清 0, 取消此中断申请。

RI(receive interrupt): 接收中断标志位。 在方式 0 时, 当串行接收第 8 位数据结束时, 或在其它方式, 串行接收停止位的同时, 由内部硬件使 RI 置 1, 向 CPU 发中断申请。也必须在中断服务程序中, 用软件将其清 0, 取消此中断申请。

(2) 电源控制寄存器 PCON
在这里插入图片描述
SMOD:波特率倍增位。 在串口方式 1、 方式 2、 方式 3 时, 波特率与 SMOD 有关, 当 SMOD=1 时, 波特率提高一倍。 复位时, SMOD=0。

串口工作方式

前面在介绍寄存器时已经知道了 51 单片机串口的几种工作方式, 下面分别来对它介绍。

方式0

方式 0 时, 串行口为同步移位寄存器的输入输出方式。 主要用于扩展并行输入或输出口。 数据由 RXD(P3.0) 引脚输入或输出, 同步移位脉冲由 TXD(P3.1)引脚输出。 发送和接收均为 8 位数据, 低位在先, 高位在后。 波特率固定为fosc/12(“fosc” 表示系统的振荡频率,“波特率 = fosc/12” 意味着每秒传输的符号数等于振荡频率除以12。例如,如果系统的振荡频率为120,000 Hz(也就是12MHz),那么根据这个公式,波特率将为120,000 Hz / 12 = 10,000 Baud。这意味着在每秒内会传输10,000个符号。)。 对应的输入输出时序图如下所示:

①方式 0 输出
在这里插入图片描述

②方式 0 输入
在这里插入图片描述

方式1

方式 1 是 10 位数据的异步通信口。 TXD 为数据发送引脚, RXD 为数据接收引脚, 传送一帧数据的格式如下所示。 其中 1 位起始位, 8 位数据位, 1 位停止位。
在这里插入图片描述
①方式 1 输出
在这里插入图片描述
②方式 1 输入
在这里插入图片描述
用软件置 REN 为 1 时, 接收器以所选择波特率的 16 倍速率采样 RXD 引脚电平, 检测到 RXD 引脚输入电平发生负跳变时, 则说明起始位有效, 将其移入输入移位寄存器, 并开始接收这一帧信息的其余位。 接收过程中, 数据从输入移位寄存器右边移入, 起始位移至输入移位寄存器最左边时, 控制电路进行最后一次移位。 当 RI=0, 且 SM2=0(或接收到的停止位为 1) 时, 将接收到的 9 位数据的前8 位数据装入接收 SBUF, 第 9 位(停止位) 进入 RB8, 并置 RI=1, 向 CPU 请求中断。

方式 2 和方式 3

方式 2 或方式 3 时为 11 位数据的异步通信口。 TXD 为数据发送引脚, RXD 为数据接收引脚。 其数据格式如下所示:
在这里插入图片描述
对应的输入输出时序图如下所示:
①方式 2、方式 3 输出
在这里插入图片描述
发送开始时, 先把起始位 0 输出到 TXD 引脚, 然后发送移位寄存器的输出位(D0)到 TXD 引脚。每一个移位脉冲都使输出移位寄存器的各位右移一位, 并由TXD 引脚输出。 第一次移位时, 停止位“1” 移入输出移位寄存器的第 9 位上,以后每次移位, 左边都移入 0。 当停止位移至输出位时, 左边其余位全为 0, 检测电路检测到这一条件时, 使控制电路进行最后一次移位, 并置 TI=1, 向 CPU请求中断。

②方式 2、 方式 3 输入
在这里插入图片描述

接收时, 数据从右边移入输入移位寄存器, 在起始位 0 移到最左边时, 控制电路进行最后一次移位。 当 RI=0, 且 SM2=0(或接收到的第 9 位数据为 1) 时,接收到的数据装入接收缓冲器 SBUF 和 RB8(接收数据的第 9 位) , 置 RI=1, 向CPU 请求中断。 如果条件不满足, 则数据丢失, 且不置位 RI, 继续搜索 RXD 引脚的负跳变。

串口的使用方法(计算波特率)

(1)如何计算波特率
在学习 51 单片机串口时, 非常重要的一点是学会如何计算波特率。 以下列出了几种方式下波特率的计算公式:
方式 0 的波特率 = fosc/12
方式 1 的波特率 =(2SMOD/32)×(T1 溢出率)
方式 2 的波特率 =(2SMOD/64)× fosc
方式 3 的波特率 =(2SMOD/32) ×(T1 溢出率)
其中 T1 溢出率 = fosc /{12× [256 -(TH1)]}, 当然还可以使用STC-ISP内附带的小工具自动生成波特率。
在这里插入图片描述

举个例子:
在这里插入图片描述

设TL1=0XF3

假设晶振频率为12MHZ,所以晶振周期为1/12M(单位是s)。定时器时钟为12T,也就是12个时钟周期(晶振周期),机器完成一条指令。
所以机器完成一条指令所需的时间为:1/12M×12=1/1M=1us

F3换算成2进制为243,需要13us才会溢出一次

所以溢出频率就是1/13us=0.07692307692307692307692307692308MHZ

SMOD置为1,则走上面,无需除以2;置于0,则走下面,需要除以2,相当于波特率减倍

最后波特率=0.07692307692307692307692307692308MHZ÷16=0.00480769MHZ=4807.69HZ

为什么最后不是4800hz呢?因为这就是设计不够精细有误差,用STC-ISP中的小工具波特率计算器计算也可知:
在这里插入图片描述
会有0.16%的误差,这多出来的7.69正好就是0.16%的误差
在这里插入图片描述

(2) 串口初始化步骤
如何使用串口, 大家可以按照以下几个步骤配置。
①确定 T1 的工作方式(TMOD 寄存器) ;
②确定串口工作方式(SCON 寄存器) ;
③计算 T1 的初值(设定波特率) , 装载 TH1、 TL1;
④启动 T1(TCON 中的 TR1 位) ;
⑤如果使用中断, 需开启串口中断控制位(IE 寄存器) 。
例如: 设置串口为工作方式 1、 波特率为 9600、 波特率加倍、 使用中断。 其配置程序如下:

/*******************************************************************************
* 函 数 名 : uart_init
* 函数功能 : 串口通信中断配置函数, 通过设置 TH 和 TL 即可确定定时时间
* 输 入 : baud: 波特率对应的 TH、 TL 装载值
* 输 出 : 无
*******************************************************************************/
void uart_init(u8 baud)
{
TMOD|=0X20; //设置计数器工作方式 2
SCON=0X50; //设置为工作方式 1
PCON=0X80; //波特率加倍
TH1=baud; //计数器初始值设置
TL1=baud;
ES=1; //打开接收中断
EA=1; //打开总中断
TR1=1; //打开计数器
}

在主函数中调用该函数并传入 0XFA 值即可, 如下:

uart_init(0XFA);//波特率为 9600

硬件设计

开发板上板载一个 USB 转串口模块。 其硬件电路如下所示:
在这里插入图片描述

软件设计

本节所要实现的功能是:

1、向单片机发送数据 0x11

#include "reg52.h"

void UartInit(void)		//4800bps@11.0592MHz
{
	PCON |= 0x80;		//使能波特率倍速位SMOD,也就是使波特率提高一倍
	SCON = 0x40;		//8位数据,可变波特率
	TMOD &= 0x0F;		//清除定时器1模式位,也就是高4位全部置为0
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xF4;		//设定定时初值
	TH1 = 0xF4;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}

void UART_SendByte(unsigned char Byte)
{
	SBUF=Byte;
	while(T1==0);
	T1=0;
}

void main()
{
	UartInit();
	UART_SendByte(0x11);
	while(1)
	{
	
	}
}

把程序下载进板子,设置好串口号和波特率后(校验位一般设置为无校验,停止位一般设置为1位),点击51单片机开发板上的复位键,上方的白框中就会显示11
在这里插入图片描述

2、向单片机发送一个不断加1的数

#include "reg52.h"

typedef unsigned int u16;
unsigned char Sec=0;

void delay(u16 i)
{
	while(i--);
}

void UartInit(void)		//4800bps@11.0592MHz
{
	PCON |= 0x80;		//使能波特率倍速位SMOD,也就是使波特率提高一倍
	SCON = 0x40;		//8位数据,可变波特率
	TMOD &= 0x0F;		//清除定时器1模式位,也就是高4位全部置为0
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xF4;		//设定定时初值
	TH1 = 0xF4;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}

void UART_SendByte(unsigned char Byte)
{
	SBUF=Byte;
	while(TI==0);
	TI=0;
}

void main()
{
	UartInit();
	while(1)
	{		
		UART_SendByte(Sec);
		Sec++;
		delay(1000000);		
	}
}

在这里插入图片描述

3、通过电脑端发送一个数据去点亮led灯

中断号为4的中断是串口中断,随意向51单片机发送一个数据,即可触发该中断,从而点亮对应的led灯

#include "reg52.h"

void UartInit(void)		//4800bps@11.0592MHz
{
	PCON |= 0x80;		//使能波特率倍速位SMOD,也就是使波特率提高一倍
	SCON = 0x50;		//8位数据,可变波特率
	TMOD &= 0x0F;		//清除定时器1模式位,也就是高4位全部置为0
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xF4;		//设定定时初值
	TH1 = 0xF4;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
	EA=1;
	ES=1;
}

void main()
{
	UartInit();
	while(1)
	{			
	}
}

void UART_Routine() interrupt 4
{
	if(RI==1)
	{
		P2=SBUF;
		RI=0;
	}
	
}

串口在接收到数据之后,硬件会自动将RI=1。
只要RI>=1或者TI>=1就会触发串口中断,也就是发送和接收都会触发中断。前提是程序打开了总中断和串口中断。
为什么要加if(RI==1)判断?因为发送和接收都会触发中断,当接收了时,RI会被自动置为1。
这样根据P2被赋给的值即可点亮相应的led灯

在这里插入图片描述
最右边四个灯会亮起

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言第二十二弹---指针(六)

✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】 指针 1. 回调函数是什么? 2、qsort使用举例 2.1、使用qsort函数排序整型数据 2.2 使用qsort排序结构体数据 3、qsort函数的模拟实现 总结 1. 回…

机器学习---概率图模型(概率计算问题)

1. 直接计算法 给定模型和观测序列,计算观测序列O出现的概率。最直接 的方法是按概率公式直接计算.通过列举所有可能的长度为T的状态序列,求各个状 态序列 I 与观测序列的联合概率,然后对所有可能的状态序列求和,得 到。 状态…

【C++】多态语法概念

目录 一、概念及定义二、虚函数重写的特例三、final和override四、抽象类 一、概念及定义 概念:在继承关系下的不同类,调用同一个函数,产生不同的行为,叫作多态。 图示: 定义:必须通过基类的指针或者引…

代码随想录算法训练营第四十八天(动态规划篇之01背包)| 1049. 最后一块石头的重量Ⅱ,494. 目标和

1049. 最后一块石头的重量Ⅱ 题目链接:1049. 最后一块石头的重量 II - 力扣(LeetCode) 思路 尽量将石头分为重量相同的两堆,这样两堆中的石头相撞之后剩下的石头就会最小。根据之前的01背包理论: 代码随想录算法训…

C语言easyx 贪吃蛇大作战,没有模仿,只有超越

作品名称:贪吃蛇大作战 版本历史和日期:V1.0 - 2024年2月11日 简介: 贪吃蛇大作战是一个基于EasyX图形库的经典贪吃蛇游戏。玩家通过键盘控制贪吃蛇的移动方向,目标是吃掉屏幕上随机生成的食物点,每吃掉一个食物点,蛇身就会增长一节。游戏提供三种模式:无屏障模式、有…

2024牛客寒假算法基础集训营2

C Tokitsukaze and Min-Max XOR 题目大意 给定一个数组从任取数构成序列序列满足,(可以只取一个数)问能构造出多少个 解题思路 定找双枚举时间复杂度到,考虑利用加速统计的方案,即将数字按二进制位拆分挂在树上对于…

vtk三维场景基本要素 灯光、相机、颜色、纹理映射 简介

整理一下VTK 三维场景基本要素,后面会一一进行整理; 1. 灯光 vtkLight 剧场里有各式各样的灯光,三维渲染场景中也一样,可以有多个灯光存在。灯光和相机 是三维渲染场景必备的要素,vtkRenderer会自动创建默认的灯光和…

第76讲安全退出实现

安全退出实现 VueX 是一个专门为 Vue.js 应用设计的状态管理构架,统一管理和维护各个vue组件的可变化状态(你可以理解成 vue 组件里的某些 data )。 Vuex有五个核心概念: state, getters, mutations, actions, modules。 state:vuex的基本数…

Blazor 子组件交互例子

源码 子组件 SwitchBar.razor &#xfeff;using Microsoft.Extensions.Logging inject ILogger<Index> Logger<div style"ClassString" onclick"OnClick">ChildContent </div>code {[Parameter]public RenderFragment? ChildContent…

element ui表格手写拖动排序

效果图&#xff1a; 思路&#xff1a; 重点在于&#xff1a;拖动行到某一位置&#xff0c;拿到这一位置的标识&#xff0c;数据插入进这个位置 vueuse的拖拽hooks useDraggable 可以用&#xff1b;html5 drag能拖动行元素&#xff1b;mounsedown、mounsemove时间实现拖拽 页…

嵌入式电子产品开发感悟!

​ 2023特别深有感触的有以下几个事件&#xff1a; 1. 早在2月底就提交报告&#xff1a;抓紧开一款便携式的空气波压力按摩仪外壳&#xff0c;包括模具费和100台试产物料费用总计不超过22W&#xff0c;保证最迟在4月中旬全部生产好&#xff0c;以供业务参加5月份开始的大健康展…

C++对象继承

继承概念&#xff1a; 首先引入一个生活例子&#xff0c;普通人是一个类对象&#xff0c;学生是一个类对象&#xff0c;普通人拥有的属性学生一定会有&#xff0c;学生拥有的属性普通人不一定有。类比一下&#xff0c;把普通人抽象为A对象&#xff0c;学生抽象为B对象&#xf…

【知识整理】接手新技术团队、管理团队

引言 针对目前公司三大技术中心的不断升级&#xff0c;技术管理岗位要求越来越高&#xff0c;且团队人员特别是管理岗位的选择任命更是重中之重&#xff0c;下面针对接手新的技术团队做简要整理&#xff1b; 一、实践操作 1、前期准备 1、熟悉情况&#xff1a; 熟悉人员&am…

【开源】JAVA+Vue.js实现计算机机房作业管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 登录注册模块2.2 课程管理模块2.3 课时管理模块2.4 学生作业模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 课程表3.2.2 课时表3.2.3 学生作业表 四、系统展示五、核心代码5.1 查询课程数据5.2 新增课时5.3 提交作…

基于JSP的网上购书系统

点击以下链接获取源码&#xff1a; https://download.csdn.net/download/qq_64505944/88825694?spm1001.2014.3001.5503 Java项目-15 源码论文数据库配置文件 基于JSP的网上购书系统 摘要 在当今的社会中&#xff0c; 随着社会经济的快速发展以及计算机网络技术和通讯技术…

C语言-----自定义类型-----结构体枚举联合

结构体和数组一样&#xff0c;都是一群数据的集合&#xff0c;不同的是数组当中的数据是相同的类型&#xff0c;但是结构体中的数据类型可以不相同&#xff0c;结构体里的成员叫做成员变量 结构体类型是C语言里面的一种自定义类型&#xff0c;我们前面已经了解到过int,char,fl…

【matalab】基于Octave的信号处理与滤波分析案例

一、基于Octave的信号处理与滤波分析案例 GNU Octave是一款开源软件&#xff0c;类似于MATLAB&#xff0c;广泛用于数值计算和信号处理。 一个简单的信号处理与滤波分析案例&#xff0c;说明如何在Octave中生成一个有噪声的信号&#xff0c;并设计一个滤波器来去除噪声。 首…

华为问界M9:领跑未来智能交通的自动驾驶黑科技

华为问界M9是一款高端电动汽车&#xff0c;其自动驾驶技术是该车型的重要卖点之一。华为在问界M9上采用了多种传感器和高级算法&#xff0c;实现了在不同场景下的自动驾驶功能&#xff0c;包括自动泊车、自适应巡航、车道保持、自动变道等。 华为问界M9的自动驾驶技术惊艳之处…

《PCI Express体系结构导读》随记 —— 第II篇 第4章 PCIe总线概述(11)

接前一篇文章&#xff1a;《PCI Express体系结构导读》随记 —— 第II篇 第4章 PCIe总线概述&#xff08;10&#xff09; 4.2 PCIe体系结构的组成部件 PCIe总线作为处理器系统的局部总线&#xff0c;其作用与PCI总线类似&#xff0c;主要目的是为了连接处理器系统中的外部设备…

k8s-深入理解Service(为Pod提供负载均衡和发现)

一、Service存在的意义 二、Service的定义和创建 Pod与Service的关系 Service的定义和创建 三、Service使用NodePort对外暴露应用 四种类型&#xff0c;常用的三种&#xff1a; 指定Service的NodePort端口 在实际生产中&#xff0c;k8s的集群不会直接暴露在公网中&#xff0c…