STM32——I2C通信
文章目录
- 一、I2C通信
- 二、使用I2C通信的硬件设备
- 三、硬件电路
- 四、I2C时序基本单元
- 起始与终止
- 发送
- 接收
- 发送应答与接收应答
- 五、I2C时序
- 指定地址写
- 当前地址读
- 指定地址读
- 连续读与写
- 六、MPU6050简介
- 七、MPU6050参数
- 八、硬件电路
- 九、MPU6050框图
- 十、系统时钟
- 十一、MPU6050的中断源
- 十二、寄存器映像
- 十三、软件I2C读写MPU6050
- 电路设计
- 关键代码
- 十四、硬件I2C读写MPU6050
一、I2C通信
- I2C总线(Inter IC BUS)是由Philips公司开发的一种通用数据总线
- 两根通信线:SCL(Serial Clock)、SDA(Serial Data)
- 同步【多一条时钟线,控制从机读写】,半双工【一根通信线】
- 带数据应答
- 支持总线挂载多设备(一主多从、多主多从)
- 控制原理和单片机cpu操作外设原理一样,单片机通过数据总线对寄存器进行读取和写入,而单片机需要通过协议来读写外部模块的寄存器,配置mpu6050的寄存器进而控制硬件电路。
- 异步通信对传输速率严格,且不能处理进入中断,必须完整发送一个字节,
非常依赖硬件外设的支持,必须USART电路才能使用
,同步时序比异步时序稳定性更加高,可以暂停传输(同时暂停时钟线) - 软件模拟I2C通信:通过软件手动翻转电平实现通信,对硬件的依赖程度低
二、使用I2C通信的硬件设备
三、硬件电路
所有I2C设备的SCL连在一起,SDA连在一起
主机对SCL线是完全控制,对SDA线不是,在从机发送数据和从机应答的时候,主机才会转交SDA控制器给从机,从机的SCL线只能被动读取。
为了防止总线没有协调好导致电源短路问题,I2C禁止所有设备输出强上拉高电平【不能是推挽输出,会输出高电平】,
采用外置弱上拉电阻+开漏输出的电路结构,可以同时兼具输入和输出功能
。输入的时候先输出1,再读取输入数据寄存器- 即设备的SCL和SDA均要配置成开漏输出模式【只有低电平和浮空两种状态】
- SCL和SDA各添加一个上拉电阻,阻值一般为4.7KΩ左右【
为了避免高电平造成的引脚浮空,加弱上拉电阻,类似于弹簧,配合开漏输出就是下拉的低电平或不拉的高电平
】 - CPU和外设内部的SCL和SDA设计如下图所示
- 有线与现象,一个从机是低电平,则SDA线就是低电平,只有所有设备输出高电平,SDA线才是高电平,利用这个特性可以实现多主机模式下的时钟同步和总线仲裁,这就是SCL也采用上拉电阻的原因。
四、I2C时序基本单元
总结:
在读写时,SCL低电平时,SDA写,SCL高电平时,SDA不变
在起始和结束时,SCL高电平,SDA变化
起始与终止
空闲状态,SCL和SDA由于外挂的上拉电阻拉高致高电平
起始和终止都是由主机产生的,从机始终不会去碰SCL和SDA线
起始条件:SCL高电平期间,SDA从高电平切换到低电平
终止条件:SCL高电平期间,SDA从低电平切换到高电平
发送
串口通信是低位先行,i2c是高位先行
- 发送一个字节:SCL低电平期间,主机将数据位依次放到SDA线上(高位先行),然后释放SCL,从机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节【在发送时,SCL和SDA都由主机进行控制】
由于有时钟线的控制,主机可以进入中断,此时传输会暂停,时序不会发送变化
接收
- 接收一个字节:SCL低电平期间,从机将数据位依次放到SDA线上(高位先行),然后释放SCL,主机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可接收一个字节(主机在接收之前,需要释放SDA)此时从机获得SDA控制权,释放SDA就是主机切换成输入模式,“释放”可以理解为主机原本就是输入模式,在下拉为低电平时是输出模式
发送应答与接收应答
发送应答和接收应答就是发送数据的一位和接收数据的一位
发送应答:主机在接收完一个字节之后,在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答
- 发送应答逻辑:主机接收完一个字节数据后,主机会给从机发送一个发送应答,决定是否继续接收,不继续接收就会收回对SDA的控制权
接收应答:主机在发送完一个字节之后,在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放SDA)
- 接收应答逻辑:主机发送完一个字节数据后,发送一个接收应答,释放SDA控制权,若有从机拿到控制权并拉低电平,表示某个从机接收完毕。
五、I2C时序
从机设备地址分为7位和10位,一般相同型号的芯片地址是一样的
当相同型号的芯片挂载在同一总线上时,可以通过最后几位区分,例如mpu6050的最后一位可以由AD0引脚控制,接低电平时地址是1101000,接高电平时地址是1101001
指定地址写
对于指定设备(Slave Address),在指定地址(Reg Address)下,写入指定数据(Data)
- 起始后,第一个字节内容必须是从机地址+读写位(0写1读)
- 接收应答:由于主机释放SDA之后立即就被从机拉低表示接收到该字节,根据线与的特性,此处就没有拉高的波形出现
- 在写操作时,第二个字节可以是指令控制字(如AD转换器)或寄存器地址(如MPU6050)
当前地址读
对于指定设备(Slave Address),在当前地址指针指示的地址下,读取从机数据(Data)
- 由于读写标志位为1时,主机还来不及发送要读寄存器的地址
- 从机哪个寄存器的数据呢?取决于之前写入的地址+1,该时序不常用
指定地址读
指定地址写+当前地址读(第三个字节不写入内容就直接开始读)
对于指定设备(Slave Address),在指定地址(Reg Address)下,读取从机数据(Data)
- sr表示重复起始条件,在后面可以加停止时序,地址指针不会消失
连续读与写
- 可以连续写入多个字节或读取多个字节,只需要在最后的时序写入多个字节,因为地址指针会在读写后自动加一,所以可以连续操作。读取时,还打算继续读就需要给应答,在结束的字节后给非应答,从机交出SDA控制权,也就是说从机的控制权从读写操作位1到发送应答位为1
- 连续地址写
- 连续地址读
六、MPU6050简介
- MPU6050是一个6轴姿态传感器,可以测量芯片自身X、Y、Z轴的加速度、角速度参数,
通过数据融合,可进一步得到姿态角(欧拉角)
,常应用于平衡车、飞行器等需要检测自身姿态的场景 - MPU6050得出来的姿态角有三种:PITCH(俯仰角)、ROLL(横滚角)、YAW(航向角)【对应XYZ】
- 3轴加速度计(Accelerometer):测量X、Y、Z轴的加速度
- 3轴陀螺仪传感器(Gyroscope):测量X、Y、Z轴的角速度
- 9轴是多了3轴磁力计(磁场强度),补测得的航向角因为磁场和硬件问题造成的积分累积偏差
- 10轴是多了气压强度
常见的数据融合算法有卡尔曼滤波,互补滤波,互补滤波和卡尔曼滤波能够一定程度解决航向角偏移的问题,而且对于随机干扰也有更优秀的表现,但是是较为复杂的算法。
MPU6050内部有DMP单元,可以进行数据融合和姿态解算,避免了复杂的算法操作和外围电路。可以减轻外围微处理器的工作负担且避免了繁琐的滤波和数据融合,使用方便,只需要通过简单读取寄存器操作便可以获得小车的姿态信息。。
加速度计测量的是加速度(可以看做测力计,根据牛顿第二定律F=ma可以计算加速度),加速度计具有静态稳定性,不具有动态稳定性
MPU6050的陀螺仪测量的是角速度,角度可以通过角速度积分得到
,具有动态稳定性,不具有静态稳定性
七、MPU6050参数
16位ADC采集传感器的
模拟信号,量化
范围:-32768~32767加速度计满量程选择:±2、±4、±8、±16(g)【量化范围对应加速度计的量程范围,变化大则选大量程,测量范围越广,变化小则选小量程,精度更高】
陀螺仪满量程选择: ±250、±500、±1000、±2000(°/sec)
可配置的数字低通滤波器(平缓信号抖动)
可配置的时钟源
可配置的采样分频
I2C从机地址:
- 1101000(AD0=0)
- 关于从机地址的十六进制,有两种表示方法
- 将二进制转十六进制是0x68当做从机地址,在I2C通信时需要左移一位,按位或上读写位,读1写0
- 将左移1位的数0xD0作为从机地址,此时在I2C通信时0xD0是写地址,0xD1是读地址
- 关于从机地址的十六进制,有两种表示方法
- 1101001(AD0=1)
- 1101000(AD0=0)
八、硬件电路
- SCL和SDA在硬件电路中已经接上拉电阻
- XCL和XDA是为了扩展芯片功能,通常是用于外接磁力计(偏航角)和气压计(高度),MPU6050的主机接口可以直接访问扩展芯片的数据,在芯片内部的DMP单元进行数据融合和姿态解算,解算出欧拉角
INT引脚可以设置电平跳变,用于输出芯片内部的中断事件
- 引脚功能图
九、MPU6050框图
- 灰色部分为传感器,本质上是可变电阻,通过串联分压后输出模拟电压,经过ADC转换后输出数据保存在寄存器中,不存在数据覆盖,每个传感器都有2个字节的寄存器,整个过程是硬件自动化完成
- 每个传感器都有自测单元self test,通过比较使能和失能后该寄存器的数据差是否在合理范围,进而判断传感器是否有问题
- Charge Pump电荷泵,用于升压,电源与电容并联时充电,串联时放电,放电时电压就是放大2倍,由于电容的电压会放完,所以不断的充电放电就能升压,在MPU6050中陀螺仪需要高电压支持所以设计该升压电路
- DMP:数字运动处理器是芯片内部自带的姿态解算的硬件算法
- 通信接口部分,上半部分显示MPU6050作为从机时,可以采用SPI通信,此时引脚的功能发送改变,也可以采用I2C通信。下半部分显示MPU6050作为主机时通过I2C协议与从机进行通信。Bypass Mux为开关,用于控制两路I2C是否为同一个通路,如果为同一个通路,则stm32既可以控制MPU6050又可以控制MPU6050的从设备。
十、系统时钟
- 可以使用内部晶振
- 内部陀螺仪的晶振
- 外部时钟
十一、MPU6050的中断源
- 分别是自由落体,运动,零运动等
- 会通过INT引脚输出电平跳变,若该引脚接入stm32可以通过外部中断来接受这个中断信号,通过CPU进行处理
十二、寄存器映像
- DMPLRT:采样频率分频器
- 分频越小,内部AD转换越快,数据寄存器刷新越快
- CONFIG:配置寄存器
- 主要配置低通滤波,配置参数越大,输出数据抖动越小
- GYRO:陀螺仪配置寄存器
- 配置自测和满量程
- ACCEL:加速度计配置寄存器
- 配置自测、满量程、高通滤波(运动检查)
- ACCEL:加速度计数据寄存器,分为高八位和低八位
- TEMP:温度寄存器,分为高八位和低八位
- GYRO:陀螺仪数据寄存器,分为高八位和低八位
十六位的有符号数以二进制补码的形式存储,读出高八位左移八位,或上低八位
- PWR:电源管理寄存器1和2
- 电源管理寄存器1:设备复位、睡眠模式(上电时默认是睡眠模式,需要关闭)、循环模式、温度传感器使能与失能、选择系统时钟来源
- 电源管理寄存器1:后六位可以控制六个轴进入待机模式
- WHO:器件ID号
- 中间六位是ID号,最高位是0,上电默认是0x68
十三、软件I2C读写MPU6050
电路设计
关键代码
MyI2C.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
/*
封装三个函数操作相应的IO口便于移植
MyI2C_W_SCL
MyI2C_W_SDA
MyI2C_R_SDA
*/
void MyI2C_W_SCL(uint8_t BitValue)
{GPIO_WriteBit(GPIOB, GPIO_Pin_10, (BitAction)BitValue);Delay_us(10);
}void MyI2C_W_SDA(uint8_t BitValue)
{GPIO_WriteBit(GPIOB, GPIO_Pin_11, (BitAction)BitValue);Delay_us(10);
}uint8_t MyI2C_R_SDA(void)
{uint8_t BitValue;BitValue = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11);Delay_us(10);return BitValue;
}void MyI2C_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_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);
}void MyI2C_Start(void)
{MyI2C_W_SDA(1);//为了兼容sr重复起始条件,先释放sda后释放sclMyI2C_W_SCL(1);MyI2C_W_SDA(0);MyI2C_W_SCL(0);
}void MyI2C_Stop(void)
{MyI2C_W_SDA(0);//为了确保释放sda是高电平,先拉低sdaMyI2C_W_SCL(1);MyI2C_W_SDA(1);
}void MyI2C_SendByte(uint8_t Byte)
{uint8_t i;for (i = 0; i < 8; i ++){MyI2C_W_SDA(Byte & (0x80 >> i));//高位先行,按位与取出相应位数,右移得到相应的位MyI2C_W_SCL(1);//高位读取sda数据MyI2C_W_SCL(0);}
}uint8_t MyI2C_ReceiveByte(void)
{uint8_t i, Byte = 0x00;//定义一个字节的数据MyI2C_W_SDA(1);//主机释放sdafor (i = 0; i < 8; i ++){MyI2C_W_SCL(1);//scl高电平时放入数据if (MyI2C_R_SDA() == 1){Byte |= (0x80 >> i);//输出寄存器为1则在该字节的相应位置写入1}MyI2C_W_SCL(0);}return Byte;
}
//发送用应答
void MyI2C_SendAck(uint8_t AckBit)
{MyI2C_W_SDA(AckBit);MyI2C_W_SCL(1);MyI2C_W_SCL(0);
}
//接收应答
uint8_t MyI2C_ReceiveAck(void)
{uint8_t AckBit;MyI2C_W_SDA(1);//释放sda,而不是输出1MyI2C_W_SCL(1);AckBit = MyI2C_R_SDA();//读到0则表示从机应答MyI2C_W_SCL(0);return AckBit;
}
MyI2C.h
#ifndef __MYI2C_H
#define __MYI2C_Hvoid MyI2C_Init(void);
void MyI2C_Start(void);
void MyI2C_Stop(void);
void MyI2C_SendByte(uint8_t Byte);
uint8_t MyI2C_ReceiveByte(void);
void MyI2C_SendAck(uint8_t AckBit);
uint8_t MyI2C_ReceiveAck(void);#endif
MPU6050.c
#include "stm32f10x.h" // Device header
#include "MyI2C.h"
#include "MPU6050_Reg.h"#define MPU6050_ADDRESS 0xD0//指定地址写
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data)
{MyI2C_Start();MyI2C_SendByte(MPU6050_ADDRESS);MyI2C_ReceiveAck();MyI2C_SendByte(RegAddress);MyI2C_ReceiveAck();MyI2C_SendByte(Data);MyI2C_ReceiveAck();MyI2C_Stop();
}
//指定地址读
uint8_t MPU6050_ReadReg(uint8_t RegAddress)
{uint8_t Data;MyI2C_Start();MyI2C_SendByte(MPU6050_ADDRESS);MyI2C_ReceiveAck();MyI2C_SendByte(RegAddress);MyI2C_ReceiveAck();//重复起始条件MyI2C_Start();MyI2C_SendByte(MPU6050_ADDRESS | 0x01);//指定地址写,修改最低位为1MyI2C_ReceiveAck();Data = MyI2C_ReceiveByte();MyI2C_SendAck(1);//主机收回控制权MyI2C_Stop();return Data;
}
//指定地址写之前需要取消睡眠模式
void MPU6050_Init(void)
{MyI2C_Init();MPU6050_WriteReg(MPU6050_PWR_MGMT_1, 0x01);//最后三位选择时钟,0x01选择陀螺仪x轴的时钟MPU6050_WriteReg(MPU6050_PWR_MGMT_2, 0x00);//不需要待机MPU6050_WriteReg(MPU6050_SMPLRT_DIV, 0x09);//10分频MPU6050_WriteReg(MPU6050_CONFIG, 0x06);//后三位给110,低通滤波器MPU6050_WriteReg(MPU6050_GYRO_CONFIG, 0x18);//中间2位是满量程,给11是最大量程MPU6050_WriteReg(MPU6050_ACCEL_CONFIG, 0x18);//中间2位是满量程,给11是最大量程
}uint8_t MPU6050_GetID(void)
{return MPU6050_ReadReg(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 DataH, DataL;DataH = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_H);DataL = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_L);*AccX = (DataH << 8) | DataL;//该变量为16位,有指针指向该地址DataH = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_H);DataL = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_L);*AccY = (DataH << 8) | DataL;DataH = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_H);DataL = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_L);*AccZ = (DataH << 8) | DataL;DataH = MPU6050_ReadReg(MPU6050_GYRO_XOUT_H);DataL = MPU6050_ReadReg(MPU6050_GYRO_XOUT_L);*GyroX = (DataH << 8) | DataL;DataH = MPU6050_ReadReg(MPU6050_GYRO_YOUT_H);DataL = MPU6050_ReadReg(MPU6050_GYRO_YOUT_L);*GyroY = (DataH << 8) | DataL;DataH = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_H);DataL = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_L);*GyroZ = (DataH << 8) | DataL;
}
/*
多返回值设计:
1. 在该文件中定义全局变量,extern暴露出去,在main文件中使用
2. 用指针
3. 使用结构体打包*/
MPU6050.h
#ifndef __MPU6050_H
#define __MPU6050_Hvoid MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data);
uint8_t MPU6050_ReadReg(uint8_t RegAddress);void MPU6050_Init(void);
uint8_t MPU6050_GetID(void);
void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ, int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ);#endif
MPU6050_Reg.h
使用宏定义,将寄存器地址用一个字符串表示
#ifndef __MPU6050_REG_H
#define __MPU6050_REG_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#endif
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "MPU6050.h"uint8_t ID;
int16_t AX, AY, AZ, GX, GY, GZ;int main(void)
{OLED_Init();MPU6050_Init();OLED_ShowString(1, 1, "ID:");ID = MPU6050_GetID();OLED_ShowHexNum(1, 4, ID, 2);while (1){MPU6050_GetData(&AX, &AY, &AZ, &GX, &GY, &GZ);//参数指针,指向各个寄存器地址OLED_ShowSignedNum(2, 1, AX, 5);OLED_ShowSignedNum(3, 1, AY, 5);OLED_ShowSignedNum(4, 1, AZ, 5);OLED_ShowSignedNum(2, 8, GX, 5);OLED_ShowSignedNum(3, 8, GY, 5);OLED_ShowSignedNum(4, 8, GZ, 5);}
}
十四、硬件I2C读写MPU6050
STM32——I2C外设总线
参考视频:江科大自化协
STM32——I2C通信相关推荐
- STM32——stm32 I2C通信代码配置(2)(学习笔记)
STM32--I2C通信配置 I2C的系统框架 1.通讯引脚 2.时钟控制逻辑 3.数据控制逻辑 4.整体控制逻辑 通信过程 写入过程 读取过程 I2C代码配置 I2C的初始化结构体 几个重要的函数 ...
- STM32 I2C通信(读写eeprom)
I2C通信 双线制:串行时钟线SCL,串行数据线SDA. 通常采用软件模拟i2c通信.
- STM32 I2C通信操作24C02写数据、读数据
202007每月一练 的板子上还有一个24C02芯片没有写教程,今天介绍一下24C02这个芯片的驱动方法. 串行EEPROM 24CXX是基于I2C总线的存储器件,遵循二线制协议,IIC总线上可以外挂 ...
- STM32应用(七)JY901九轴姿态模块(串口DMA空闲中断和I2C通信)
文章目录 0.相关基础知识介绍 0.1六轴.九轴传感器有什么区别? 1.JY901模块简介 1.1 产品概述 1.2 性能参数 1.3 实物图和接线 2.软件和使用说明书 3.串口通信JY901 3. ...
- STM32的I2C通信
STM32的两个GPIO引脚,分别用于SCL和SDA,按照I2C规约的时序,像控制LED灯那样控制引脚输出,若是接收数据时则读取SDA线上的电平,那就可以实现I2C通信了,这也是我们在51单片机上 ...
- linux stm32 主从,STM32F407和STM32F051主从I2C通信方法
STM32F407和STM32F051主从I2C通信方法 作者:华清远见讲师 M4作为主机: int main(void) { HAL_Init(); SystemClock_Config(); MX ...
- 基于STM32的I2C通信 2(读写AT24C02)
本文采用STM32的模拟I2C对 EEPROM(AT24C02)进行读写操作. 1.EEPROM(24C02):I2C接口 1.1-24C02器件介绍: AT24C02的总容量是256个字节,也就是2 ...
- i2c hid 触摸板不能用_I2C 总线协议初探 - STM32 I2C 接口外设学习笔记
I2C(Inter-Integrated Circuit)总线是由 PHILIPS(飞利浦) 公司开发的两线式串行总线,用于连接微控制器及其外围设备.是微电子通信控制领域广泛采用的一种总线标准.它是同 ...
- STM32——I2C
STM32--I2C 宗旨:技术的学习是有限的,分享的精神是无限的. 一.I2C协议 I 2 C (Inter-Integrated Circuit)协议是由 Philips 公司开发的,由于它具备引 ...
最新文章
- 自动驾驶汽车“定位”技术
- ora-12545连接错误解决一例
- python运行程序-Python程序的执行过程
- class-5 If语句
- Redis集群功能概述
- simulink中s-function使用
- druid报异常 “sql injection violation, part alway true condition not allow”的解决方案
- 软考信息系统项目管理师_信息系统综合测试与管理---软考高级之信息系统项目管理师027
- CStdioFile读写文件的问题
- php报503怎么排查,php监控日志500、503错误并发送邮件提示的代码
- matlab2c使用c++实现matlab函数系列教程-abs函数
- 本地环境测试二级域名
- pcb 理论阻值、 过孔_PCB设计中过孔常用的处理方式
- Scratch跑酷游戏
- app做好后如何上线_自己开发一个APP,如何上线
- 网络正常且开启了代理Chrome不能正常上网的解决方法
- 云更新网吧系统服务器,云更新网吧无盘
- 【MySQL学习】数据库问题及着重点汇总
- 鼠标画上去图片旋转360度
- 多网卡环境下(数据网卡+有线网卡)下广播失败问题