STM32实战之深入理解I²C通信协议
目录
I²C的物理层
I²C的协议层
I²C特点
I²C 总线时序图
软件模拟I²C时序分享
软件模拟IIC驱动AT24C02分享
例程简介
例程分享
STM32的I²C外设
IIC(Inter-Integrated Circuit),也称为I²C或TWI(Two-Wire Interface),是一种广泛使用的串行总线接口,用于连接低速度的集成电路。这种通信协议非常适合在单个主设备和多个从设备之间进行短距离通信。
I²C的物理层
IIC通信只需要两根线:一个是串行数据线(SDA),另一个是串行时钟线(SCL)。这两根线都需要通过上拉电阻连接到正电源,以确保在没有信号驱动时,线路能够保持在高电平状态。
I²C的协议层
IIC协议定义了一系列的信号,包括开始信号、停止信号、数据有效性和应答信号。开始信号和停止信号用于标识一次通信的开始和结束,而数据有效性确保数据在时钟信号稳定时被读取。应答信号则是从设备对接收数据的确认。
I²C特点
- 两线制接口:I2C通信只需要两根线,一根是串行数据线(SDA),另一根是串行时钟线(SCL),所以I2C为半双工通信。
- 多主设备:I2C允许多个主设备(master)和多个从设备(slave)在同一总线上通信。
- 地址识别:每个从设备都有一个唯一的地址,主设备通过这个地址与特定的从设备通信。
- 同步通信:I2C是一种同步通信协议,数据传输是由时钟信号(SCL)来同步的。
- 支持多速率:I2C支持多种不同的数据传输速率,包括标准模式(100kbps)、快速模式(400kbps)、快速模式加(1Mbps)和高速模式(3.4Mbps)。
- 软件可配置:I2C设备的地址和一些功能可以通过软件进行配置。
- 简单易用:I2C接口的硬件实现相对简单,易于集成到各种微控制器和其他集成电路中。
- 应用广泛:I2C广泛应用于各种电子产品中,如手机、电视、医疗设备和嵌入式系统等。
- 支持热插拔:I2C设备支持在系统运行时添加或移除,即热插拔。
- 总线仲裁:在多主设备的情况下,I2C协议提供了一种仲裁机制,以决定哪个主设备可以控制总线。
- 时钟拉伸:从设备可以通过拉低时钟线来暂停通信(称为时钟拉伸),以便有足够的时间处理接收到的数据或完成数据发送。
- 应答机制:I2C通信中包含应答(ACK)和非应答(NACK)信号,用于指示数据是否成功接收。
I2C由于其简单和灵活的特性,成为了连接低速外围设备,如传感器、EEPROM、显示器等的理想选择。
I²C 总线时序图
总线时序图是理解IIC通信的关键。它展示了开始信号、数据位的传输、应答位以及停止信号的顺序。在IIC通信中,数据位在SCL线为高电平时被认为是稳定的,因此数据应该在SCL的高电平期间被读取。
起始条件: SCL高电平期间,SDA从高电平切换到低电平
终止条件: SCL高电平期间,SDA从低电平切换到高电平
起始和终止条件都是由主机产生
发送一个字节: SCL低电平期间,主机将数据位依次放到SDA线上,(高位先行),然后释放SCL,从机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许由数据变化,依次循环上述过程8次即可发送一个字节
接收一个字节: SCL低电平期间,从机将数据位依次放到SDA线上(高位先行),然后释放SCL,主机将在SCL高电平期间读取数据位,所哟一SCL高电平期间SDA不允许有数据变换,依次循环上述过程8次,即可接收一个字节(主机在接收数据前需要先释放SDA)
发送应答: 主机在接收完一个字节后,在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答
接收应答: 主机在发送完一个字节之后,在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前需要释放SDA)
软件模拟I²C时序分享
/*** @brief 定义SCL写函数* @param None* @retval None*/void myi2c_w_scl(uint8_t bitval){GPIO_WriteBit(GPIOA, GPIO_Pin_1, (BitAction)bitval); //将bitval的值写入GPIOA的Pin_1,也就是SCL线Delay_us(10); //延迟10微秒}/*** @brief 定义SDA写函数* @param None* @retval None*/void myi2c_w_sda(uint8_t bitval){GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)bitval); //将bitval的值写入GPIOA的Pin_0,也就是SDA线Delay_us(10); //延迟10微秒}/*** @brief 读取SDA数据* @param None* @retval None*/uint8_t myi2c_r_sda(void){return GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0); //读取GPIOA的Pin_0,也就是SDA线的值}/*** @brief 软件模拟I2C初始化* SDA PA0 推挽输出* SCL PA1 推挽输出* @param None* @retval None*/
void myi2c_init(void){//初始化GPIO口RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA时钟GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO初始化结构体GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //设置GPIO模式为开漏输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; //设置GPIO的Pin_0和Pin_1GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置GPIO速度为50MHzGPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA//释放总线GPIO_SetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_1); //将GPIOA的Pin_0和Pin_1设置为高电平,释放总线
}/*** @brief I2C起始条件* @param None* @retval None*/
void i2c_start(void){//输出起始条件myi2c_w_sda(1); //将SDA线设置为高电平myi2c_w_scl(1); //将SCL线设置为高电平myi2c_w_sda(0); //将SDA线设置为低电平,生成起始条件myi2c_w_scl(0); //将SCL线设置为低电平
}/*** @brief I2C结束条件* @param None* @retval None*/
void i2c_stop(void){//输出起始条件myi2c_w_sda(0); //将SDA线设置为低电平myi2c_w_scl(1); //将SCL线设置为高电平myi2c_w_sda(1); //将SDA线设置为高电平,生成结束条件
}/**
* @brief I2C发送一个字节* @param None* @retval None*/
void myi2c_sendbyte(uint8_t byte){for(uint8_t i = 0; i < 8; i++){ //循环8次,发送一个字节myi2c_w_sda(byte & 0x80 >> i); //每发送一次向右偏移一个字节myi2c_w_scl(1); //将SCL线设置为高电平myi2c_w_scl(0); //将SCL线设置为低电平}
}/*** @brief I2C接收一个字节* @param None* @retval None*/
uint8_t myi2c_recv_byte(void){uint8_t byte = 0; //定义一个字节变量for(uint8_t i = 0; i < 8; i++){ //循环8次,接收一个字节myi2c_w_scl(1); //将SCL线设置为高电平if(myi2c_r_sda() == 1){byte |= (0x80 >> i);} //如果SDA线为高电平,将byte的相应位设置为1myi2c_w_scl(0); //将SCL线设置为低电平}return byte; //返回接收到的字节
}/*** @brief I2C接收应答* @param None* @retval None*/
uint8_t myi2c_recv_ack(void){uint8_t ackbit = 0; //定义一个应答位变量myi2c_w_sda(1); //将SDA线设置为高电平myi2c_w_scl(1); //将SCL线设置为高电平ackbit = myi2c_r_sda(); //读取SDA线的值,也就是应答位myi2c_w_scl(0); //将SCL线设置为低电平return ackbit; //返回应答位
}/**
* @brief I2C发送应答* @param None* @retval None*/
void myi2c_send_ack(uint8_t ackbit){myi2c_w_sda(ackbit); //将应答位的值写入SDA线myi2c_w_scl(1); //将SCL线设置为高电平myi2c_w_scl(0); //将SCL线设置为低电平
}
软件模拟IIC驱动AT24C02分享
例程简介
通过I2C协议与AT24C04 EEPROM芯片进行交互的函数。EEPROM代表电可擦除可编程只读存储器,这是一种非易失性存储器,用于计算机和其他电子设备中存储断电后必须保存的少量数据。
以下是每个函数的简要概述:
-
AT24_init
:此函数初始化与AT24C04芯片通信的I2C接口。 -
AT24_write_byte
:此函数将单个字节的数据写入AT24C04芯片的指定地址。 -
AT24_read_byte
:此函数从AT24C04芯片的指定地址读取单个字节的数据。 -
AT24_write_page
:此函数将多个字节的数据写入AT24C04芯片的指定地址。AT24C04的内存被划分为多个页面,每个页面可以容纳多个字节的数据。 -
AT24_WriteBuffer
:此函数将数据缓冲区写入AT24C04芯片。它考虑到芯片内存的页面结构,并在必要时跨多个页面写入数据。 -
AT24_readBuffer
:此函数从AT24C04芯片读取数据缓冲区。与AT24_WriteBuffer
一样,它也考虑到芯片内存的页面结构。
例程分享
/*源代码*/
#include "AT24.h"uint8_t AT24_ADDR_W1 = 0XA0;
uint8_t AT24_ADDR_W2 = 0XA2;
uint8_t AT24_ADDR_R1 = 0xA1;
uint8_t AT24_ADDR_R2 = 0xA3;/*** @brief AT24C04初始化* @param None* @retval None*/
void AT24_init(void){myi2c_init();}/*** @brief 指定地址写入一个字节数据(0 ---- 255)* @param uint16_t addr 写入数据地址* @param uint8_t data 写入字节* @retval 写入成功返回4*/
uint8_t AT24_write_byte(uint16_t addr, uint8_t data){i2c_start(); //发送起始信号myi2c_sendbyte(AT24_ADDR_W1); //发送从机地址if(myi2c_recv_ack() == 1){i2c_stop(); //发送停止位printf("AT24寻址未应答\r\n");return 1;}myi2c_sendbyte(addr); //发送要写入的地址if(myi2c_recv_ack() == 1){i2c_stop(); //发送停止位printf("AT24内部寻址未应答\r\n");return 2;}myi2c_sendbyte(data); //发送要写入的数据if(myi2c_recv_ack() == 1){i2c_stop(); //发送停止位printf("AT24写入数据未应答\r\n");return 3;}i2c_stop(); //发送停止位printf("AT24写入数据成功\r\n");return 4;
}/*** @brief 指定地址读出一个字节数据(0 ---- 255)* @param uint16_t addr 读数据地址* @retval 成功返回读出数据*/uint8_t AT24_read_byte(uint16_t addr){uint8_t read_data = 0;i2c_start(); //发送起始信号myi2c_sendbyte(AT24_ADDR_W1); //发送从机地址if(myi2c_recv_ack() == 1){i2c_stop(); //发送停止位printf("AT24寻址未应答\r\n");return 1;}myi2c_sendbyte(addr); //发送要写入的地址if(myi2c_recv_ack() == 1){i2c_stop(); //发送停止位printf("AT24内部寻址未应答\r\n");return 2;}i2c_stop(); //发送停止位i2c_start(); //发送起始信号myi2c_sendbyte(AT24_ADDR_R1); //发送从机地址if(myi2c_recv_ack() == 1){i2c_stop(); //发送停止位printf("AT24寻址未应答\r\n");return 1;}read_data = myi2c_recv_byte();myi2c_send_ack(1);i2c_stop(); //发送停止位return read_data;
}/*** @brief 指定地址页写入数据(0 ---- 255)* @param uint16_t addr 写入数据地址* @param uint8_t data 写入字节首地址* @param uint8_t num 写入字节个数* @retval 写入成功返回4*/
uint8_t AT24_write_page(uint16_t addr, uint8_t num, uint8_t *data){i2c_start(); //发送起始信号myi2c_sendbyte(AT24_ADDR_W1); //发送从机地址if(myi2c_recv_ack() == 1){i2c_stop(); //发送停止位printf("AT24寻址未应答\r\n");return 1;}myi2c_sendbyte(addr); //发送要写入的地址if(myi2c_recv_ack() == 1){i2c_stop(); //发送停止位printf("AT24内部寻址未应答\r\n");return 2;}while(num--){myi2c_sendbyte(*data); //发送要写入的数据if(myi2c_recv_ack() == 1){i2c_stop(); //发送停止位printf("AT24写入数据未应答\r\n");return 3;}data++;}i2c_stop(); //发送停止位printf("AT24写入数据成功\r\n");return 4;
}/*** @brief 随机写* @param uint8_t *pBuffer 写入数据的首地址* @param uint32_t WriteAddr 写入地址* @param uint16_t NumByteToWrite 数据长度* @retval None*/
void AT24_WriteBuffer(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite){uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0;Addr = WriteAddr % 16; //判断地址是否为整页count = 16 - Addr; //当前页剩余字节数NumOfPage = NumByteToWrite / 16; //需要的整页数NumOfSingle = NumByteToWrite % 16; //除整页剩余的字节数if (Addr == 0) /*整页开始 */{if (NumOfPage == 0) /*所写数据不够一整页,直接调用页编程函数 */{AT24_write_page(WriteAddr, NumByteToWrite, pBuffer);}else /*所写数据超过一页*/{while (NumOfPage--) //整页写{AT24_write_page(WriteAddr, 16, pBuffer);WriteAddr += 16;pBuffer += 16;}AT24_write_page(WriteAddr, NumOfSingle, pBuffer); //除整页之外剩余的}}else /*不是整页开始写 */{if (NumOfPage == 0) /*所写不到一页 */{if (NumOfSingle > count) /*所需空间大于当前页所剩空间*/{temp = NumOfSingle - count; //当前页写完之后剩余量AT24_write_page(WriteAddr, count, pBuffer); //在当前页写,写满WriteAddr += count;pBuffer += count;AT24_write_page(WriteAddr, temp, pBuffer); //剩余写入下一页}else{AT24_write_page(WriteAddr, NumByteToWrite, pBuffer); //直接写当前页}}else /*写入数据量大于一页 */{NumByteToWrite -= count; //写满当前页所剩数据NumOfPage = NumByteToWrite / 16; //要写入的整页NumOfSingle = NumByteToWrite % 16; //写完整页剩余的字节AT24_write_page(WriteAddr, count, pBuffer);//把当前页写满WriteAddr += count;pBuffer += count;while (NumOfPage--) //写整页{AT24_write_page(WriteAddr, 16, pBuffer);WriteAddr += 16;pBuffer += 16;}if (NumOfSingle != 0) //写剩余不满一页的字节{AT24_write_page(WriteAddr, NumOfSingle, pBuffer);}}}
}/*** @brief 随便读* @param None* @retval None*/
uint8_t AT24_readBuffer(uint16_t addr, uint16_t num, uint8_t *recvdata){i2c_start(); //发送起始信号myi2c_sendbyte(AT24_ADDR_W1); //发送从机地址Delay_us(10);if(myi2c_recv_ack() == 1){i2c_stop(); //发送停止位printf("AT24器件寻址未应答\r\n");return 1;}myi2c_sendbyte(addr); //发送要写入的地址if(myi2c_recv_ack() == 1){i2c_stop(); //发送停止位printf("AT24内部寻址未应答\r\n");return 2;}i2c_stop(); //发送停止位i2c_start(); //发送起始信号myi2c_sendbyte(AT24_ADDR_R1); //发送从机地址if(myi2c_recv_ack() == 1){i2c_stop(); //发送停止位printf("AT24器件2寻址未应答\r\n");return 1;}while(num--){*recvdata = myi2c_recv_byte();myi2c_send_ack(0);recvdata++;Delay_us(5);}myi2c_send_ack(1);i2c_stop(); //发送停止位return num;
}
/*头文件*/
#ifndef __AT24_H_
#define __AT24_H_#include "stm32f4xx.h" // Device header
#include "myi2c.h"
#include "usart.h"
#include "delay.h"void AT24_init(void);
uint8_t AT24_write_byte(uint16_t addr, uint8_t data);
uint8_t AT24_read_byte(uint16_t addr);
uint8_t AT24_write_page(uint16_t addr, uint8_t num, uint8_t *data);
void AT24_WriteBuffer(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);
uint8_t AT24_readBuffer(uint16_t addr, uint16_t num, uint8_t *recvdata);
#endif
STM32的I²C外设
STM32内部集成了硬件I²C收发电路,可以由硬件自动执行时钟生成、起始终止条件生成、应答位收发、数据发送等功能,减轻CPU的负担。STM32的I²C外设支持多主机模式、7位或10位地址模式、不同的通信速度(标准速度高达100KHZ,快速400KHZ)、DMA,以及兼容SMBus协议。
- 硬件自动执行:STM32内部的硬件I2C模块可以自动执行时钟生成、起始终止条件生成、应答位收发、数据发送等功能,减轻了CPU的负担,使通信更高效。
- 多主机模式:STM32的硬件I2C模块支持多主机模式,可以实现多个主机设备在同一总线上进行通信。
- 7位或10位地址模式:STM32的硬件I2C模块支持7位或10位地址模式,可以适应不同设备的寻址需求。
- 不同通信速度:STM32的硬件I2C模块支持不同的通信速度,标准速度可达100KHz,快速模式可达400KHz,可以根据具体需求选择合适的通信速率。
- 支持DMA:STM32的硬件I2C模块支持DMA(直接内存访问)功能,可以通过DMA传输数据,提高数据传输效率,减少CPU的负载。
- 兼容SMBus协议:STM32的硬件I2C模块与SMBus(系统管理总线)协议兼容,SMBus是一种基于I2C的通信协议,用于管理和控制电子设备。
这些特点使得STM32的硬件I2C模块成为在嵌入式系统中实现I2C通信的理想选择,提供了方便、高效和可靠的通信功能。
相关文章:

STM32实战之深入理解I²C通信协议
目录 IC的物理层 IC的协议层 IC特点 IC 总线时序图 软件模拟IC时序分享 软件模拟IIC驱动AT24C02分享 例程简介 例程分享 STM32的IC外设 IIC(Inter-Integrated Circuit),也称为IC或TWI(Two-Wire Interface)&am…...
如何区分ChatGPT 3.5与ChatGPT 4:洞悉智能对话的新时代
如何区分ChatGPT 3.5与ChatGPT 4:洞悉智能对话的新时代 随着人工智能技术的快速发展,OpenAI持续推出更加强大和精准的模型,以改善和扩展用户体验。在聊天机器人领域,特别是OpenAI的ChatGPT系列,每一次迭代都带来了显著…...

blender scripting 编写
blender scripting 编写 一、查看ui按钮对应的代码二、查看或修改对象名称三、案例:渲染多张图片并导出对应的相机参数 一、查看ui按钮对应的代码 二、查看或修改对象名称 三、案例:渲染多张图片并导出对应的相机参数 注:通过ui交互都设置好…...

使用 Elasticsearch 检测抄袭 (二)
我在在之前的文章 “使用 Elasticsearch 检测抄袭 (一)” 介绍了如何检文章抄袭。这个在许多的实际使用中非常有意义。我在 CSDN 上的文章也经常被人引用或者抄袭。有的人甚至也不用指明出处。这对文章的作者来说是很不公平的。文章介绍的内容针对很多的…...
WPF DataGrid
文章目录 SelectionModeHeaderVisibilityBorderBrush SelectionMode DataGrid 控件的 SelectionMode 属性定义了用户可以如何选择 DataGrid 中的行。它是一个枚举类型的属性,有以下几个选项: Single(默认值):只能选择…...

【cesium-5】鼠标交互与数据查询
scene.pick返回的是包含给定窗口位置基元的对象 scene.drillpack返回的是给定窗口位置所有对象的列表 Globe.pick返回的是给光线和地形的交点 Cesium.ScreenSpaceEventType.MIDDLE_CLICK 鼠标中间点击事件 Cesium.ScreenSpaceEventType.MOUSE_MOVE 鼠标移入事件 Cesium.ScreenS…...

Xcode 编译速度慢是什么原因?如何提高编译速度?
作为一个开发者,我们都希望能够高效地开发应用程序,而编译速度是影响开发效率的重要因素之一。然而,有时候我们会发现在使用 Xcode 进行开发时,译速度非常慢,这给我们带来了不少困扰。那么,为什么 Xcode 的…...
Best Arm Identification in Batched Multi-armed Bandit Problems
Q: 这篇论文试图解决什么问题? A: 这篇论文试图解决在批量多臂老虎机问题中进行最佳臂识别(BAI)的挑战,其中必须成批地对臂进行抽样,因为代理等待反馈的时间有限。这种场景出现在许多现实世界的应用中,例如…...
Unity编辑器紫色
紫色原因是因为编辑器内跑了其他平台的shader兼容性导致的,需要动态的去修改shader,主要用到Unity的api : Shader.Find(shaderName); 具体的工具代码如下: using System.Collections; using System.Collections.Generic; using UnityEngine…...
冒泡排序(C语言)
void BubbleSort(int arr[], int len) {int i, j, temp;for (i 0; i < len; i){for (j len - 1; j > i; j--){if (arr[j] > arr[j 1]){temp arr[j];arr[j] arr[j 1];arr[j 1] temp;}}} } 优化: 设置标志位flag,如果发生了交换flag设置…...

Unity中Shader观察空间推导(在Shader中实现)
文章目录 前言一、观察空间矩阵推导1、求观察空间基向量2、求观察空间的基向量在世界空间中的矩阵 的 逆矩阵2、求平移变换矩阵3、相乘得出 观察空间转化矩阵4、得到顶点的世界空间坐标,然后转化到观察空间5、把观察空间坐标转化为齐次裁剪坐标输出到屏幕 二、最终效…...

Hive04_DDL操作
Hive DDL操作 1 DDL 数据定义 1.1 创建数据库 CREATE DATABASE [IF NOT EXISTS] database_name [COMMENT database_comment] [LOCATION hdfs_path] [WITH DBPROPERTIES (property_nameproperty_value, ...)];[IF NOT EXISTS] :判断是否存在 [COMMENT database_c…...
odoo17核心概念view4——view.js
这是view系列的第四篇文章,专门介绍View组件。 作为一个Component,它总共包含js、css、xml三个标准文件,当然最重要的是view.js 首先在setup函数中对传入的参数props做了各种校验,然后扩展了subenv useSubEnv({keepLast: new Kee…...
Centos7 openSSL
阅读时长:10分钟 本文内容: 在阿里云Centos7上部署python3.10.6项目时遇到openSSL协议不支持,导致无法下载第三方包 本文目的: 通过手动编译,升级openssl版本centos7 重编译 python3.10.6github下载缓慢解决镜像源记录…...
Web 安全之文件下载漏洞详解
目录 引言 文件下载漏洞原理 文件下载漏洞的危害 文件下载漏洞类型 文件下载漏洞的利用方法 文件下载漏洞示例 文件下载漏洞的防护措施 漏洞检测与测试 小结 引言 在数字化时代,文件下载是网络应用程序的重要的功能之一,用户可以通过这一功能获…...

搬运机器人RFID传感器CNS-RFID-01|1S的RS485(MODBUS|HS协议)通讯连接方法
搬运机器人RFID传感器CNS-RFID-01|1S支持RS485通信,可支持RS485(MODBUS RTU)协议、RS485-HS协议,广泛应用于物流仓储,立库 AGV|无人叉车|搬送机器人等领域,常用定位、驻车等,本篇重点介绍CNS-RF…...
使用ZMQ.proxy实现ZMQ PUB消息转发
MQ.proxy 是 ZeroMQ 库中的一个功能,用于创建一个简单的代理服务器。它可以将消息从一个套接字传递到另一个套接字,实现消息的转发和路由。 要使用 ZMQ.proxy,需要按照以下步骤进行操作: 创建两个 ZMQ.Socket 对象:一个…...

若依SQL Server开发使用教程
1. sys_menu表中的将菜单ID修改为自动ID,解决不能增加菜单的问题,操作流程如下: 解决方案如下 菜单栏->工具->选项 点击设计器,去掉阻止保存要求更新创建表的更改选项,点确认既可以保存了 2 自动生成代码找不表的解决方案…...
Mysql5.7服务器选项、系统变量和状态变量参考
官网地址:MySQL :: MySQL 5.7 Reference Manual :: 5.1.3 Server Option, System Variable, and Status Variable Reference 欢迎关注留言,我是收集整理小能手,工具翻译,仅供参考,笔芯笔芯. MySQL 5.7 参考手册 / ..…...
【Qt-Qss-Style】
Qt编程指南 ■ Qss■ Style■ setStyleSheet ■ style.qss■ border■ 去除弹框背景圆角■ QProgressBar样式表 ■ Qss Qt 支持很多种常见 符号 “>”代表直属子部件,说明两个控件之间是父子关系。 “#”代表后面的字段是前面控件类型的名称,当然也可…...

Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...

中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...

给网站添加live2d看板娘
给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...

C++_哈希表
本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说,直接开始吧! 一、基础概念 1. 哈希核心思想: 哈希函数的作用:通过此函数建立一个Key与存储位置之间的映射关系。理想目标:实现…...
WEB3全栈开发——面试专业技能点P7前端与链上集成
一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染(SSR)与静态网站生成(SSG) 框架,由 Vercel 开发。它简化了构建生产级 React 应用的过程,并内置了很多特性: ✅ 文件系…...