03-51单片机定时器和串口通信

news2025/1/13 0:47:04

一、51单片机定时器

1.定时器介绍

1.1为什么要使用定时器

在前面的学习中,用到了 Delay 函数延时,这里学习定时器以后,就可以通过定时器来完成,当然定时器的功能远不止这些:

  1. 51 单片机的定时器既可以定时,又可以计数,故称之为定时器/计数器;
  2. 定时器/计数器和单片机的 CPU 是相互独立的,定时器/计数器工作的过程是自动完成的,不需要 CPU 的参与,相比于 Delay 函数需要 CPU 才能运行,节约了 CPU 资源;
  3. 51 单片机中的定时器/计数器有两种计时/计数方式:一是机器内部的时钟,二是外部的脉冲信号对寄存器中的数据加 1;
  4. 通过定时器/计数器,可以增加单片机的效率,一些简单的重复加 1 的工作可以交给定时器/计数器处理,CPU 转而处理一些复杂的事情,同时可以实现精确定时作用。

1.2定时器的结构

  • 定时器/计数器的结构示意图如下:

在这里插入图片描述

  1. T0 和 T1 引脚对应单片机的 P34 和 P35 管脚,定时器由两个特殊功能的寄存器控制:工作方式寄存器(TMOD)用于确定工作方式和功能、控制寄存器(TCON)用于控制 T0、T1 的启动和停止及设置溢出标志;

  2. 工作方式寄存器(TMOD):其低四位用于 T0,高四位用于 T1,不可位寻址:

    在这里插入图片描述

    GATE 是门控位;

    C/T :定时/计数模式选择位,C/T =0 为定时模式,C/T =1 为计数模式;

    M1和 M0:工作方式设置位,00 01 10 11 分别代表 方式0 方式1 方式2 方式3。

  3. 控制寄存器(TCON):低 4 位用于控制外部中断,高 4 位用于控制定时/计数器的启动和中断申请,可位寻址:

    在这里插入图片描述

    TF1:T1 溢出中断请求标志位,T1 计数溢出时由硬件自动置 TF1为 1,CPU 响应中断后 TF1 由硬件自动清 0;

    TR1:T1 运行控制位,TR1 置 1 时,T1 开始工作,TR1 置 0 时,T1 停止工作;

    TF0 和 TR0 同上,只不过是针对 T0 号引脚;

    IE1:外部中断 1 中断请求标志位;

    IT1:外部中断 1 中断请求标志位;

    IT0 和 IE0 同理;

    TL0和TH0:机器周期脉冲,它们每个占4字节,两个组成了8字节,TL0是低4位,TH0高4位。每发出一次脉冲,计数器 + 1,最大值为65535,超过最大值就会导致中断位置1。可以为其设置初始值,计算每一次脉冲需要多少时间,然后得到固定时间如 1ms 会发生多少次脉冲,这样就能达到计时效果。

1.3定时器工作原理

上面介绍定时器的工作方式有四种,我们主要使用方式1, 16位定时计数器,其工作模式结构体如下:

在这里插入图片描述

在这里插入图片描述

  1. STC89C52RC 单片机内有两个可编程的定时/计数器 T0、T1 和一个特殊功能定时器 T2,定时/计数器的实质是加 1 计数器(16 位),由高 8 位和低 8 位两个寄存器 TH0 和 TL0 组成,最大值为 65535;
  2. 如图时钟系统每来一个脉冲,计数系统就自动加 1,当加到计数器为全 1 时,再输入一个脉冲就使计数器溢出回零,同时使相应的中断标志位 TF0 置 1,向 CPU 发出中断请求。如果是在计数模式,表明计数已满,类似于我们 while 循环时回写一个计数器,每运行一次+1、定时模式,表示定时时间已满,类似于之前用的delay函数,延时已到;
  3. SYSclk:系统时钟,即晶振周期,晶振是一个能发生固定频率振动的器件,本开发板上的晶振为11.0592MHz(前面说错了,但不影响代码逻辑),C/T 为0时使用系统时钟,功能相当于定时器;
  4. T0 Pin:单片机外部引脚,C/T 为 1 时使用 T0 引脚,功能相当于计数器;
  5. GATE:上面介绍它是门控位,它能决定是否能够由 TR0 或 TR1 单独控制启动定时器。如果 GATE 为 0 ,经过非门为 1 ,经过或门,不管外部中断 INTO 是什么,结果还是 1 ,然后与上 TR0 或 TR1,TR0 或 TR1 为 1 代表打开计数器,为 0 关闭,可以单独控制计数器开关状态,不受外部中断 INTO 的影响;
  6. 计数器初值与计数个数的关系为:X=2^16 - N,X 为初值,N 为个数。

1.5定时器与中断

中断系统是为了使 CPU 具有对外界紧急事件的实时处理能力而设置的。

  • 原理图:

在这里插入图片描述

如图所示,当我们正在运行某个程序的时候,发出了某些特定的 “信号” ,如:计时器结束,或计数器达到预定值的时候,就会发出中断请求,CPU 收到中断请求,暂停主程序,转而去执行中断程序,等中断程序执行完成,再返回继续执行主程序。

STC89C52RC 单片机提供了 8 个中断请求源:外部中断0(INTO)、外部中断 1(INT1)、外部中断 2(INT2)、外部中断 3(INT3)、定时器 0中断、定时器 1 中断、定时器 2 中断、串口(UART)中断。当多个中断发生的时候,具体先执行哪个中断程序,要看中断的优先级,优先级高的先执行,低的后执行。如果一个中断程序正在执行,但是有一个中断优先级更高的中断请求,这暂停当前中断程序,去执行优先级更高的中断程序,这个叫中断嵌套。

  • 中断内部结构图:

在这里插入图片描述

  • 说明:目前不使用外部中断,因此外部中断暂时不讲:
    1. T0 对应的是 P3.4 口的附加功能,TF0(TCON.5),片内定时/计数器 T0 溢出中断请求标志,当定时/计数器 T0 溢出时,TF0位置 1 ,并向 CPU 申请中断。
    2. T1 对应的是 P3.5 口的附加功能,TF1(TCON.7),片内定时/计数器 T1溢出中断请求标志,当定时/计数器 T1 溢出时,TF1位置1,并向 CPU 申请中断。
    3. EA=1 时打开总中断开关;ET0=1,开时钟中断 0;PT0=0/1,选择中断触发方式。

2.定时器案例

2.1按键控制流水灯左右移动

  • 代码演示
  • Timer0.c:
#include <REGX52.H>

// 手动写的
void Timer0_Init()
{
	// 配置 TMOD
	// TMOD=0x01;
	TMOD=TMOD&0xF0;
	TMOD=TMOD|0x01;
	// 配置 TCON
	TF0=0; // 默认中断是关闭的
	TR0=1; // 开启0号定时器
	// 赋初值
	TH0=0xFC; // 1111 1100
	TL0=0x18; // 0001 1000
	// 配置中断
	ET0=1;
	EA=1;
	PT0=0;
}

// 软件生成的
void Timer0Init(void)		//1毫秒@12.000MHz
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	// 软件生成的不包括中断配置,要手动添加
	ET0=1;
	EA=1;
	PT0=0;
}

// 定时器中断函数模板,因为定时器会用到主函数的一些东西
// 不太方便模块化
/*

// 发生中断请求时执行的中断函数
void Timer0_Routine() interrupt 1
{	
	// 定义变量用于计算中断函数执行次数,应设置静态,否则函数每次调用结束就释放了,永远无法加到1000
	static unsigned int Count=0;
	// 赋初值
	TH0=0xFC;
	TL0=0x18;
	Count++;
	if(Count >= 1000) // 设置1000即执行中断函数1000次,1000ms=1s
	{
		Count=0;
	}
}

*/
  1. 配置 TMOD 的时候,可以直接给它赋值,如TMOD=0x01,但这样有个坏处就是只能给 Timer0 设置,如果本来 Timer1 就有设置,那么这种写法会将高四位置0,将 Timer1 的设置清空。因此,可以先将原本的 TMOD 按位与清空低四位:TMOD=TMOD&0xF0,按位与,遇 1 不变,遇 0 置 0 ;再将 TMOD 按位与上对应的断码,只设置低四位:TMOD |= 0x01。这样就完成了只针对 Timer0 的设置,同时不影响 Timer1 ;

  2. 这里的 TMOD 配置,使用方式1,定时模式,Timer1 时钟,TR0 单独控制,参照表格,将对应位赋值就行;

  3. 配置 TCON 的时候,TF0=0将中断默认设置为关闭,如果设置 1 的话,那么一运行就会发生中断;

  4. 计数器赋初值的时候,因为其由两个四位组成,因此分别对高 4 位和低 4 位赋值。单片机内部时钟频率是外部时钟的 12 分频,12MHZ 晶振,单片机内部的时钟频率就是 12/12MHZ,机器周期=1/1M=1us,即每 1 纳秒发送一个脉冲,计数器加一,那么要想定时 1ms 就需要 1000 次脉冲,但计数器最大值为 65535 ,65536时溢出中断,因此,只需要将初始值赋为 64535 即可;

    64535 == 1111 1100 0001 1000;
    
    将其分为高低4位就是:
    TH0=0xFC; // 1111 1100
    TL0=0x18; // 0001 1000
    
    不过还另外一种写法:
    TH0=65534/256;
    TL0=65534%256;
    
  5. 中断函数不需要放到主函数里去运行,当发出中断信号的时候,会触发其自动调用。每执行一次中断函数,都要为其赋初值,因为溢出后计数器会变 0,不赋初值,下一次会从 0 开始计数,而不是从我们指定值开始。

  • Timer0.h:
#ifndef __TIMER0_H__
#define __TIMER0_H__

// 软件生成的
void Timer0Init(void);

#endif
  • Key.c:
#include <REGX52.H>
#include "Delay.h"

unsigned char Key()
{
	unsigned char Num=0;
	if(P3_1==0){Delayxms(20);while(P3_1==0);Delayxms(20);Num=1;}
	if(P3_0==0){Delayxms(20);while(P3_0==0);Delayxms(20);Num=2;}
	if(P3_2==0){Delayxms(20);while(P3_2==0);Delayxms(20);Num=3;}
	if(P3_3==0){Delayxms(20);while(P3_3==0);Delayxms(20);Num=4;}
    
	return Num;
}
  • Key.h:
#ifndef __KEY_H__
#define __KEY_H__

unsigned char Key();

#endif
  • main.c:
#include <REGX52.H>
#include "Timer0.h"
#include "Key.h"
#include <INTRINS.H>

// KeyNum用于保存独立按键的键盘对应数值
// LEDMode用于保存流水灯方向的状态值,为1,流水灯从 D1 - D8 ,反之 D8 - D1
unsigned char KeyNum,LEDMode;

void main()
{
    // 设置默认 D1 亮
	P2=0xFE;
    // 初始化定时器
	Timer0Init();
	while(1)
	{
		KeyNum=Key();
		if(KeyNum)
		{
			if(KeyNum==1)
			{
                // 按键控制 LEDMode 在 0 和 1 之间切换
				LEDMode++;
				if(LEDMode>=2)
                    LEDMode=0;
			}
		}
	}
}

void Timer0_Routine() interrupt 1
{
	static unsigned int Count;
	// 赋初值
	TL0 = 0x18;		
	TH0 = 0xFC;		
	Count++;		
	if(Count>=500) // 每 0.5 s执行一次中断函数
	{
		Count=0;
		if(LEDMode==0)
			P2=_crol_(P2,1); // 左移函数
		if(LEDMode==1)
			P2=_cror_(P2,1); // 右移函数
	}
}
  • 说明:
    1. 上面代码执行的效果,默认执行流水灯 D1 - D8 每 0.5 秒移动一个,按一次 K1 就变成 D8 - D1 移动,再按一次又恢复 D1 - D8 移动,如此循环;
    2. _crol__cror_是官方只带的库函数,使用时需要包含头文件#include <INTRINS.H>,分别代表左移和右移,第一个参数是要操作的8位寄存器,第二个参数是每次移动的步数;
    3. 要清除这里的左移右移并不是对于我们单片机上的 LED 的左移右移,因为有的 LED 是左到右由低到高排列的,有点是由高到低。其实际是相对一个一字节寄存器的8位就行左右移动的,一般左为低位,右为高位,左移就是低位到高位,右移就是高位到低位。因此,_crol_函数可以理解为是低位到高位移动,_cror_函数是高位到低位移动。

2.2 LCD1602 显示时钟

  • 代码演示
#include <REGX52.H>
#include "LCD1602.h"
#include "Timer0.h"

unsigned char Hour, Min, Sec, flag;

void main()
{
	// 初始化 LCD1602
	LCD_Init();
	// 初始化 Timer0
	Timer0Init();
		
	LCD_ShowChar(2, 3, ':');
	LCD_ShowChar(2, 6, ':');
	
	while(1)
	{
		// 显示时间
		LCD_ShowNum(2, 1, Hour, 2);
		LCD_ShowNum(2, 4, Min, 2);
		LCD_ShowNum(2, 7, Sec, 2);
	}
}


void Timer0_Routine() interrupt 1
{	
	static unsigned int Count;
	// 赋初值
	TH0=0xFC;
	TL0=0x18;
	Count++;
	if(Count >= 1000)
	{
		flag++;
		if(flag>=2)
			flag=0;
		if(flag==0)
			LCD_ShowString(1, 1, "MyClock ^_^     ");
		else if(flag==1)
			LCD_ShowString(1, 1, "MyClock ^.^     ");
		Count=0;
		Sec++;
		if(Sec>=60)
		{
			Sec=0;
			Min++;
			if(Min>=60)
			{
				Min=0;
				Hour++;
				if(Hour>=24)
				{
					Hour=0;
				}
			}
		}
	}
}
  • 说明:代码运行效果,就是一个普通的时钟显示,以24小时格式显示,上面的小表情每秒变换一次,这个代码的逻辑很简单,就不详细解释了。

二、串口通信

1.串口通信介绍

1.1串口通信方式分类

51单片机内部自带UART(Universal Asynchronous Receiver Transmitter,通用异步收发器),可实现单片机的串口通信。

  • 按数据传输方式分为:

    1. 串行通信:指使用一条数据线,将数据一位一位地依次传输,每一位数据占据一个固定的时间长度。只需要少数几条线就可以在系统间交换信息,适用于计算机与计算机、计算机与外设之间的远距离通信。可以理解为只有一条通道传输,同一时间只能过一位数据;
    2. 并行通信:通常是将数据字节的各位用多条数据线同时进行传送,通常是 8位、16 位、32 位等数据一起传输。可以理解为,一条通道同一时间只能传输一位数据,但它是多条通道,因此同一时间可以传输多位数字。
  • 按数据同步方式分为:

    1. 异步通信:指通信的发送与接收设备使用各自的时钟控制数据的发送和接收过程。为使双方的收发协调,要求发送和接收设备的时钟尽可能一致;
    2. 同步通信:要建立发送方时钟对接收方时钟的直接控制,通信双方靠一根时钟线来约定通信速率,使双方达到完全同步。
  • 按数据传输方向分为:

    1. 单工:通信只能由一方发送到另一方,不能反向传输;
    2. 半双工:通信双方可以互相传输数据,但必须分时复用一根数据线,即同一时刻只能一方给另外一方发,不能同时给对方发;
    3. 全双工:通信双方可以在同一时刻互相传输数据。

1.2硬件电路

在这里插入图片描述

  1. 简单双向串口通信有两根通信线(发送端TXD和接收端RXD);
  2. TXD与RXD要交叉连接,即一台计算机的TXD要与另外一台电脑的RXD连接;
  3. 当只需单向的数据传输时,可以直接一根通信线,发送的计算机接TXD,接收的计算机接RXD;
  4. 当电平标准不一致时,需要加电平转换芯片。

1.3电平标准

串口常用的电平标准有如下三种:

  1. TTL电平:5V 表示 1,0V 表示 0,电平值是相对于 GND 而言的;
  2. RS232电平:-3~-15V 表示1,3~15V 表示 0,电平值是相对于 GND 而言的;
  3. RS485电平:两线压差 2~6V 表示1,-2~-6V 表示 0(差分信号),电平值是两根导线的压差。

1.4UART的工作模式

STC89C52的UART有四种工作模式:

  1. 模式0:同步移位寄存器(00);
  2. 模式1:8位UART,波特率可变,常用(01);
  3. 模式2:9位UART,波特率固定(10);
  4. 模式3:9位UART,波特率可变(11)。

1.5串口参数和时序图

串口参数:

  1. 波特率:串口通信的速率,发送和接收各数据位的间隔时间,因为这里的串口通信是异步通信,没有时钟线,因此为保证收发数据的准确性,需要保证两个设备的波特率一致;
  2. 比特率:每秒钟传输二进制代码的位数,单位是:位/秒( bps);
  3. 检验位:用于数据验证,校验方法有奇校验(odd)、偶校验(even)、0 校验(space)、1 校验(mark)以及无校验(noparity);
  4. 停止位:用于数据帧间隔。

在这里插入图片描述

9位数据格式比8位数据格式多了1位数据,是检验位,主要用于检验数据是否有误。

因为数据是一位一位的发,每发一字节8位数据就会在接收端重组这八位数据得到一字节数据,每字节前后会有起始位和停止位,就是为了标记什么时候开始的一字节数据传输,什么时候一字节传输完成,接收方可以重组数据了。

1.6串口模式图

在这里插入图片描述

  1. SBUF:串口数据缓存寄存器,物理上是两个独立的寄存器,但占用相同的地址。写操作时,将数据写入发送寄存器来发送,读操作时,将接收到的数据读到接收寄存器;
  2. 通过时钟 Timer1 的溢出率控制波特率,经过 2 分频或 16 分频来控制收发控制器的采样时间;
  3. 当有数据发送或者有数据接收完成的时候,都会产生中断申请,执行中断函数。

1.7串口相关寄存器

在这里插入图片描述

  • 串口控制寄存器 SCON
  1. FE用来检测帧错误,这里我们用不到;
  2. SM0 和 SM1 为工作方式选择位:有四种模式,1.4节有介绍,这里我们使用模式1,赋值 01;
  3. SM2 是模式2和模式3使用的,这里不介绍,可以去看单片机手册;
  4. REN 允许/禁止串口接收数据,为 1 允许,为 0 禁止;
  5. TI 发送中断标志位;
  6. RI 接收中断标志位。
  • 电源控制寄存器 PCON:SMOD 波特率倍增位。在串口方式 1、方式 2、方式 3 时,波特率与 SMOD 有关,当 SMOD=1 时,波特率提高一倍。复位时,SMOD=0。

2.串口通信案例

2.1通过串口发送数据到电脑

  • 代码演示
  • Uart.c:
#include <REGX52.H>

void Uart_Init()
{
	// 串口配置
	PCON &= 0x7F; // 将第八位置0,其他位不变
	SCON=0x40; // 0100 0000
	
	// 定时器配置
	TMOD &= 0x0F;		//设置定时器模式
	TMOD |= 0x20;		//设置定时器模式
	TL1 = 0xFA;		//设定定时初值
	TH1 = 0xFA;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}

void Uart_SendByte(unsigned char Byte)
{
	SBUF=Byte;
	while(TI==0);
	TI=0;
}
  • 说明:

    1. 该案例只接收数据,不发送数据,什么模式一通信,因此SCON=0x40
    2. TI:发送中断标志位,在中断服务程序中,必须用软件将其清 0,取消此中断申请,因此这里的函数中加上了TI=0
    3. 这里配置时钟是配置的 Timer1 ,初始化函数可以通过软件生成,但是要设置好对应参数,如图:

    在这里插入图片描述

  • Uart.h:

#ifndef __UART_H__
#define __UART_H__

void Uart_Init();
void Uart_SendByte(unsigned char Byte);

#endif
  • main.c:
#include <REGX52.H>
#include "Delay.h"
#include "Uart.h"

unsigned char sec;

void main()
{
	// 初始化串口
	Uart_Init();
	
	while(1)
	{
		// 通过串口发送数据
		Uart_SendByte(sec);
		Delayxms(1000);
		sec++;
	}
}
  • 说明:其运行的结果是单片机通过串口每秒给电脑发送一个字节的数据,从0开始递增,显示格式位十六进制。

2.2电脑通过串口控制 LED

  • 代码演示
  • Uart.c:
#include <REGX52.H>

void Uart_Init()
{
	// 串口配置
	PCON &= 0x7F; // 将第八位置0,其他位不变
	SCON=0x50; // 0101 0000 允许接收
	
	// 定时器配置
	TMOD &= 0x0F;		//设置定时器模式
	TMOD |= 0x20;		//设置定时器模式
	TL1 = 0xFA;		//设定定时初值
	TH1 = 0xFA;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
	// 使能中断
	EA=1;
	ES=1;
}

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

// 中断函数,用于电脑给单片机发送数据(模板)
/*
void Uart_Routine() interrupt 4
{
	if(RI==1)
	{
		P2=~SBUF;
		Uart_SendByte(SBUF);
		RI=0;
	}
}
*/

  • Uart.h:
#ifndef __UART_H__
#define __UART_H__

void Uart_Init();
void Uart_SendByte(unsigned char Byte);

#endif
  • main:
#include <REGX52.H>
#include "Delay.h"
#include "Uart.h"

unsigned char sec;

void main()
{
	// 初始化串口
	Uart_Init();
	
	while(1)
	{
		
	}
}

void Uart_Routine() interrupt 4
{
	if(RI==1)
	{
		P2=~SBUF;
		Uart_SendByte(SBUF);
		RI=0;
	}
}
  1. 代码演示效果,通过电脑给单片机发送一字节数据,如发送 ff ,单片机 LED 灯全亮,同时单片机会回给电脑相同的数据;
  2. 这里将SCON=0x50设置为允许接收数据,同时相比上一个案例添加了中断使能;
  3. RI:接收中断标志位,在中断服务程序中,必须用软件将其清 0,取消此中断申请,因此这里的中断函数中加上了RI=0
  4. 因为这里的RI 和 TI是或门,不管谁中断标志位置1了都会发送中断请求,因此需要在这里判断到底是谁发出来中断请求;
  5. 中断序号查询下表:

在这里插入图片描述

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

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

相关文章

搭建docker私有化仓库Harbor

Docker私有仓库概述 Docker私有仓库介绍 Docker私有仓库是个人、组织或企业内部用于存储和管理Docker镜像的存储库。Docker默认会有一个公共的仓库Docker Hub,而与Docker Hub不同,私有仓库是受限访问的,只有授权用户才能够上传、下载和管理其中的镜像。这种私有仓库可以部…

【深度学习】核心概念-人工神经网络(Artificial Neural Network, ANN)

人工神经网络是一种受生物神经系统启发的机器学习模型&#xff0c;旨在通过连接大量的节点&#xff08;称为神经元或节点&#xff09;来模拟人脑的学习方式。它是一种在监督学习和非监督学习中广泛应用的深度学习模型。 人工神经网络的基本结构 一个人工神经网络通常由以下三个…

切比雪夫插值

切比雪夫插值是一种基于切比雪夫节点的多项式插值方法&#xff0c;其优势是减少插值误差(特别是龙格现象&#xff1a;表现为高维插值时在边缘处插值误差骤增)。本文对其基本操作进行说明。 1. 切比雪夫节点 切比雪夫插值的核心是使用切比雪夫节点作为插值点。切比雪夫节点是切…

ELK的搭建

ELK elk&#xff1a;elasticsearch logstatsh kibana统一日志收集系统 elasticsearch&#xff1a;分布式的全文索引引擎点非关系型数据库,存储所有的日志信息&#xff0c;主和从&#xff0c;最少需要2台 logstatsh&#xff1a;动态的从各种指定的数据源&#xff0c;获取数据…

【物联网原理与运用】知识点总结(上)

目录 名词解释汇总 第一章 物联网概述 1.1物联网的基本概念及演进 1.2 物联网的内涵 1.3 物联网的特性——泛在性 1.4 物联网的基本特征与属性&#xff08;五大功能域&#xff09; 1.5 物联网的体系结构 1.6 物联网的关键技术 1.7 物联网的应用领域 第二章 感知与识别技术 2.1 …

英文字体:复古八十年代优雅品牌邀请函电影标题设计衬线字体 Eighties Nostalgia Font

嘿&#xff0c;大家好&#xff0c;我希望你们一切顺利&#xff0c;考虑到现在世界上发生的一切&#xff0c;你们在生活的各个方面都取得了进步。过去 3 年对我们所有人来说都是过山车&#xff0c;我一直非常怀念美好的时光。怀旧之情将我带到了 Pinterest&#xff0c;自然而然地…

GPT大模型下,如何实现网络自主防御

近年来&#xff0c;随着GPT大模型的出现&#xff0c;安全领域的攻防对抗变得更加激烈。RSAC2023人工智能安全议题重点探讨了人工智能安全的最新发展&#xff0c;包括人工智能合成器安全、安全机器学习以及如何利用渗透测试和强化学习技术来确保人工智能模型的安全性和可靠性。 …

Spring Framework 5.3.x源码构建 (jdk-1.8, gradle 7.5.1, idea2024.3)

1、下载jdk安装并配置环境变量&#xff08;自行百度&#xff09; https://www.oracle.com/java/technologies/downloads/#java8 2、下载spring-framework源码&#xff0c;切换分支到5.3.x https://github.com/spring-projects/spring-framework.git 备用地址 https://gitco…

韩顺平老师Linux学习笔记【持续更新...】

1、课程内容 1.1、课程大纲 1.2、Linux使用在哪些地方 Linux运维工程师Linux嵌入式工程师Linux下开发项目&#xff1a;JavaEE、大数据、Python、PHP、C/C、Go 1.3、Linux的应用领域 个人桌面领域服务器领域&#xff08;最强领域&#xff09;嵌入式领域 2、Linux入门 2.1、…

代码随想录算法训练营day27

代码随想录算法训练营 —day27 文章目录 代码随想录算法训练营前言一、贪心算法理论基础二、455.分发饼干三、376. 摆动序列53. 最大子数组和总结 前言 今天是算法营的第27天&#xff0c;希望自己能够坚持下来&#xff01; 今日任务&#xff1a; ● 贪心算法理论基础 ● 455.…

浅谈容灾技术方案详解

一、什么是容灾&#xff1f; 容灾指的是&#xff0c;在异地搭建一套或多套和主生产系统一样的IT系统&#xff0c;用于应对在系统因发生意外&#xff08;自然灾害、人为灾害、设备系统故障等&#xff09;造成业务影响的情况&#xff0c;达到尽量让生产业务损失最小的目的。 二…

《框架程序设计》期末复习

目录 Maven 简介 工作机制&#xff08;★&#xff09; 依赖配置&#xff08;★&#xff09; Maven命令 MyBatis 入门 单参数查询&#xff08;★&#xff09; 多参数查询&#xff08;★★★&#xff09; 自定义映射关系&#xff08;★★★&#xff09; 基本增删改查操…

SDK调用文心一言如何接入,文心一言API接入教程

一、前期准备 注册百度智能云账号&#xff1a; 前往百度智能云官网注册一个账号。这是接入文心一言API的基础。 了解API接口&#xff1a; 在百度智能云开放平台中&#xff0c;找到文心一言API的详情页&#xff0c;了解提供的API接口类型&#xff08;如云端API、移动端API、离线…

刚体变换矩阵的逆

刚体运动中的变换矩阵为&#xff1a; 求得变换矩阵的逆矩阵为&#xff1a; opencv应用 cv::Mat R; cv::Mat t;R.t(), -R.t()*t

<style lang=“scss“ scoped>: 这是更常见的写法,也是官方文档中推荐的写法

这两种写法在大多数情况下是没有区别的&#xff0c;它们都是 Vue.js 单文件组件 (.vue 文件) 中用来定义组件私有样式的方式。 两种写法&#xff1a; <style lang"scss" scoped>: 这是更常见的写法&#xff0c;也是官方文档中推荐的写法。<style scoped l…

ai,seo,关键词

什么是AI在SEO中的应用 在当今数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;在搜索引擎优化&#xff08;SEO&#xff09;领域的应用正变得愈发重要。AI技术能够处理和分析大量的数据&#xff0c;通过识别用户行为和搜索模式&#xff0c;帮助优化网站内容和结构。…

git - 用SSH方式迁出远端git库

文章目录 git - 用SSH方式迁出远端git库概述笔记以gitee为例产生RSA密钥对 备注githubEND git - 用SSH方式迁出远端git库 概述 最近一段时间&#xff0c;在网络没问题的情况下&#xff0c;用git方式直接迁出git库总是会失败。 失败都是在远端, 显示RPC错误。 但是git服务器端…

slurm部署安装

slurm部署安装 管理节点和计算节点 在所有节点执行 安装系统工具 apt install -y build-essential curl wget munge将hosts文件 vim /etc/hostsxxx.xxx.xxx.xxx xxx分发到其他计算节点创建slurm用户 useradd -m slurm mkdir /var/spool/slurmd /var/spool/slurmctld chow…

初识Java 2

目录 一.方法&#xff08;函数&#xff09; 1.方法的定义 2.方法的调用过程 3.实参与形参的关系 4.方法的重载 5.方法签名&#xff08;了解&#xff09; 6.递归&#xff08;常用于数列&#xff0c;阶乘&#xff09; 二.数组 1.定义方法&#xff1a; 2.初始化&#xff…

react-quill 富文本组件编写和应用

index.tsx文件 import React, { useRef, useState } from react; import { Modal, Button } from antd; import RichEditor from ./RichEditor;const AnchorTouchHistory: React.FC () > {const editorRef useRef<any>(null);const [isModalVisible, setIsModalVis…