STM32入门——IIC通讯
江科大STM32学习记录
I2C通信
- I2C(Inter IC Bus)是由Philips公司开发的一种通用数据总线
- 两根通信线:SCL(Serial Clock)、SDA(Serial Data)
- 同步,半双工
- 带数据应答
- 支持总线挂载多设备(一主多从、多主多从)
硬件电路 - 所有I2C设备的SCL连在一起,SDA连在一起
- 设备的SCL和SDA均要配置成开漏输出模式
- SCL和SDA各添加一个上拉电阻,阻值一般为4.7KΩ左右

- *IIC的SCL和SDA要配置成开漏输出,开漏与弱上拉的模式
I2C时序基本单元
- 起始条件:SCL高电平期间,SDA从高电平切换到低电平
- 终止条件:SCL高电平期间,SDA从低电平切换到高电平

void myIIC_Start(void)//SCL高电平期间,sda产生一个下升沿
{Set_SDA(1);Set_SCL(1);Set_SDA(0);Set_SCL(0);}void myIIC_Stop(void)//SCL高电平期间,sda产生一个上升沿
{Set_SCL(1);Set_SDA(0);Set_SDA(1);
}
I2C时序基本单元
- 发送一个字节:SCL低电平期间,主机将数据位依次放到SDA线上(高位先行),然后释放SCL,从机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节

void myIIC_SendByte(uint8_t Byte)//SCL低电平,主机把数据放到SDA线上,SCL高电平,从机读取SDA上的数据
{uint8_t i;for(i=0;i<8;i++){Set_SDA(Byte & (0x80>>i));Set_SCL(1); Set_SCL(0); }
}
I2C时序基本单元
- 接收一个字节:SCL低电平期间,从机将数据位依次放到SDA线上(高位先行),然后释放SCL,主机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可接收一个字节(主机在接收之前,需要释放SDA)

uint8_t myIIC_ReceByte(void)//SCL低电平,从机把数据放到SDA线上,SCL高电平,主机读取SDA上的数据
{uint8_t Rece_Byte = 0x00;uint8_t i;Set_SDA(1);//释放sda总线for(i=0;i<8;i++){Set_SCL(1);if(Read_SDA() == 1){Rece_Byte |= (0x80 >> i);}Set_SCL(0); }return Rece_Byte;}
- 发送应答:主机在接收完一个字节之后,在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答
- 接收应答:主机在发送完一个字节之后,在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放SDA)

void myIIC_SendACK(uint8_t AckBit)
{Set_SDA(AckBit);Set_SCL(1); Set_SCL(0);
}uint8_t myIIC_ReceACK(void)
{uint8_t AckBit;Set_SDA(1);//释放sda总线Set_SCL(1);AckBit = Read_SDA();Set_SCL(0); return AckBit;
}
I2C时序
- 指定地址写
- 对于指定设备(Slave Address),在指定地址(Reg Address)下,写入指定数据(Data)

发送的第一个字节为从机地址加读写位,高七位为从机地址,最低位为读写位(0表示要写入;1表示要读出)
void Specify_Address_Write(uint8_t Slave,uint8_t RegAddress,uint8_t Data)
{myIIC_Start();myIIC_SendByte(Slave);myIIC_ReceACK();myIIC_SendByte(RegAddress);myIIC_ReceACK();myIIC_SendByte(Data);myIIC_ReceACK();myIIC_Stop();}
- 当前地址读
- 对于指定设备(Slave Address),在当前地址指针指示的地址下,读取从机数据(Data)

- 指定地址读
- 对于指定设备(Slave Address),在指定地址(Reg Address)下,读取从机数据(Data)

uint8_t Specify_Address_Read(uint8_t Slave,uint8_t RegAddress)
{uint8_t temp;myIIC_Start();myIIC_SendByte(Slave);myIIC_ReceACK();myIIC_SendByte(RegAddress);myIIC_ReceACK();
//上面为指定地址myIIC_Start();//重复起始myIIC_SendByte(Slave | 0x01);//低位1表示读操作myIIC_ReceACK();temp = myIIC_ReceByte();myIIC_SendACK(1);//不应答myIIC_Stop();return temp;
MPU6050简介
- MPU6050是一个6轴姿态传感器,可以测量芯片自身X、Y、Z轴的加速度、角速度参数,通过数据融合,可进一步得到姿态角,常应用于平衡车、飞行器等需要检测自身姿态的场景
- 3轴加速度计(Accelerometer):测量X、Y、Z轴的加速度
- 3轴陀螺仪传感器(Gyroscope):测量X、Y、Z轴的角速度

MPU6050参数 - 16位ADC采集传感器的模拟信号,量化范围:-32768~32767
- 加速度计满量程选择:±2、±4、±8、±16(g)
- 陀螺仪满量程选择: ±250、±500、±1000、±2000(°/sec)
- 可配置的数字低通滤波器
- 可配置的时钟源
- 可配置的采样分频
- I2C从机地址:1101000(AD0=0) 1101001(AD0=1)
硬件电路


MPU6050框图

案例:获取xyz加速度值和陀螺仪值
#include "MPU6050.h"void MPU6050_Init(void)
{myIIC_Init();Specify_Address_Write(MPU6050_Address,MPU6050_PWR_MGMT_1,0x01);Specify_Address_Write(MPU6050_Address,MPU6050_PWR_MGMT_2,0x00);Specify_Address_Write(MPU6050_Address,MPU6050_SMPLRT_DIV,0x09);Specify_Address_Write(MPU6050_Address,MPU6050_CONFIG,0x06);Specify_Address_Write(MPU6050_Address,MPU6050_GYRO_CONFIG,0x18);Specify_Address_Write(MPU6050_Address,MPU6050_ACCEL_CONFIG,0x18);}uint8_t MCU6050_GetID(void)
{return Specify_Address_Read(MPU6050_Address,MPU6050_WHO_AM_I);}void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ, int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ)
{uint8_t data_H;uint8_t data_L;data_H = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_XOUT_H);data_L = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_XOUT_L);*AccX = (data_H<<8) | data_L;data_H = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_YOUT_H);data_L = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_YOUT_L);*AccY = (data_H<<8) | data_L;data_H = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_ZOUT_H);data_L = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_ZOUT_L);*AccZ = (data_H<<8) | data_L;data_H = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_XOUT_H);data_L = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_XOUT_L);*GyroX = (data_H<<8) | data_L;data_H = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_YOUT_H);data_L = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_YOUT_L);*GyroY = (data_H<<8) | data_L;data_H = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_ZOUT_H);data_L = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_ZOUT_L);*GyroZ = (data_H<<8) | data_L;}
#ifndef _MPU6050_H
#define _MPU6050_H
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "myIIC.h"
#define MPU6050_SMPLRT_DIV 0x19
#define MPU6050_CONFIG 0x1A
#define MPU6050_GYRO_CONFIG 0x1B
#define MPU6050_ACCEL_CONFIG 0x1C#define MPU6050_ACCEL_XOUT_H 0x3B
#define MPU6050_ACCEL_XOUT_L 0x3C
#define MPU6050_ACCEL_YOUT_H 0x3D
#define MPU6050_ACCEL_YOUT_L 0x3E
#define MPU6050_ACCEL_ZOUT_H 0x3F
#define MPU6050_ACCEL_ZOUT_L 0x40
#define MPU6050_TEMP_OUT_H 0x41
#define MPU6050_TEMP_OUT_L 0x42
#define MPU6050_GYRO_XOUT_H 0x43
#define MPU6050_GYRO_XOUT_L 0x44
#define MPU6050_GYRO_YOUT_H 0x45
#define MPU6050_GYRO_YOUT_L 0x46
#define MPU6050_GYRO_ZOUT_H 0x47
#define MPU6050_GYRO_ZOUT_L 0x48#define MPU6050_PWR_MGMT_1 0x6B
#define MPU6050_PWR_MGMT_2 0x6C
#define MPU6050_WHO_AM_I 0x75
#define MPU6050_Address 0xD0void MPU6050_Init(void);
uint8_t MCU6050_GetID(void);
void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ, int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ);#endif
硬件I2C通信
- STM32内部集成了硬件I2C收发电路,可以由硬件自动执行时钟生成、起始终止条件生成、应答位收发、数据收发等功能,减轻CPU的负担
- 支持多主机模型
- 支持7位/10位地址模式
- 支持不同的通讯速度,标准速度(高达100 kHz),快速(高达400 kHz)
- 支持DMA
- 兼容SMBus协议
- STM32F103C8T6 硬件I2C资源:I2C1、I2C2
I2C框图

I2C基本结构

主机发送

//超时退出机制uint8_t Check_Timeout(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
{uint32_t time = 5000;while(I2C_CheckEvent(I2Cx,I2C_EVENT) != SUCCESS){time -- ;if(time == 0){return Timeout;}}return SUCCESS;
}void Specify_Address_Write(uint8_t Slave,uint8_t RegAddress,uint8_t Data)
{I2C_GenerateSTART(I2C2,ENABLE);Check_Timeout(I2C2,I2C_EVENT_MASTER_MODE_SELECT);I2C_Send7bitAddress(I2C2,Slave,I2C_Direction_Transmitter);Check_Timeout(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);I2C_SendData(I2C2,RegAddress);Check_Timeout(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTING);I2C_SendData(I2C2,Data);Check_Timeout(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED);I2C_GenerateSTOP(I2C2,ENABLE);}
主机接收

uint8_t Specify_Address_Read(uint8_t Slave,uint8_t RegAddress)
{uint8_t ReceData;I2C_GenerateSTART(I2C2,ENABLE);Check_Timeout(I2C2,I2C_EVENT_MASTER_MODE_SELECT);I2C_Send7bitAddress(I2C2,Slave,I2C_Direction_Transmitter);Check_Timeout(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);I2C_SendData(I2C2,RegAddress);Check_Timeout(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED);I2C_GenerateSTART(I2C2,ENABLE);Check_Timeout(I2C2,I2C_EVENT_MASTER_MODE_SELECT);I2C_Send7bitAddress(I2C2,Slave,I2C_Direction_Receiver);Check_Timeout(I2C2,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED);I2C_AcknowledgeConfig(I2C2,DISABLE);I2C_GenerateSTOP(I2C2,ENABLE);Check_Timeout(I2C2,I2C_EVENT_MASTER_BYTE_RECEIVED);ReceData = I2C_ReceiveData(I2C2);I2C_AcknowledgeConfig(I2C2,ENABLE);return ReceData;
}
软件/硬件波形对比

硬件I2C相关寄存器

硬件I2C读取MPU6050数据
#include "I2C.h"void I2C_init(void)
{//开启时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//GPIO初始化GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;//复用开漏模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStructure);GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11);I2C_InitTypeDef I2C_InitStructure;I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;//指定I2C模式。I2C_InitStructure.I2C_ClockSpeed = 200000;//指定时钟频率I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//作为从机地址为7位I2C_InitStructure.I2C_OwnAddress1 = 0x00;//作为从机自身地址I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;//指定I2C快速模式占空比I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;I2C_Init(I2C2,&I2C_InitStructure);I2C_Cmd(I2C2,ENABLE);}//超时退出机制uint8_t Check_Timeout(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
{uint32_t time = 5000;while(I2C_CheckEvent(I2Cx,I2C_EVENT) != SUCCESS){time -- ;if(time == 0){return Timeout;}}return SUCCESS;
}void Specify_Address_Write(uint8_t Slave,uint8_t RegAddress,uint8_t Data)
{I2C_GenerateSTART(I2C2,ENABLE);Check_Timeout(I2C2,I2C_EVENT_MASTER_MODE_SELECT);I2C_Send7bitAddress(I2C2,Slave,I2C_Direction_Transmitter);Check_Timeout(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);I2C_SendData(I2C2,RegAddress);Check_Timeout(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTING);I2C_SendData(I2C2,Data);Check_Timeout(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED);I2C_GenerateSTOP(I2C2,ENABLE);}uint8_t Specify_Address_Read(uint8_t Slave,uint8_t RegAddress)
{uint8_t ReceData;I2C_GenerateSTART(I2C2,ENABLE);Check_Timeout(I2C2,I2C_EVENT_MASTER_MODE_SELECT);I2C_Send7bitAddress(I2C2,Slave,I2C_Direction_Transmitter);Check_Timeout(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);I2C_SendData(I2C2,RegAddress);Check_Timeout(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED);I2C_GenerateSTART(I2C2,ENABLE);Check_Timeout(I2C2,I2C_EVENT_MASTER_MODE_SELECT);I2C_Send7bitAddress(I2C2,Slave,I2C_Direction_Receiver);Check_Timeout(I2C2,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED);//接收的最后一个字节之前就要不应答和发送终止信号I2C_AcknowledgeConfig(I2C2,DISABLE);I2C_GenerateSTOP(I2C2,ENABLE);Check_Timeout(I2C2,I2C_EVENT_MASTER_BYTE_RECEIVED);//接收到事件后一个字节就传到DR寄存器了ReceData = I2C_ReceiveData(I2C2);I2C_AcknowledgeConfig(I2C2,ENABLE);return ReceData;
}void MPU6050_Init(void)
{I2C_init();Specify_Address_Write(MPU6050_Address,MPU6050_PWR_MGMT_1,0x01);Specify_Address_Write(MPU6050_Address,MPU6050_PWR_MGMT_2,0x00);Specify_Address_Write(MPU6050_Address,MPU6050_SMPLRT_DIV,0x09);Specify_Address_Write(MPU6050_Address,MPU6050_CONFIG,0x06);Specify_Address_Write(MPU6050_Address,MPU6050_GYRO_CONFIG,0x18);Specify_Address_Write(MPU6050_Address,MPU6050_ACCEL_CONFIG,0x18);}
uint8_t MCU6050_GetID(void)
{return Specify_Address_Read(MPU6050_Address,MPU6050_WHO_AM_I);}void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ, int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ)
{uint8_t data_H;uint8_t data_L;data_H = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_XOUT_H);data_L = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_XOUT_L);*AccX = (data_H<<8) | data_L;data_H = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_YOUT_H);data_L = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_YOUT_L);*AccY = (data_H<<8) | data_L;data_H = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_ZOUT_H);data_L = Specify_Address_Read(MPU6050_Address,MPU6050_ACCEL_ZOUT_L);*AccZ = (data_H<<8) | data_L;data_H = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_XOUT_H);data_L = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_XOUT_L);*GyroX = (data_H<<8) | data_L;data_H = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_YOUT_H);data_L = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_YOUT_L);*GyroY = (data_H<<8) | data_L;data_H = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_ZOUT_H);data_L = Specify_Address_Read(MPU6050_Address,MPU6050_GYRO_ZOUT_L);*GyroZ = (data_H<<8) | data_L;}相关文章:
STM32入门——IIC通讯
江科大STM32学习记录 I2C通信 I2C(Inter IC Bus)是由Philips公司开发的一种通用数据总线两根通信线:SCL(Serial Clock)、SDA(Serial Data)同步,半双工带数据应答支持总线挂载多设备…...
DTC 19服务学习2
紧跟上篇 0x04 reportDTCSnapshotRecordByDTCNumber 通过DTC和快照序列来获取DTC快照记录。 适用以下假设: — 服务器支持存储给定 DTC 的两个 DTCSnapshot 记录的能力。 — 此示例假定是上一个示例的延续。 — 假设服务器请求服务器存储的 DTC 编号 123456 的两个…...
【腾讯云 TDSQL-C Serverless 产品体验】基于腾讯云轻量服务器以及 TDSQL-C 搭建 LNMP WordPress 博客系统
文章目录 一、前言二、数据库发展与云原生数据库2.1 数据库发展简介2.2 云原生数据库简介2.2.1 云数据库与云原生数据库区别 三、腾讯云 TDSQL-C 数据库3.1 什么是腾讯云 TDSQL-C 数据库3.2 为什么推出 TDSQL-C 数据库?传统 MySQL 架构存在较多痛点3.2.1 传统 MySQL…...
【vue3】对axios进行封装,方便更改路由并且可以改成局域网ip访问(附代码)
对axios封装是在main.js里面进行封装,因为main.js是一个vue项目的入口 步骤: 在1处创建一个axios实例为http,baseURL是基础地址(根据自己的需求写),写了这个在vue界面调用后端接口时只用在post请求处写路由…...
Java IO流(三)线程模型
传统阻塞I/O模式 其中黄色框表示对象,蓝色框表示线程,白色框表示API方法 特点 采用阻塞IO模式获取输入数据每个连接都需要独立的线程完成数据的输入,业务处理和处理结果数据返回 潜在问题 并发数很大时,需要对应每个连接请求创建一个线程,所以占用资源很大连接创建后,若当前…...
string(模拟实现与深拷贝)
目录 深拷贝与浅拷贝 浅拷贝: 深拷贝 写时拷贝(了解) 模拟实现 准备 完整代码 深拷贝与浅拷贝 浅拷贝: 也称位拷贝,编译器只是将对象中的值拷贝过来。如果对象中管理资源,最后就会导致多个对象共享同一份资源,当一…...
5.Vue_Element
文章目录 1 Ajax1.1 Ajax介绍1.1.1 Ajax概述1.1.2 Ajax作用1.1.3 同步异步 1.2 Axios1.2.1 Axios的基本使用1.2.2 Axios请求方法的别名 2 前端工程化2.1 前端工程化特点2.2 Vue项目开发流程 3 Vue组件库Element3.1 Element介绍 1 Ajax 1.1 Ajax介绍 1.1.1 Ajax概述 Ajax: 全…...
链路追踪jaeger
这里的链路指的是客户端向服务发起一个请求,该请求所经过的路线,也可以说是该请求经过的流量 例如: 客户端发起一个下订单的请求其流量过程: request—>service—>order-web—>order_srv—>mysql—>order_srv—&…...
神经网络基础-神经网络补充概念-42-梯度检验
概念 梯度检验(Gradient Checking)是一种验证数值计算梯度与解析计算梯度之间是否一致的技术,通常用于确保实现的反向传播算法正确性。在深度学习中,通过梯度检验可以帮助验证你的神经网络模型是否正确地计算了梯度,从…...
<kernel>kernel 6.4 USB-之-hub_port_connect()分析
<kernel>kernel 6.4 USB-之-hub_port_connect()分析 kernel 6.4 USB系列文章如下: <kernel>kernel 6.4 USB-之-hub_event()分析 <kernel>kernel 6.4 USB-之-port_event()分析 <kern…...
linux驱动学习3-外部中断
在做中断试验时,发现中断驱动总是insmod失败,之后定位到 gpio_request 失败,之后是想到使用的野火做好的系统,在uEnv.txt中会加载大量设备树插件,将key相关的设备树插件屏蔽即可。 linux中断API函数 中断号 每个中断…...
vue中的canvas插件
vue中canvas插件有vue-konva、vue-fabricjs、vue-canvas-effect、vue-chartjs和vue-threejs等。详细介绍:1、vue-konva是一个用于在Vue.js中使用Konva.js的插件,Konva.js是一个功能强大的HTML5 2D 渲染引擎,可以用于创建交互式的Canvas应用程…...
分享图片 | 快速浏览网页资源,批量保存、一键分享图片
前言 小伙伴学习吉他,有时需要在互联网搜索曲谱资源,而多数曲谱均为图片,并且为多页,在电脑上显示练习很不方便,需要停下来点击鼠标进行翻页,影响练习的连贯性。 为了解决上述问题,通常把图片…...
Programming abstractions in C阅读笔记:p123-p126
《Programming Abstractions In C》学习第50天,p123-p126,总结如下: 一、技术总结 1.notaion 这也是一个在计算机相关书籍中出现的词,但有时却不是那么好理解,因为它可以指代很多对象,这里做一个记录。示…...
自然语言处理从入门到应用——LangChain:链(Chains)-[通用功能:LLMChain、RouterChain和SequentialChain]
分类目录:《自然语言处理从入门到应用》总目录 LLMChain LLMChain是查询LLM对象最流行的方式之一。它使用提供的输入键值(如果有的话,还包括内存键值)格式化提示模板,将格式化的字符串传递给LLM,并返回LLM…...
ElasticSearch-安装部署全过程
本文已收录于专栏 《中间件合集》 目录 概念说明什么是ElasticSearch什么是Kibana什么是RESTful API 提供服务安装过程安装ElasticSearch1.下载ElasticSearch 安装包2.解压安装包3.进入解压之后的文件夹4.创建一个data文件夹用来存储数据5.进入config文件夹编辑elasticsearch.y…...
mathematica报错:Tag Plus is \ Protected
在使用化简函数Simplify的时候使用了规则的语法,但是规则可能没有使用等号。 例如 Simplify[(1 - c^2)/d^2, c^2 d^2 1]等号被认为是赋值符号,要修改为两个等号: Simplify[(1 - c^2)/d^2, c^2 d^2 1]这样就不会报错了。...
Python Django 模型概述与应用
今天来为大家介绍 Django 框架的模型部分,模型是真实数据的简单明确的描述,它包含了储存的数据所必要的字段和行为,Django 遵循 DRY Principle 。它的目标是你只需要定义数据模型,然后其它的杂七杂八代码你都不用关心,…...
Golang Gorm 更新字段 save update updates
更新和删除操作的前提条件都是要在找到数据的情况下,先要查询到数据才可以做操作。 更新的前提的先查询到记录,Save保存所有字段,用于单个记录的全字段更新它会保控所有字段,即使零值也会保存。 在更新和删除之前,要利…...
springBoot 配置文件引入 redis 的相关参数说明
在Spring Boot应用中使用Redis作为缓存或数据存储时,可以在应用的配置文件中配置相关参数。下面是常用的Redis配置参数及其说明: spring.redis.host: Redis服务器主机地址,默认为localhost。spring.redis.port: Redis服务器端口,…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...
WEB3全栈开发——面试专业技能点P7前端与链上集成
一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染(SSR)与静态网站生成(SSG) 框架,由 Vercel 开发。它简化了构建生产级 React 应用的过程,并内置了很多特性: ✅ 文件系…...
