IIC通信总线

news2024/11/30 10:56:23

文章目录

    • 1. IIC总线协议
      • 1. IIC简介
      • 2. IIC时序
        • 1. 数据有效性
        • 2. 起始信号和终止信号
        • 3. 数据格式
        • 4. 应答和非应答信号
        • 5. 时钟同步
        • 6. 写数据和读数据
    • 2. AT24C02
    • 3. AT24C02读写时序
    • 4. AT24C02配置步骤
    • 5. 代码部分
        • 1. IIC基本信号
        • 2. AT24C02驱动代码
        • 3. 实验结果分析

1. IIC总线协议

1. IIC简介

  • 简介:

    IIC(Inter-Integrated Circuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器以及其外围设备。它是由数据线SDA时钟线SCL构成的串行总线,可发送和接收数据,在CPU与被控IC之间、IC与IC之间进行双向传送。

  • 特点:

    1. 总线由数据线 SDA时钟线 SCL 构成的串行总线,数据线用来传输数据,时钟线用来同步数据收发;
    2. 总线上每一个器件都有一个唯一的地址识别,所以我们只需要知道器件的地址,根据时序就可以实现微控制器与器件之间的通信;
    3. 数据线 SDA 和时钟线 SCL 都是双向线路,都通过一个电流源或上拉电阻连接到正的电压,所以当总线空闲的时候,这两条线路都是高电平
    4. 总线上数据的传输速率在标准模式下可达 100kbit/s 在快速模式下可达 400kbit/s 在高速模式下可达 3.4Mbit/s;
    5. 总线支持设备连接。在使用 IIC 通信总线时,可以有多个具备 IIC 通信能力的设备挂载在上面,同时支持多个主机和多个从机,连接到总线的接口数量只由总线电容 400pF 的限制决定。
  • 总线挂载器件示意图:
    在这里插入图片描述

  • IIC通信的优缺点:

    优点 (Advantages)缺点 (Disadvantages)
    简化的连线:仅需两根线(SDA 和 SCL)速度较慢:最高速率为 3.4 Mbps
    多主多从架构:支持多个主设备和从设备协议复杂性:处理起始位、停止位、应答信号等
    灵活的速度选择:支持多种速度模式功耗较高:使用开漏驱动方式需上拉电阻
    芯片地址分配:每个从设备有唯一地址有限的从设备数量:地址有数量限制
    内置握手和校验机制:提高通信可靠性信号完整性问题:高速模式下可能影响通信
  • 硬件IIC与软件IIC对比:

    IIC用法速度稳定性管脚
    硬件IIC比较复杂较稳定需使用特定管脚
    软件IIC操作过程比较清晰较慢稳定任意管脚,比较灵活

2. IIC时序

1. 数据有效性

SDA 线上的数据在时钟的高电平期间必须保持稳定。只有当 SCL 线上的时钟信号为低电平时,数据线的高电平或低电平状态才会改变。每传输一个数据位都会产生一个时钟脉冲。
在这里插入图片描述

2. 起始信号和终止信号

在这里插入图片描述

3. 数据格式

在这里插入图片描述

SDA线上的每个字节长度必须为8位,每次可以传输的字节数不受限制。每个字节后面必须有一个确认位。数据传输时,首先传输最高有效位。如果从设备在执行其他功能(例如处理内部中断)之前无法接收或传输另一个完整的数据字节,则可以将时钟线SCL保持在低位以强制主设备进入等待状态。当从设备准备好接收另一个数据字节并释放时钟线SCL时,数据传输将继续。

4. 应答和非应答信号

每个字节后都会应答。应答位允许从机主机发出应答信号,表示已成功接收该字节并且可以发送另一个字节。主机生成所有时钟脉冲,包括应答的第九个时钟脉冲。

检测应答信号:
在这里插入图片描述

应答信号定义如下:主机在应答时钟脉冲期间释放 SDA 线,以便从机可以将 SDA 线拉低,并且在此时钟脉冲的高电平期间保持稳定的低电平。还必须考虑设置和保持时间。
在这里插入图片描述

非应答信号定义如下:当 SDA 在第九个时钟脉冲期间保持高电平时,这被定义为未确认信号。然后,主机可以生成 STOP 条件以中止传输,或生成重复的 START 条件以开始新的传输。
在这里插入图片描述

有五种情况会导致生成 NACK:

  1. 总线上没有传输地址的从机,因此没有设备可以做出确认信号;
  2. 从机无法接收或发送,因为它正在执行某些实时功能并且尚未准备好开始与主设备通信;
  3. 在传输过程中,从机收到其无法理解的数据或命令;
  4. 在传输期间,从机无法再接收任何数据字节;
  5. 主机必须向从机发送传输结束信号。
5. 时钟同步

两个主设备可以同时在空闲总线上开始传输,并且必须有一种方法来决定由哪个主设备控制总线并完成传输。这是通过时钟同步和仲裁来实现的。在单主系统中,不需要时钟同步和仲裁。
在这里插入图片描述

6. 写数据和读数据

写操作:
在这里插入图片描述

主机首先在IIC总线上发送起始信号,此时总线上的从机都会等待接收由主机发送的数据。主机接下来发送从机地址+0(写操作)组成的8位数据,所有从机接收该8位数据后,自行检验是否是自己的设备地址,如果是,就会发出应答信号。主机在总线上接收到应答信号后,才能继续向从机发送数据。

读操作:
在这里插入图片描述

主机向从机读取数据的操作,主机发出起始信号,接着发送从机地址+1(读操作)组成的8位数据,从机接收到数据验证是否是自身的地址。验证成功后从机会发出应答信号, 并向主机返回8位数据,发送完之后主机就会等待主机的应答信号。如果主机一直返回应答信号,那么从机可以一直发送数据,直到主机发出非应答信号,从机才会停止发送信号。

发送1字节数据:
在这里插入图片描述

读取1字节数据:
在这里插入图片描述

2. AT24C02

在这里插入图片描述

引脚定义:

WP:写保护引脚,接高电平只读,接低电平读和写,默认接低电平。

A0/1/2:可编程地址部分,由8位组成,最后一位是读写操作,0是读操作,1是写操作。

​ 写操作地址:0xA0; 读操作地址:0xA1.

3. AT24C02读写时序

写字节时序:
在这里插入图片描述

主机在 IIC 总线发送第 1 个字节的数据为 24C02的设备地址 0xA0,用于寻找总线上找到 24C02,在获得 24C02 的应答信号之后,继续发送第2 个字节数据,该字节数据是 24C02 的内存地址,再等到 24C02 的应答信号,主机继续发送第 3 字节数据,这里的数据即是写入在第 2 字节内存地址的数据。主机完成写操作后,可以发出停止信号,终止数据传输。

连续写时序:
在这里插入图片描述

在单字节写时序时,每次写入数据时都需要先写入设备的内存地址才能实现,在页写时序 中,只需要告诉24C02 第一个内存地址 1,后面数据会按照顺序写入到内存地址 2,内存地址 3等,大大节省了通信时间,提高了时效性。因为 24C02 每次只能 8bit 数据,所以它的页大小也就是 1 字节。

读字节时序:
在这里插入图片描述

24C02读取数据的过程是一个复合的时序,其中包含写时序和读时序。先看第一个通信过程,这里是写时序,起始信号产生后,主机发送24C02设备地址0xA0,获取从机应答信号后,接着发送需要读取的内存地址;在读时序中,起始信号产生后,主机发送24C02设备地址0xA1,获取从机应答信号后,接着从机返回刚刚在写时序中内存地址的数据,以字节为单位传输在总线上,假如主机获取数据后返回的是应答信号,那么从机会一直传输数据,当主机发出的是非应答信号并以停止信号发出为结束,从机就会结束传输。

4. AT24C02配置步骤

  1. 使能SCL和SDA对应时钟

    __HAL_RCC_GPIOB_CLK_ENABLE()
    
  2. 设置GPIO工作模式

    HAL_GPIO_Init()
    
  3. 编写基本信号

    void iic_init(void);
    static void iic_delay(void);
    void iic_start(void);
    void iic_stop(void);
    uint8_t iic_wait_ack(void);
    void iic_ack(void);
    void iic_nack(void);
    void iic_send_byte(uint8_t data);
    uint8_t iic_read_byte(uint8_t ack);
    
  4. 编写读和写函数

    void at24c02_write_one_byte(uint8_t addr, uint8_t data);
    uint8_t at24c02_read_one_byte(uint8_t addr);
    

5. 代码部分

1. IIC基本信号
  • 软件模拟IIC使用的引脚:

    #define IIC_SCL(x) do{ x ? \
                       HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET) : \
                       HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); \
                       }while(0)       /* SCL */
    
    #define IIC_SDA(x) do{ x ? \
                       HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET) : \
                       AL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET); \
                       }while(0)       /* SDA */
    
    #define IIC_READ_SDA  HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) /* 读取SDA */
    
  • 延时函数:

    static void iic_delay(void)
    {
        delay_us(2);
    }
    

    iic_delay函数中使用2微秒延迟对于确保I²C通信的正确时序和信号稳定性至关重要。这种延迟有助于满足I²C的标准和快速模式的时序要求,适应微控制器的速度,并确保在总线的电气特性下信号转换的稳定性。选择的延迟时间平衡了及时通信和信号转换稳定性的需求。

  • 起始信号:

    void iic_start(void)
    {
        IIC_SDA(1);    // 确保SDA线为高电平
        IIC_SCL(1);    // 确保SCL线为高电平
        iic_delay();   // 短暂延迟
        IIC_SDA(0);    // 将SDA线拉低,生成起始条件
        iic_delay();   // 短暂延迟
        IIC_SCL(0);    // 将SCL线拉低,准备进行数据传输
        iic_delay();   // 短暂延迟
    }
    
    1. 确保总线空闲状态

      • IIC_SDA(1);:将SDA线设置为高电平。
      • IIC_SCL(1);:将SCL线设置为高电平。
      • 在I²C协议中,空闲状态是SDA和SCL都为高电平。
    2. 生成起始信号

      • IIC_SDA(0);:将SDA线从高电平拉低,在SCL高电平期间,这是I²C的起始条件。
      • 这个信号告诉所有从设备,主设备即将开始通信。
    3. 准备数据传输

      • IIC_SCL(0);:将SCL线拉低,表示开始数据传输。
  • 终止信号:

    void iic_stop(void)
    {
        IIC_SDA(0);    // 确保SDA线为低电平
        iic_delay();   // 短暂延迟
        IIC_SCL(1);    // 将SCL线拉高
        iic_delay();   // 短暂延迟
        IIC_SDA(1);    // 将SDA线拉高,生成停止条件
        iic_delay();   // 短暂延迟
    }
    
    1. 准备停止信号

      • IIC_SDA(0);:将SDA线设置为低电平。
    2. 生成停止信号

      • IIC_SCL(1);:将SCL线拉高,准备生成停止条件。
      • IIC_SDA(1);:将SDA线从低电平拉高,在SCL高电平期间,这是I²C的停止条件(Stop Condition)。
      • 这个信号通知所有从设备,主设备已经结束通信,释放总线。
  • 等待应答信号:

    uint8_t iic_wait_ack(void)
    {
        IIC_SDA(1);   // 主机释放SDA线(将SDA线设置为高电平,准备接收从机的ACK信号)
        iic_delay();  // 短暂延迟,等待信号稳定
        IIC_SCL(1);   // 主机拉高SCL线,准备读取SDA线的状态
        iic_delay();  // 短暂延迟,等待信号稳定
    
        if(IIC_READ_SDA)  // 在SCL高电平时读取SDA线的状态
        {
            iic_stop();   // 如果SDA线为高电平,表示从机未发送ACK信号,执行停止条件
            return 1;     // 返回1表示未接收到ACK信号
        }
        IIC_SCL(0);   // 主机拉低SCL线
        iic_delay();  // 短暂延迟
    
        return 0;     // 返回0表示成功接收到ACK信号
    }
    
    1. 释放SDA线

      • IIC_SDA(1);:主机将SDA线设置为高电平,准备接收从机的ACK信号。
    2. 短暂延迟

      • iic_delay();:等待一段时间,以确保信号稳定。
    3. 拉高SCL线

      • IIC_SCL(1);:主机拉高SCL线,使数据稳定在SDA线上,并准备读取SDA线的状态。
    4. 读取SDA线的状态

      • if(IIC_READ_SDA):在SCL高电平时读取SDA线的状态。如果SDA线为高电平,表示从机未发送ACK信号(从机没有将SDA线拉低)。
    5. 停止条件

      • iic_stop();:如果未接收到ACK信号(SDA线为高电平),主机生成停止条件终止通信。
    6. 返回值

      • return 1;:返回1表示未接收到ACK信号。
      • return 0;:返回0表示成功接收到ACK信号。
    7. 拉低SCL线

      • IIC_SCL(0);:主机拉低SCL线,准备进行下一步操作。
    8. 延迟

      • iic_delay();:再次短暂延迟以确保信号稳定。
  • 应答信号:

    void iic_ack(void)
    {
        IIC_SCL(0);  // 确保SCL线为低电平
        iic_delay();
        IIC_SDA(0);  // 数据线为低电平,表示应答信号
        iic_delay();
        IIC_SCL(1);  // 拉高SCL线,发送应答信号
        iic_delay();
    }
    
    1. IIC_SCL(0)

      • 这一步确保时钟线(SCL)为低电平,表示准备发送应答信号。
    2. IIC_SDA(0)

      • 将数据线(SDA)拉低,表示发送应答信号(ACK)。
      • ACK信号表示接收设备成功接收到数据,并准备接收下一个字节。
    3. IIC_SCL(1)

      • 拉高SCL线,完成应答信号的发送。
      • 接收设备在此时刻确认它已准备好接收数据。
  • 非应答信号:

    void iic_nack(void)
    {
        IIC_SCL(0);
        iic_delay();
        IIC_SDA(1);   //数据线为高电平,表示非应答
        iic_delay();
        IIC_SCL(1);
        iic_delay();
    }
    
    1. IIC_SCL(0)

      • 这一步确保时钟线(SCL)为低电平,表示准备发送非应答信号。
    2. IIC_SDA(1)

      • 将数据线(SDA)拉高,表示发送非应答信号(NACK)。
      • NACK信号表示接收设备未能成功接收到数据,或发送设备需要停止传输。
    3. IIC_SCL(1)

      • 拉高SCL线,完成非应答信号的发送。
      • 发送设备在此时刻了解接收设备未能成功接收数据或接收设备不再准备接收更多数据。
  • 发送一个字节数据:

    void iic_send_byte(uint8_t data)
    {
        for(uint8_t t = 0; t < 8; t++)
        {
            IIC_SDA((data & 0x80) >> 7);
            iic_delay();
            IIC_SCL(1);
            iic_delay();
            IIC_SCL(0);
            data <<= 1;
        }
        IIC_SDA(1);  //发送完成,主机释放SDA线
    }
    
    1. 循环发送每一位数据

      for(uint8_t t = 0; t < 8; t++)
      {
          IIC_SDA((data & 0x80) >> 7);  // 设置数据线的值
          iic_delay();                  // 延时
          IIC_SCL(1);                   // 设置时钟线为高电平
          iic_delay();                  // 延时
          IIC_SCL(0);                   // 设置时钟线为低电平
          data <<= 1;                   // 左移一位,准备发送下一位数据
      }
      
      • for 循环从 t = 0 开始,一直执行到 t < 8,每次循环 t 自增。
      • IIC_SDA((data & 0x80) >> 7);:设置数据线(SDA)的值为 data 的最高位(第7位),data & 0x80 是用来获取 data 的最高位,>> 7 是右移操作,将最高位移到最低位,然后通过 IIC_SDA 函数设置数据线的值。
      • iic_delay();:延时一段时间,为了等待数据稳定或者设备处理数据。
      • IIC_SCL(1);:设置时钟线(SCL)为高电平。
      • iic_delay();:再次延时一段时间。
      • IIC_SCL(0);:将时钟线(SCL)设置为低电平。
      • data <<= 1;:将数据左移一位,这样下一次循环时处理的是数据的下一位(次高位)。

      这样循环执行完毕后,就完成了对一个字节数据的逐位发送。

    2. 释放数据线

      IIC_SDA(1);  //发送完成,主机释放SDA线
      
      • 将数据线(SDA)设置为高电平,表示数据发送完成后,释放数据线,让其他设备可以使用这条数据线。
  • 读取一个字节数据:

    uint8_t iic_read_byte(uint8_t ack)
    {
        uint8_t receive = 0;
        
        for(uint8_t t = 0; t < 8; t++)
        {
            receive <<= 1;
            IIC_SCL(1);
            iic_delay();
            if(IIC_READ_SDA) receive++;
            IIC_SCL(0);
            iic_delay();
        }
        if(!ack) iic_nack();
        else iic_ack();
        
        return receive;
    }
    
    1. 初始化接收变量和循环接收每一位数据

      uint8_t receive = 0;
      
      for(uint8_t t = 0; t < 8; t++)
      {
          receive <<= 1;
          IIC_SCL(1);
          iic_delay();
          if(IIC_READ_SDA) receive++;
          IIC_SCL(0);
          iic_delay();
      }
      
      • receive 是用来存储接收到的数据的变量,初始值为0。
      • for 循环从 t = 0 开始,一直执行到 t < 8,每次循环 t 自增。
      • receive <<= 1;:将接收变量 receive 左移一位,为下一位数据的接收做准备。
      • IIC_SCL(1);:设置时钟线(SCL)为高电平,表示准备接收数据。
      • iic_delay();:延时一段时间,以确保数据稳定。
      • if(IIC_READ_SDA) receive++;:检查数据线(SDA)的状态,如果为高电平(1),则将 receive 的最低位(第0位)设置为1。
      • IIC_SCL(0);:将时钟线(SCL)设置为低电平,完成一个时钟周期的接收。

      这样循环执行完毕后,receive 变量中存储了从设备发送过来的8位数据。

    2. 发送应答或不应答信号

      if(!ack) iic_nack();
      else iic_ack();
      
      • 根据函数参数 ack 的值来决定发送应答(ACK)或不应答(NACK)信号。
      • 如果 ack 为0,调用 iic_nack() 函数发送不应答信号。
      • 如果 ack 不为0(即非0),调用 iic_ack() 函数发送应答信号。
    3. 返回接收到的数据

      return receive;
      
      • 将接收到的完整字节数据返回给调用该函数的地方。
  • 总结:

    函数功能
    void iic_init(void)IIC初始化函数
    static void iic_delay(void)IIC延时函数
    void iic_start(void)起始信号
    void iic_stop(void)终止信号
    uint8_t iic_wait_ack(void)等待应答信号
    void iic_ack(void)应答信号
    void iic_nack(void)非应答信号
    void iic_send_byte(uint8_t data)发送一个字节数据
    uint8_t iic_read_byte(uint8_t ack)读取1个字节数据
2. AT24C02驱动代码
  • 写字节函数:

    void at24c02_write_one_byte(uint8_t addr, uint8_t data)
    {
        //1.发送起始信号
        iic_start();
        
        //2.发送通信地址
        iic_send_byte(0xA0);
        
        //3.等待应答信号
        iic_wait_ack();
        
        //4.发送内存地址
        iic_send_byte(addr);
        
        //5.等待应答信号
        iic_wait_ack();
        
        //6.发送数据
        iic_send_byte(data);
        
        //7.等待应答信号
        iic_wait_ack();
        
        //8.发送停止信号
        iic_stop();
        
        //等待EEPROM写入完成
        delay_ms(10);
    }
    
  • 读字节函数:

    uint8_t at24c02_read_one_byte(uint8_t addr)
    {
        uint8_t rec = 0;
        
        //1.发送起始信号
        iic_start();
        
        //2.发送通信地址
        iic_send_byte(0xA0);
        
        //3.等待应答信号
        iic_wait_ack();
        
        //4.发送内存地址
        iic_send_byte(addr);
        
        //5.等待应答信号
        iic_wait_ack();
        
        //6.发送起始信号
        iic_start();
        
        //7.发送读操作地址
        iic_send_byte(0xA1);
        
        //8.等待应答信号
        iic_wait_ack();
        
        //9.等待接收数据
        rec = iic_read_byte(0);
        
        //10.发送非应答(获取该地址)
        
        
        //11.发送停止信号
        iic_stop();
        
        //等待EEPROM写入完成
        delay_ms(10);
        
        return rec;
    }
    
3. 实验结果分析

在这里插入图片描述
在这里插入图片描述

以上是写时序的实验结果,三个字节分别是设备地址、内存地址、数据内容。黄色线条为时钟线SCL,绿色线条为数据线SDA,从图中可以清晰的看到起始信号、终止信号、应答信号、以及发送的数据。

声明:资料来源(战舰STM32F103ZET6开发板资源包)

  1. Cortex-M3权威指南(中文).pdf
  2. STM32F10xxx参考手册_V10(中文版).pdf
  3. STM32F103 战舰开发指南V1.3.pdf
  4. STM32F103ZET6(中文版).pdf
  5. 战舰V4 硬件参考手册_V1.0.pdf

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

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

相关文章

MAC系统下安装VUE

下载node.js 点击链接 选择图片中的稳定版本 安装node.js 打开终端&#xff0c;输入 node -v 和 npm -v 显示如上信息表示安装成功 安装vue脚手架&#x1f527; sudo npm install -g vue/cli查看vue版本 vue -V6. 启动项目 1 采用 图形页面方式 控制台输入&#xff…

2024最新D卷 华为OD统一考试题库清单(按算法分类),如果你时间紧迫,就按这个刷

目录 专栏导读华为OD机试算法题太多了&#xff0c;知识点繁杂&#xff0c;如何刷题更有效率呢&#xff1f; 一、逻辑分析二、数据结构1、线性表① 数组② 双指针 2、map与list3、队列4、链表5、栈6、滑动窗口7、二叉树8、并查集9、矩阵 三、算法1、基础算法① 贪心思维② 二分查…

【c++进阶(三)】STL之vector的介绍和使用

&#x1f493;博主CSDN主页::Am心若依旧&#x1f493; ⏩专栏分类c从入门到精通⏪ &#x1f69a;代码仓库:青酒余成&#x1f69a; &#x1f339;关注我&#x1faf5;带你学习更多c   &#x1f51d;&#x1f51d; vector的介绍 1.vector表示的是可变序列大小的容器 2、vector…

MySQL 日志(一)

本篇主要介绍MySQL日志的相关内容。 目录 一、日志简介 常用日志 一般查询日志和慢查询日志的输出形式 日志表 二、一般查询日志 三、慢查询日志 四、错误日志 一、日志简介 常用日志 在MySQL中常用的日志主要有如下几种&#xff1a; 这些日志通常情况下都是关闭的&a…

一文读懂Java线程池之线程复用原理

什么是线程复用 在Java中,我们正常创建线程执行任务,一般都是一条线程绑定一个Runnable执行任务。而Runnable实际只是一个普通接口,真正要执行,则还是利用了Thread类的run方法。这个rurn方法由native本地方法start0进行调用。我们看Thread类的run方法实现 /* What will be…

Mysql8.0.31开启mysqlbinlog

1、查看mysqlbinlog是否已经开启 show variables like %log_bin%; log_bin: ON是OFF否已经开启binlog log_bin_basename: binlog所在路径的文件开头前缀名 lob_bin_index: binlog文件的索引文件所在路径 2、若log_binOFF&#xff0c;则开启log_bin -- 退出mysql client ex…

open-amv开发环境搭建

open-amv是基于rv1103主控芯片的视觉开发板子 1.板子使用 板子使用type c作为调试口&#xff0c;同时供电&#xff0c;请在电脑上下载adb&#xff0c;当板子通过tpye c与电脑连接后&#xff0c;执行命令adb shell就会进入到板子的linux系统命令行。 2.编译环境 2.1 搭建doc…

【网络编程】优雅断开套接字连接

Linux的close函数和Windows的closesocket函数意味着完全断开连接。完全断开不仅指无法传输数据&#xff0c;而且也不能接收数据。 2台主机正在进行双向通信&#xff0c;主机A发送完最后的数据后&#xff0c;调用close函数断开了连接&#xff0c;之后主机A无法再接收主机B传输的…

超全Midjourney自学教程,怒码1万3千字!这是我见过最良心的教程啦!

前段时间&#xff0c;后台有网友私信我&#xff0c;说想跟我一起学AI~当时一边开心一边惶恐&#xff0c;满足于被人看到自己的努力、又担心自己是不是教不好别人&#xff0c;毕竟我自己也是业余时间边学边发的那种~ 不过&#xff0c;我还是会继续搬运或整理一些我认为值得记录…

C++100行超简单系统

非常好用&#xff0c;小白也可以自己修改 先来看图片&#xff1a; 用法附在代码里了&#xff01; #include <bits/stdc.h> #include <windows.h>using namespace std;struct users {string name;string num; bool f; } u[10000];int now_users 0; /*当前用户数*…

MyBatis使用 PageHelper 分页查询插件的详细配置

1. MyBatis使用 PageHelper 分页查询插件的详细配置 文章目录 1. MyBatis使用 PageHelper 分页查询插件的详细配置2. 准备工作3. 使用传统的 limit 关键字进行分页4. PageHelper 插件&#xff08;配置步骤&#xff09;4.1 第一步&#xff1a;引入依赖4.2 第二步&#xff1a;在m…

LDR6020显示器应用:革新连接体验,引领未来显示技术

一、引言 随着科技的飞速发展&#xff0c;显示器作为信息展示的重要载体&#xff0c;其性能和应用场景不断得到拓展。特别是在办公、娱乐以及物联网等领域&#xff0c;用户对显示器的需求越来越多样化。在这一背景下&#xff0c;LDR6020显示器的出现&#xff0c;以其卓越的性能…

【LeetCode:2779. 数组的最大美丽值 + 排序 + 二分】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

干部管理软件有哪些

随着信息技术的飞速发展&#xff0c;干部管理软件在各级党政机关、国企事业单位中扮演着越来越重要的角色。这些软件通过整合干部管理的各项业务流程&#xff0c;实现了干部信息的系统化、规范化和高效化管理。以下是几款主流的干部管理软件及其特点&#xff1a; 一、干部信息…

C++ 06 之 c++增强

c06c增强.cpp #include <iostream>using namespace std; // 1、全局变量检测增强&#xff1a;可以检测出重定义 (c语言不会报错&#xff0c;但是C会报错) //int a; //int a 10;// 2、函数检测增强: 函数返回值类型、形参类型、实参个数 int sum(int a, int b) {return …

Json-server 的使用教程

目录 前言一、简介二、安装与配置1. 安装 node-js2. npm 镜像设置3. 安装 json-server 三、使用1. 创建本地数据源2. 启动 Json Server3. 操作数据&#xff08;1&#xff09;查询数据&#xff08;2&#xff09;新增数据&#xff08;3&#xff09;修改数据&#xff08;4&#xf…

仿element-ui 实现自己组件库 <3>

目录 input 组件封装 v-model用在组件上 显示和隐藏密码 封装switch组件 实现转换的功能 设置checkbox input 组件封装 首先input组件的基本框架和样式&#xff1a; <div class"miao-input"><input class"miao-input_inner" > </div…

LDR6500:手机电脑拓展坞转接器方案的卓越之选

随着科技的飞速发展&#xff0c;手机和电脑已成为我们日常生活中不可或缺的工具。然而&#xff0c;它们的接口有限&#xff0c;经常难以满足我们多样化的需求。这时&#xff0c;一款高效、稳定的拓展坞转接器就显得尤为重要。LDR6500&#xff0c;作为乐得瑞科技精心研发的USB P…

HCIA12 NAT网络地址转换实验

NAT&#xff08;Network Address Translation&#xff09;是将 IP 报头中的 IP 地址转换为另一个 IP 地址的过程。主要俩好处&#xff1a; • 有效避免来自外网的攻击&#xff0c;可以很大程度上提高网络安全性。 • 控制内网主机访问外网&#xff0c;同时也可以控制外网…

微信鸿蒙版本来了 我不允许你不会

前言: 各位同学大家好, 好久没有更新鸿蒙文章了 现在更新一个鸿蒙版本高仿微信版本 那么废话不多说 我们正式开始 作者:徐庆 团队:坚果派 公众号:“大前端之旅” 润开鸿生态技术专家,华为HDE,CSDN博客专家,CSDN超级个体,CSDN特邀嘉宾,InfoQ签约作者,OpenHarmony布…