IIC通信总线

文章目录

    • 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.mzph.cn/web/27631.shtml

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

相关文章

【C++提高编程-05】----C++之Deque容器实战

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

MySQL的三种重要的日志

日志 Mysql有三大日志系统 Undo Log&#xff08;回滚日志&#xff09;&#xff1a;记录修改前的数据&#xff0c;用于事务回滚和 MVCC&#xff08;多版本并发控制&#xff09;。 Redo Log&#xff08;重做日志&#xff09;&#xff1a;记录数据变更&#xff0c;用于崩溃恢复&…

【java】指定类,指定package,找到package下面,这个类的所有子类

目录 ■java代码 ■注意 ■运行效果 ■包的结构 ■java代码 package com.sxz.study.reflect;import java.io.File; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.List;public class …

缓存技术实战[一文讲透!](Redis、Ecache等常用缓存原理介绍及实战)

目录 文章目录 目录缓存简介工作原理缓存分类1.按照技术层次分类2.按照应用场景分类3.按照缓存策略分类 应用场景1.硬件缓存2.软件缓存数据库缓存Web开发应用层缓存 3.分布式缓存4.微服务架构5.移动端应用6.大数据处理7.游戏开发 缓存优点缓存带来的问题 常见常用Java缓存技术1…

Unity 之通过自定义协议从浏览器启动本地应用程序

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity 之通过自定义协议从浏览器启动本地应用程序 TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进…

树莓派等Linux开发板上使用 SSD1306 OLED 屏幕,bullseye系统 ubuntu,debian

Raspberry Pi OS Bullseye 最近发布了,随之而来的是许多改进,但其中大部分都在引擎盖下。没有那么多视觉差异,最明显的可能是新的默认桌面背景,现在是大坝或湖泊上的日落。https://www.the-diy-life.com/add-an-oled-stats-display-to-raspberry-pi-os-bullseye/ 通过这次操…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 特惠寿司(100分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 📎在线评测链接 特惠寿司(100分) 🌍 评测功能需要订阅专栏后私信联系清隆解…

王思聪日本街头在被偶遇

王思聪日本街头再被偶遇&#xff0c;甜蜜约会日常成网友热议焦点近日&#xff0c;有网友在日本街头再次偶遇了“国民老公”王思聪&#xff0c;这次他不仅携带着一位美丽的女友&#xff0c;还展现出了两人之间亲密无间的互动&#xff0c;让不少网友感叹&#xff1a;这真的是每天…

八、BGP

目录 一、为何需要BGP&#xff1f; 二、BGP 2.1、BGP邻居 2.2、BGP报文 2.3、BGP路由 2.4、BGP通告遵循原则 2.5、BGP实验 第一步&#xff1a;建立邻居 第二步&#xff1a;引入路由 BGP路由黑洞 路由黑洞解决方案 1、IBGP全互联 2、路由引入 3、MPLS 多协…

甘肃这款饼子很火 你是否有吃过呢

白吉饼那独特的外形&#xff0c;圆圆的十分可爱。&#x1f44f;它的表皮酥脆&#xff0c;内里绵软&#xff0c;麦香四溢。&#x1f60b;拿在手里沉甸甸的&#xff0c;就知道用料十足。 无论是直接吃&#xff0c;感受那纯粹的面香&#xff0c;还是夹上腊汁肉&#xff0c;变成美味…

ThinkPHP5.0 apache服务器配置URL重写,index.php去除

本地环境wamp .htaccess文件代码 <IfModule mod_rewrite.c>Options FollowSymlinks -MultiviewsRewriteEngine onRewriteCond %{REQUEST_FILENAME} !-dRewriteCond %{REQUEST_FILENAME} !-fRewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L] </IfModule> 踩过这个坑&a…

dbForge Studioor MySQL v6 解锁版 安装教程(MYSQL数据库客户端)

前言 dbForge Studioor MySQL是一个在Windows平台被广泛使用的MySQL客户端&#xff0c;它能够使MySQL开发人员和管理人员在一个方便的环境中与他人一起完成创建和执行查询&#xff0c;开发和调试MySQL程序&#xff0c;自动化管理MySQL数据库对象等工作。 一、下载地址 下载链…

什么是GPT-4

什么是GPT-4 ChatGPT 可以说&#xff0c;ChatGPT的发展&#xff0c;主要的分水岭在GPT-4&#xff0c;GPT-4主要是文本对话&#xff0c;且训练度也不够完善。GPT-4之后不但训练度得到了巨大提升&#xff0c;模型支持的参数量更是预计有1万亿参数&#xff0c;在这之后出现的GPT-4…

图书管理系统(SpringBoot+SpringMVC+MyBatis)

目录 1.数据库表设计 2.引入MyBatis和MySQL驱动依赖 3.配置数据库&日志 4.Model创建 5.用户登录功能实现 6.实现添加图书功能 7.实现翻页功能 1.数据库表设计 数据库表是应⽤程序开发中的⼀个重要环节, 数据库表的设计往往会决定我们的应⽤需求是否能顺利实现, 甚至决…

探索档案未来,尽在ARCHE-2024

2024年第三届上海国际智慧档案展览会暨高峰论坛&#xff08;ARCHE-2024&#xff09;将于2024年6月19日至21日在上海跨国采购会展中心隆重举行。深圳市铨顺宏科技有限公司应邀参展&#xff0c;将以全新形象盛装亮相&#xff0c;展示其在档案管理领域的最新技术和解决方案。 ARC…

UC Berkeley简介以及和Stanford的区别与联系

UC Berkeley Source: Google Map 中文版 UC Berkeley&#xff0c;全称University of California, Berkeley&#xff0c;是一所位于美国加利福尼亚州伯克利市的世界知名公立研究型大学。以下是关于UC Berkeley的详细介绍&#xff1a; 学术声誉和排名 学术声誉&#xff1a; U…

PROSAIL模型前向模拟与植被参数遥感

原文链接&#xff1a;PROSAIL模型前向模拟与植被参数遥感 “绿水青山就是金山银山”的生态文明理念现已深入人心&#xff0c;从顶层设计到全面部署&#xff0c;生态文明建设进入举措最实、推进最快、力度最大、成效最好的时期。生态文明评价必须将生态系统健康作为基本内容&am…

超详解——Python 字典详解——小白篇

目录 1. 创建字典 示例&#xff1a; 2. 访问字典中的元素 示例&#xff1a; 3. 修改字典元素 示例&#xff1a; 4. 删除字典元素 示例&#xff1a; 5. 查找元素是否是字典的键 示例&#xff1a; 6. 标准类型操作符 获取字典长度 合并两个字典 7. 常用内置函数 k…

TFT屏幕波形显示

REVIEW 关于TFT显示屏&#xff0c;之前已经做过彩条显示&#xff1a; TFT显示屏驱动_tft驱动-CSDN博客 关于ROM IP核&#xff0c;以及coe文件生成&#xff1a; FPGA寄存器 Vivado IP核_fpga寄存器资源-CSDN博客 1. TFT屏幕ROM显示正弦波 ①生成coe文件 %% sin-cos wave dat…

【Linux】基础IO [万字之作]

目录 一.重谈文件 二.重谈C文件操作 1.操作 1.文件的打开和关闭 2.文件的读写操作 ​编辑 1.fgetc函数 2.fputc函数 3.fputs函数 4.fgets函数 5.fprintf函数 6.fscanf函数 7.fread函数 8.fwrite函数 三.重谈当前路径 四.系统文件操作接口 1.Open函数 2.write函数 3…