单片机知识总结(完整)

news2024/11/26 6:14:16

在这里插入图片描述

1、单片机概述

1.1. 单片机的定义与分类

定义:
单片机(Microcontroller Unit,简称MCU)是一种将微处理器、存储器(包括程序存储器和数据存储器)、输入/输出接口和其他必要的功能模块集成在单个芯片上的微型计算机。它通常用于控制应用,可以在没有外部支持芯片的情况下独立运行。

分类:

  1. 按处理能力分类:

    • 低端单片机:处理能力较弱,适用于简单的控制应用。
    • 中端单片机:具有一定的处理能力,适用于中等复杂度的控制系统。
    • 高端单片机:处理能力强,适用于复杂的控制系统和计算密集型应用。
  2. 按指令集分类:

    • 复杂指令集单片机(CISC):指令丰富,操作复杂,适用于多种应用场景。
    • 精简指令集单片机(RISC):指令简单,执行速度快,功耗低。
  3. 按位数分类:

    • 4位单片机:处理能力有限,适用于简单的控制任务。
    • 8位单片机:应用最广泛,如8051系列。
    • 16位单片机:处理能力更强,适用于较为复杂的控制系统。
    • 32位单片机:具有更高的处理能力和更多的功能,适用于高端应用。
  4. 按用途分类:

    • 通用型单片机:适用于多种场合。
    • 专用型单片机:针对特定应用设计,如汽车电子、家电控制等。

1.2. 单片机的发展历程

早期阶段(1970年代):

  • 1971年,Intel推出了世界上第一款微处理器4004,随后推出了8008,为单片机的发展奠定了基础。

发展阶段(1980年代):

  • 1981年,Intel推出了8051单片机,成为历史上最成功的单片机之一。
  • 其他公司如Motorola、Zilog、Atmel等也相继推出了自己的单片机产品。

成熟阶段(1990年代):

  • 单片机的性能不断提升,应用领域不断扩展。
  • 出现了基于Flash存储技术的单片机,使得程序更新更加方便。

多元化发展阶段(2000年代至今):

  • 单片机开始集成更多的功能,如USB、网络、CAN总线等。
  • 32位单片机逐渐成为市场的主流。
  • 出现了基于ARM架构的嵌入式处理器,进一步推动了单片机技术的发展。

1.3. 单片机的应用领域

  1. 消费电子:

    • 家用电器(如洗衣机、空调、电视)
    • 音响设备
    • 游戏机
  2. 工业控制:

    • 自动化生产线
    • 机器人控制
    • 电力系统监控
  3. 汽车电子:

    • 发动机控制单元(ECU)
    • 车身电子控制
    • 车载娱乐系统
  4. 医疗设备:

    • 监护仪器
    • 医疗诊断设备
    • 智能假肢
  5. 通信设备:

    • 路由器
    • 交换机
    • 无线通信模块
  6. 物联网(IoT):

    • 智能家居
    • 智能城市
    • 工业互联网
  7. 其他:

    • 安全监控
    • 环境监测
    • 仪器仪表

2、单片机硬件基础

2.1. 单片机的内部结构

在这里插入图片描述
内部结构图

单片机的内部结构通常包括以下几个主要部分:

  1. 中央处理器(CPU): 执行程序指令,进行算术和逻辑运算。
  2. 程序存储器(ROM): 存储程序代码。
  3. 数据存储器(RAM): 存储运行时的数据和变量。
  4. 特殊功能寄存器(SFR): 控制和状态寄存器,用于特定功能的配置和状态反馈。
  5. 输入/输出端口(I/O): 与外部设备进行数据交换。
  6. 定时器/计数器: 用于定时或计数功能。
  7. 中断控制器: 处理中断请求,实现多任务处理。
  8. 串行通信接口: 实现与其他设备或单片机的串行通信。

2.2. 单片机的引脚功能

在这里插入图片描述

以8051单片机为例,它通常有40个引脚,以下是部分引脚的功能:

  • VCC: 电源正极。
  • GND: 电源负极。
  • P0.0 - P0.7: 端口0,可以作为通用I/O口,也可以作为地址/数据总线。
  • P1.0 - P1.7: 端口1,通用I/O口。
  • P2.0 - P2.7: 端口2,通用I/O口,也可用于外部存储器地址线。
  • P3.0 - P3.7: 端口3,通用I/O口,部分引脚具有第二功能,如P3.0和P3.1用于串行通信。
  • RST: 复位引脚,高电平有效。
  • ALE/PROG: 地址锁存使能/程序存储器编程。
  • PSEN: 程序存储器选通信号。
  • EA/VPP: 外部访问使能/编程电压。

2.3. 单片机的时钟与复位

  • 时钟: 单片机的时钟用于提供CPU操作的基本时间节拍。8051单片机通常需要一个外部晶振或陶瓷振荡器来提供时钟信号。
  • 复位: 当RST引脚接收到高电平时,单片机会执行复位操作,将CPU和寄存器恢复到初始状态。

2.4. 单片机的存储器结构

在这里插入图片描述

2.4.1 程序存储器(ROM)

程序存储器用于存储单片机的程序代码。在8051单片机中,程序存储器通常是只读存储器(ROM)或闪存(Flash)。汇编代码将被存储在程序存储器的特定地址中。

assembly ORG 0000H ;	//程序起始地址 MOV A, 
55H ;	 //将55H加载到累加器A 

2.4.2 数据存储器(RAM)

数据存储器用于存储程序运行时的数据和变量。在8051单片机中,数据存储器是随机存取存储器(RAM)。

char data_var = 0xAA; // 定义一个字符变量并初始化为0xAA

data_var变量将被存储在数据存储器中的一个地址。

2.4.3 特殊功能寄存器(SFR)

特殊功能寄存器是CPU内部的一些寄存器,它们具有特定的功能,如控制I/O端口、定时器、串行通信等。P1是一个特殊功能寄存器,用于控制端口1的状态。

SFR P1 = 0x90; // 定义P1端口的地址
P1 = 0xFF; // 将P1端口的所有引脚设置为高电平

3. 汇编语言

(1)指令系统

汇编语言的指令系统是指单片机可以理解和执行的指令集合。每个指令对应一个特定的操作,如数据传送、算术运算、逻辑运算、跳转等。以下是一些常见的8051单片机汇编指令:

  • 数据传送指令: MOV A, #data(将立即数data传送到累加器A)
  • 算术运算指令: ADD A, Rn(将寄存器Rn的内容加到累加器A,结果存储在A中)
  • 逻辑运算指令: ANL A, #data(将累加器A的内容与立即数data进行逻辑与运算)
  • 跳转指令: JMP label(无条件跳转到label标签处执行)

(2)汇编程序结构

  • 起始地址: 指定程序开始执行的地址。
  • 数据定义: 定义程序中使用的变量和数据。
  • 代码段: 包含实际的指令代码。
  • 子程序: 可被主程序调用的代码块。
  • 中断服务程序: 处理中断事件的代码。
  assembly
ORG 0000H ; 程序起始地址
START: MOV A, #55H ; 将立即数55H传送到累加器A
       ADD A, R0 ; 将寄存器R0的内容加到累加器A
       MOV P1, A ; 将累加器A的内容输出到端口P1
       SJMP START ; 无条件跳转到START标签处继续执行
 

(3) 汇编语言编程实例

例子1: 将P1端口的值翻转到P2端口

assembly
ORG 0000H
START: MOV A, P1 ; 将P1端口的值读取到累加器A
       CPL A ; 将累加器A的内容取反
       MOV P2, A ; 将取反后的值输出到P2端口
       SJMP START ; 无限循环

3.1C语言基础

C语言的基础概念:

  • 变量: 用于存储数据的标识符。
  • 数据类型: 定义变量可以存储的数据种类,如int、char、float等。
  • 控制结构: 如if、for、while等,用于控制程序流程。

3.2 C语言编程实例

例子1: 将P1端口的值翻转到P2端口

#include <reg51.h> // 包含8051寄存器定义的头文件

void main() {
    while (1) { // 无限循环
        P2 = ~P1; // 将P1端口的值取反后输出到P2端口
    }
}
 

reg51.h头文件包含了8051单片机的特殊功能寄存器定义,P1P2是特殊功能寄存器,分别代表端口1和端口2。程序中的while循环会不断执行,将P1端口的值取反后输出到P2端口。

4、单片机I/O接口

在这里插入图片描述

4.1、I/O口的结构与功能

I/O口(输入/输出端口)是单片机与外部设备进行数据交换的接口。在8051单片机中,通常有P0、P1、P2、P3四个8位并行I/O端口。

  1. 结构:

    • 锁存器: 用于存储数据输出。
    • 缓冲器: 用于数据输入。
    • 驱动器: 提供足够的电流来驱动外部设备。
  2. 功能:

    • 输入模式: 可以读取外部设备的状态(如按键、传感器等)。
    • 输出模式: 可以控制外部设备(如LED、继电器等)。

4.2、I/O口的编程方法

  1. 设置I/O口为输入模式:

    • 对于P0、P1、P2、P3端口,可以通过设置相应的数据(定义)方向寄存器(如P1DIR)来控制每个位是输入还是输出。
  2. 设置I/O口为输出模式:

    • 同样,通过设置数据方向寄存器来控制端口的方向。
  3. 读取输入:

    • 直接读取I/O口寄存器即可。
  4. 写入输出:

    • 直接向I/O口寄存器入数据即可。

4.3、I/O口的应用实例

例子1: 控制一个连接在P1.0的LED亮灭( LED控制)

#include <reg51.h>

void delay(unsigned int ms) {
    unsigned int i, j;
    for (i = 0; i < ms; i++)
        for (j = 0; j < 123; j++); // 简单的延时函数
}

void main() {
    P1 = 0xFF; // 初始化P1口,所有LED熄灭
    while (1) {
        P1_0 = 0; // 点亮LED
        delay(1000); // 延时
        P1_0 = 1; // 熄灭LED
        delay(1000); // 延时
    }
}

例子2: 检测连接在P1.0的按键是否被按下(按键检测)

#include <reg51.h>

void delay(unsigned int ms) {
    unsigned int i, j;
    for (i = 0; i < ms; i++)
        for (j = 0; j < 123; j++);
}

void main() {
    P1 = 0xFF; // 将P1口设置为输入模式,并启用内部上拉电阻
    while (1) {
        if (P1_0 == 0) { // 如果P1.0为低电平,表示按键被按下
            delay(20); // 延时消抖
            if (P1_0 == 0) { // 再次检测,确保按键确实被按下
                while (P1_0 == 0); // 等待按键释放
                P1_1 = ~P1_1; // 切换P1.1连接的LED状态
            }
        }
    }
}
 

例子3: 控制一个连接在P1.0的继电器开关(继电器控制)

#include <reg51.h>

void delay(unsigned int ms) {
    unsigned int i, j;
    for (i = 0; i < ms; i++)
        for (j = 0; j < 123; j++);
}

void main() {
    P1 = 0xFF; // 初始化P1口,所有继电器断开
    while (1) {
        P1_0 = 0; // 继电器闭合
        delay(5000); // 延时
        P1_0 = 1; // 继电器断开
        delay(5000); // 延时
    }
}
 
``

`

5、单片机定时器/计数器

5.1、定时器/计数器的工作原理

定时器/计数器是单片机内部的一个重要模块,它可以用于计时或者计数。在8051单片机中,通常有两个定时器/计数器:定时器/计数器0和定时器/计数器1。

5.1.1 工作原理:

  • 定时器模式: 当定时器/计数器被配置为定时器模式时,它会对单片机的内部时钟信号进行计数。当计数达到设定值时,定时器溢出,可以触发中断或改变I/O端口的状态。
  • 计数器模式: 当定时器/计数器被配置为计数器模式时,它会对外部信号(通常是T0或T1引脚上的脉冲)进行计数。

5.2、定时器/计数器的编程方法

初始化定时器/计数器:

  • 设置定时器/计数器模式。
  • 设置定时器/计数器的初值。
  • 启用或禁用定时器/计数器。
  • 配置中断(如果需要)。

5.3、定时器/计数器的应用实例

例子1: 使用定时器0实现1秒的延时(延时)

#include <reg51.h>

void Timer0_Init() {
    TMOD &= 0xF0; // 清除定时器0模式位
    TMOD |= 0x01; // 设置定时器0为模式1(16位定时器模式)
    TH0 = 0xFC;   // 设置定时器初值(1秒延时,具体值取决于晶振频率)
    TL0 = 0x18;
    ET0 = 1;      // 启用定时器0中断
    EA = 1;       // 启用全局中断
    TR0 = 1;      // 启动定时器0
}

void Timer0_ISR() interrupt 1 {
    TH0 = 0xFC;   // 重新加载定时器初值
    TL0 = 0x18;
    // 这里可以执行需要延时的代码
}

void main() {
    Timer0_Init();
    while (1) {
        // 主循环代码
    }
}

例子2: 使用定时器1对外部脉冲进行计数(脉冲计数)

#include <reg51.h>

void Timer1_Init() {
    TMOD &= 0x0F; // 清除定时器1模式位
    TMOD |= 0x10; // 设置定时器1为模式1(16位计数器模式)
    ET1 = 1;      // 启用定时器1中断
    EA = 1;       // 启用全局中断
    TR1 = 1;      // 启动定时器1
}

void Timer1_ISR() interrupt 3 {
    // 这里可以读取TL1和TH1的值,以获取脉冲计数
    // 注意:在中断服务程序中,通常不进行复杂操作
}

void main() {
    Timer1_Init();
    while (1) {
        // 主循环代码
    }
}
 

例子3: 使用定时器0产生PWM信号(PWM输出)

#include <reg51.h>

void Timer0_Init() {
    TMOD &= 0xF0; // 清除定时器0模式位
    TMOD |= 0x02; // 设置定时器0为模式2(8位自动重装载模式)
    TH0 = 0xFF;   // 设置PWM周期(具体值取决于PWM频率)
    TL0 = TH0;    // 初始化TL0
    ET0 = 1;      // 启用定时器0中断
    EA = 1;       // 启用全局中断
    TR0 = 1;      // 启动定时器0
}

void Timer0_ISR() interrupt 1 {
    static unsigned char pwm_width = 0; // PWM占空比变量
    if (TF0) { // 检查定时器是否溢出
        TR0 = 0; // 停止定时器
        TH0 = 0xFF; // 重新加载PWM周期
        TL0 = TH0;
        P1_1 = 1; // 开始PWM周期
        TR0 = 1; // 重新启动定时器
    } else if (TL0 == pwm_width) {
        P1_1 = 0; // 设置PWM占空比
    }
}

void main() {
    Timer0_Init();

6、单片机中断系统

6.1中断系统的组成

  1. 中断源:中断源是指能够触发中断的事件或信号。中断源可以是硬件事件(如定时器溢出、外部引脚变化)或软件事件(如软件中断指令)。

  2. 中断控制器:中断控制器负责管理中断请求,确定中断的优先级,以及选择哪个中断服务程序(ISR)来响应。

  3. 中断向量表:中断向量表是一个存储中断服务程序入口地址的表格。当中断发生时,CPU通过中断向量表找到对应的中断服务程序。

  4. 中断服务程序(ISR):中断服务程序是一段用于处理特定中断事件的代码。当中断被触发时,CPU会暂停当前任务,跳转到ISR执行。

6.2中断处理流程

  1. 中断请求:中断源发出中断请求信号。

  2. 中断识别:中断控制器识别中断请求,并判断其优先级。

  3. 中断响应:如果中断被允许,CPU会暂停当前任务,保存当前程序状态(如程序计数器、寄存器等),然后跳转到对应的中断服务程序。

  4. 执行中断服务程序:CPU执行中断服务程序来处理中断事件。

  5. 恢复执行:中断服务程序执行完毕后,CPU恢复之前保存的程序状态,并返回到中断发生前的位置继续执行。

6.3中断优先级和嵌套

中断系统通常支持中断优先级,以决定多个中断同时发生时哪个中断将被首先处理。中断嵌套是指一个中断服务程序在执行时可以被另一个更高优先级的中断打断。

6.4程实践

#include <reg51.h>

// 外部中断0服务程序
void External0_ISR(void) interrupt 0 {
    // 执行外部中断0的处理代码
}

// 定时器0中断服务程序
void Timer0_ISR(void) interrupt 1 {
    // 执行定时器0的处理代码
}

void main() {
    EA = 1;   // 全局中断使能
    EX0 = 1;  // 外部中断0使能
    ET0 = 1;  // 定时器0中断使能

    // 其他初始化代码...

    while(1) {
        // 主循环代码
    }
}
 

7、单片机串行通信

单片机的串口通信是一种常用的数据传输方式,它允许单片机与其他设备(如计算机、传感器、其他单片机等)进行数据交换。

串口通信的基本概念

串口通信(Serial Communication)是一种按照位序列进行数据传输的方式,通常使用串行通信接口

串口通信的主要参数

  1. 波特率(Baud Rate):表示每秒钟传送的位数,单位是bps(bits per second)。

  2. 数据位(Data Bits):表示每个数据帧中数据位的数量,通常为7或8位。

  3. 停止位(Stop Bits):表示每个数据帧结束时的停止位的数量,通常为1、1.5或2位。

  4. 校验位(Parity Bit):用于错误检测的位,可以是奇校验、偶校验或无校验。

  5. 流控制(Flow Control):用于防止数据丢失的技术,如硬件流控制(RTS/CTS)或软件流控制(XON/XOFF)。

串口通信的硬件接口

  • RX(接收):用于接收数据。
  • TX(发送):用于发送数据。
  • GND(地):用于信号参考点。

单片机串口通信的步骤

  1. 初始化串口:设置波特率、数据位、停止位、校验位等参数。

  2. 配置中断(可选):如果使用中断方式进行数据接收和发送,需要配置相关的中断服务程序。

  3. 数据发送:编写代码将数据写入串口发送缓冲区。

  4. 数据接收:编写代码从串口接收缓冲区读取数据。

示例1:8051单片机串口通信

#include <reg51.h>


```c

```c

```bash

```bash
// 假设使用11.0592MHz的晶振

void Serial_Init() {
    SCON = 0x50;  // 设置为模式1,8位数据,可变波特率
    TMOD |= 0x20; // 定时器1使用模式2(自动重装载)
    TH1 = 0xFD;   // 设置波特率为9600
    TL1 = 0xFD;   // 与TH1相同
    TR1 = 1;      // 启动定时器1
    TI = 1;       // 设置TI位,准备发送
}

void Serial_SendByte(unsigned char dat) {
    SBUF = dat;   // 将数据放入发送缓冲区
    while (!TI);  // 等待发送完成
    TI = 0;       // 清除发送完成标志
}

void main() {
    Serial_Init(); // 初始化串口
    while (1) {
        Serial_SendByte('A'); // 发送字符'A'
        // 可以添加延时,控制发送速度
    }
}
 

首先初始化串口,然后在一个无限循环中发送字符’A’。Serial_Init函数设置了串口的工作模式和波特率,而Serial_SendByte函数负责发送一个字节的数据。

8、单片机外围设备扩展

单片机连接到各种外围设备的详细插图
在这里插入图片描述

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

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

相关文章

代码管理之Gitlab

文章目录 Git基础概述场景本地修改未提交&#xff0c;拉取远程代码修改提交本地&#xff0c;远程已有新提交 GitIDEA引入Git拉取仓库代码最后位置 Git基础 概述 workspace 工作区&#xff1a;本地电脑上看到的目录&#xff1b; repository 本地仓库&#xff1a;就是工作区中隐…

基于Java Springboot古风生活体验交流网站

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

智慧社区管理系统平台提升物业运营效率与用户体验

内容概要 智慧社区管理系统平台是一个集成了多项功能的综合性解决方案&#xff0c;旨在通过先进的技术手段提升物业管理的效率和居民的生活质量。该平台不仅关注物业运营的各个方面&#xff0c;还强调用户体验的重要性。随着科技的发展&#xff0c;社区管理方式正发生着翻天覆…

Docker--通过Docker容器创建一个Web服务器

Web服务器 Web服务器&#xff0c;一般指网站服务器&#xff0c;是驻留于因特网上某种类型计算机的程序。 Web服务器可以向浏览器等Web客户端提供文档&#xff0c;也可以放置网站文件以供全世界浏览&#xff0c;或放置数据文件以供全世界下载。 Web服务器的主要功能是提供网上…

健身房小程序服务渠道开展

健身不单单是锻炼身体、保持身材&#xff0c;也是一种社交方式&#xff0c;城市里门店不少&#xff0c;每家都有一定流量和老客&#xff0c;但仅靠传统线下拉客/自然流量前往和线上朋友圈、短视频发硬广等方式还不够。 商家需要找到更多潜在目标客户&#xff0c;而消费者也对门…

利用Java爬虫获得1688商品分类:技术解析与代码示例

在电商领域&#xff0c;了解商品分类对于市场分析和产品策略至关重要。1688作为中国领先的B2B电商平台&#xff0c;其商品分类数据对于商家来说具有极高的价值。本文将详细介绍如何使用Java编写爬虫程序&#xff0c;以合法合规的方式获取1688商品分类信息&#xff0c;并提供代码…

QT:QListView实现table自定义代理

介绍 QListVIew有两种切换形式&#xff0c;QListView::IconMode和QListView::ListMode&#xff0c;通过setViewMode()进行设置切换。因为QListView可以像QTreeView一样显示树形结构&#xff0c;也可以分成多列。这次目标是将ListView的ListMode形态显示为table。使用代理&…

YOLOv10改进,YOLOv10添加SE注意力机制,二次C2f结构

摘要 理论介绍 SE 注意力机制是一种提升卷积神经网络(CNN)性能的模块,SE更关注重要的特征图,增强了网络的表现,同时仅增加了较少的参数。SE 机制包含两个主要步骤: Squeeze (压缩):对所有特征图进行全局平均池化,生成一个通道描述符。Excitation (激励):将通道描述符…

详解Servlet的使用

目录 Servlet 定义 动态页面 vs 静态页面 主要功能 Servlet的使用 创建Maven项目 引入依赖 创建目录 编写代码 打war包 部署程序 验证程序 Smart Tomcat 安装Smart Tomcat 配置Smart Tomcat插件 启动Tomcat 访问页面 路径对应关系 Servlet运行原理 Tomcat的…

【Nginx从入门到精通】05-安装部署-虚拟机不能上网简单排错

文章目录 总结1、排查步骤 一、排查&#xff1a;Vmware网关二、排查&#xff1a;ipStage 1 &#xff1a;ping 127.0.0.1Stage 2 &#xff1a;ping 宿主机ipStage 3 &#xff1a;ping 网关 失败原因解决方案Stage 4 &#xff1a;ping qq.com 总结 1、排查步骤 Vmware中网关是否…

优化求解 | 非线性最小二乘优化器Ceres安装教程与应用案例

目录 0 专栏介绍1 Ceres库介绍2 Ceres库安装3 Ceres库概念3.1 构建最小二乘问题3.1.1 残差块3.1.2 代价函数 3.2 求解最小二乘问题 4 Ceres库案例4.1 Powell函数优化4.2 非线性曲线拟合 0 专栏介绍 &#x1f525;课设、毕设、创新竞赛必备&#xff01;&#x1f525;本专栏涉及…

Flink Transformation-转换算子

map算子的使用 假如有如下数据&#xff1a; 86.149.9.216 10001 17/05/2015:10:05:30 GET /presentations/logstash-monitorama-2013/images/github-contributions.png 83.149.9.216 10002 17/05/2015:10:06:53 GET /presentations/logstash-monitorama-2013/css/print/paper…

记录一些PostgreSQL操作

本文分享一些pg操作 查看版本 select version(); PostgreSQL 11.11 查看安装的插件 select * from pg_available_extensions; 查看分词效果 select ‘我爱北京天安门,天安门上太阳升’::tsvector; ‘天安门上太阳升’:2 ‘我爱北京天安门’:1select to_tsvector(‘我爱北京天…

【ubuntu】数学人的环境搭建

Python 语言环境 python 的 pip 第三方库管理 sudo apt install python3-pippython 的 idle 界面 sudo apt install idle3R 语言环境 sudo apt install r-cran-zoo### RStudio 界面 ubuntu sudo snap install rstudio --classicJulia 语言环境 sudo snap install julia --…

android 11添加切换分屏功能

引言 自Android 7开始官方就支持分屏显示,但没有切换分屏的功能,即交换上下屏幕。直到Android 13开始才支持切换分屏,操作方式是:分屏模式下双击中间分割线就会交换上下屏位置。本文的目的就是在Android 11上实现切换分屏的功能。 下图是Android13切换分屏演示 切换分屏…

数据结构——排序算法第一幕(插入排序:直接插入排序、希尔排序 选择排序:直接选择排序,堆排序)超详细!!!!

文章目录 前言一、排序1.1 概念1.2 常见的排序算法 二、插入排序2.1 直接插入排序2.2 希尔排序希尔排序的时间复杂度 三、选择排序3.1 直接选择排序3.2 堆排序 总结 前言 时间很快&#xff0c;转眼间已经到数据结构的排序算法部分啦 今天我们来学习排序算法当中的 插入排序 和 …

C++网络编程之多播

概述 在移动互联网时代&#xff0c;随着多媒体应用的日益普及&#xff0c;如何高效地将数据传输给多个接收者成为了网络通信领域的一个重要课题。多播&#xff08;英文为Multicast&#xff09;作为一种高效的网络通信方式&#xff0c;可以将数据同时发送到多个接收者&#xff0…

AWS的流日志

文章目录 一、aws如何观察vpc的日志&#xff1f;二、aws观测其vpc的入口日志三、 具体配置3.1、配置你的存储神器 S33.2、建立子网的流日志 一、aws如何观察vpc的日志&#xff1f; 排查问题的时候除了去抓包看具体的端口信息的时候&#xff0c;还可以根据其所在的vpc的子网信息…

C++ —— 以真我之名 如飞花般绚丽 - 智能指针

目录 1. RAII和智能指针的设计思路 2. C标准库智能指针的使用 2.1 auto_ptr 2.2 unique_ptr 2.3 简单模拟实现auto_ptr和unique_ptr的核心功能 2.4 shared_ptr 2.4.1 make_shared 2.5 weak_ptr 2.6 shared_ptr的缺陷&#xff1a;循环引用问题 3. shared_ptr 和 unique_…

DAMODEL丹摩|《ChatGLM-6B 在丹摩智算平台的部署与使用指南》

目录 一、引言 二、ChatGLM-6B 模型简介 ChatGLM-6B 的特点 三、DAMODEL 平台部署 ChatGLM-6B 1. 实例创建 2. 模型准备 3. 模型启动 四、通过 Web API 实现本地使用 1. 启动服务 2. 开放端口 3. 使用 PostMan 测试功能 4. 本地代码使用功能 五、总结 一、引言 Ch…