江协科技STM32学习- P35 硬件I2C读写MPU6050

        🚀write in front🚀  
🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​ 

💬本系列哔哩哔哩江科大STM32的视频为主以及自己的总结梳理📚 

🚀Projeet source code🚀   

💾工程代码放在了本人的Gitee仓库:iPickCan (iPickCan) - Gitee.com

引用:

STM32入门教程-2023版 细致讲解 中文字幕_哔哩哔哩_bilibili

Keil5 MDK版 下载与安装教程(STM32单片机编程软件)_mdk528-CSDN博客

STM32之Keil5 MDK的安装与下载_keil5下载程序到单片机stm32-CSDN博客

0. 江协科技/江科大-STM32入门教程-各章节详细笔记-查阅传送门-STM32标准库开发_江协科技stm32笔记-CSDN博客

【STM32】江科大STM32学习笔记汇总(已完结)_stm32江科大笔记-CSDN博客

江科大STM32学习笔记(上)_stm32博客-CSDN博客

STM32学习笔记一(基于标准库学习)_电平输出推免-CSDN博客

STM32 MCU学习资源-CSDN博客

stm32学习笔记-作者: Vera工程师养成记

stem32江科大自学笔记-CSDN博客

术语:

英文缩写描述
GPIO:General Purpose Input Onuput通用输入输出
AFIO:Alternate Function Input Output复用输入输出
AO:Analog Output模拟输出
DO:Digital Output数字输出
内部时钟源 CK_INT:Clock Internal内部时钟源
外部时钟源 ETR:External Trigger 时钟源 External 触发
外部时钟源 ETR:External Trigger mode 1外部时钟源 External 触发 时钟模式1
外部时钟源 ETR:External Trigger mode 2外部时钟源 External 触发 时钟模式2
外部时钟源 ITRx:Internal Trigger inputs外部时钟源,ITRx (Internal trigger inputs)内部触发输入
外部时钟源 TIx:exTernal Input pin 外部时钟源 TIx (external input pin)外部输入引脚
CCR:Capture/Comapre Register捕获/比较寄存器
OC:Output Compare输出比较
IC:Input Capture输入捕获
TI1FP1:TI1 Filter Polarity 1Extern Input 1 Filter Polarity 1,外部输入1滤波极性1
TI1FP2:TI1 Filter Polarity 2Extern Input 1 Filter Polarity 2,外部输入1滤波极性2
DMA:Direct Memory Access直接存储器存取

正文:

0. 概述

从 2024/06/12 定下计划开始学习下江协科技STM32课程,接下来将会按照哔站上江协科技STM32的教学视频来学习入门STM32 开发,本文是视频教程 P2 STM32简介一讲的笔记。

1.🚚I2C硬件库函数

stm32中I2C库函数介绍(stm32f10x_i2c.h) 

下面这些是关于I2C的库函数,这里我会挑选最常见的以及本期要用到的来去进行详细讲解。

1.初始化

在学过前面这么多结构体初始化的函数,对于结构体的初始化我们已经再属性不过了,下面是I2C外设的结构体初始化的函数。

void I2C_DeInit(I2C_TypeDef* I2Cx);
void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct);
void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct);

一般情况我们都是自己去定义配置结构体再初始化的,下面我们看一个定义好结构体初始化的示例:

I2C_InitTypeDef I2C_initstruct;I2C_initstruct.I2C_Mode = I2C_Mode_I2C; //选择模式,这里选定使用I2C模式I2C_initstruct.I2C_ClockSpeed = 100000; //选择时钟的频率,不得大于400kHzI2C_initstruct.I2C_DutyCycle = I2C_DutyCycle_2;//占空比选择,低电平:高电平,如果当前是标准速度的话,这个是没用的的,如果在快速时钟的时候,这个才会起作用I2C_initstruct.I2C_Ack = I2C_Ack_Enable; //选择是否给应答I2C_initstruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//stm32作为从机的时候的响应地址位数I2C_initstruct.I2C_OwnAddress1 = 0x01;   //stm32作为从机的时候地址,我们这里是主机,所以这里随便设一个就行了I2C_Init(I2C2, &I2C_initstruct);
2.使能操作

我们本期不需要用DMA到使能,所以这里就不过多讲解。

void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
3.生成起始位和结束位标志
void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState);
void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState);

手册解释如下:

4.发送I2C从机地址

下面这个函数其实就是前面学习软件I2C的“点名”操作,硬件也是一样的,同样都是需要进行点名指定的I2C从机来进行通讯。如果有多个从机,主机会执行下面这个函数后会给每一个从机发送Address的数据,然后从机接收到了后就对比自己的IP数据,如果一样的话那么就开始跟主机通讯,其他从机保持沉默。

void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction);

5.发送数据和接收数据

下面这个是发送数据:

void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data);

下面可以看到把数据放入到数据寄存器DR的操作后,然后剩下就是进入到发送数据的流程。 

下面这个是接受数据:

uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx);

我们可以看到这个函数的返回值是DR寄存器里面的数据。 

6.发送应答位

下面这个函数是用来发送应答位的,当主机接收到了数据之后会向从机发送应答情况,如果应答位是ENABLE表示接收完成返回一个应答反之就是无应答返回 ,手册解释如下

void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState);

7.状态检测

下面这个函数是用来检测每次操作一个步骤之后的状态的,比如发送了一个字节后的数据,然后就会进入一个EVx的状态,这里就需要去执行这个状态是否完成,然后再执行下一步,这是一种缓冲机制以保证数据收发的准确性。在上一期我们也是详细讲解过了这个过程了的。

ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT);

下面是这个函数的相关参数: 

2.🚚硬件I2C读取MPU6050

实验现象如下,其实跟前面软件I2C读取MPU6050现象是一样的,只是方法不同。(软件I2C读取MPU6050链接:stm32入门-----软件I2C读写MPU6050-CSDN博客)

1.电路连线图

查STM32F102T8C6引脚定义表,看到I2C1 PB6, PB7引脚已经给 OLED液晶显示屏使用,本节我们使用I2C2的PB10,PB11引脚。

2.主要工程文件 
主要工程文件如下,这里我们就没有像软件那部分一样需要建立一个MyI2C的文件来去执行收发数据的底层,这里我们是使用硬件外设配置库函数来去实现I2C通讯的,底层是由硬件来自动执行的,所以就不需要MyI2C这个文件了。

其中MPU6050.c文件是用来配置I2C外设以及MPU6050相关模块的文件,MPU6050_reg.h文件是存放MPU6050相关寄存器数据的文件

 MPU6050_reg.h文件数据如下:

#ifndef __MP6050_REG_H__
#define __MP6050_REG_H__#define MP6050_SMPLRT_DIV		0x19
#define MP6050_CONFIG			0x1A
#define MP6050_GYRO_CONFIG		0x1B
#define MP6050_ACCEL_CONFIG		0x1C#define MP6050_ACCEL_XOUT_H		0x3B
#define MP6050_ACCEL_XOUT_L		0x3C
#define MP6050_ACCEL_YOUT_H		0x3D	
#define MP6050_ACCEL_YOUT_L		0x3E
#define MP6050_ACCEL_ZOUT_H		0x3F
#define MP6050_ACCEL_ZOUT_L		0x40
#define MP6050_TEMP_OUT_H		0x41
#define MP6050_TEMP_OUT_L		0x42
#define MP6050_GYRO_XOUT_H		0x43
#define MP6050_GYRO_XOUT_L		0x44
#define MP6050_GYRO_YOUT_H		0x45
#define MP6050_GYRO_YOUT_L		0x46
#define MP6050_GYRO_ZOUT_H		0x47
#define MP6050_GYRO_ZOUT_L		0x48#define MP6050_PWM_MGMT_1		0x6B
#define MP6050_PWM_MGMT_2		0x6C
#define MP6050_WHO_AM_I			0x75
#endif

这里我们主要去讲解MPU6050.c这个文件里面的内容,这个是配置I2C外设的主要文件。

3.MPU6050.c代码剖析
(1)检测步骤超时操作

在进入到检测状态的函数的时候,难免会出现意外超时的情况,这里我们就需要去对这个bug进行处理,比如如果超时的情况就放弃这个字节读取或写入的操作。

//检测事件后的超时操作
void MPU6050_WaitEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT) {uint32_t time_out = 100000;while (I2C_CheckEvent(I2Cx, I2C_EVENT) != SUCCESS) {time_out--;if (!time_out) {break;} }
}
(2)指定地址写

代码是对应下面这个序列图进行写的,序列图跟代码的步骤是一样的,我们这里使用的是7位。

void MP6050_WriteReg(uint8_t RegAddr, uint8_t data)
{//起始条件I2C_GenerateSTART(I2C2, ENABLE);	//产生Start起始位while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS);	//等待EV5事件//发送I2C从机地址I2C_Send7bitAddress(I2C2, MP6050_I2CADDR, I2C_Direction_Transmitter);while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != SUCCESS); //等待EV6事件//发送寄存器地址I2C_SendData(I2C2, RegAddr);while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING) != SUCCESS); //等待EV8事件//发送数据I2C_SendData(I2C2, data);while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING) != SUCCESS); //等待EV8事件//发送停止位while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS); //等待EV8_2事件I2C_GenerateSTOP(I2C2, ENABLE);
}
(3)指定地址读

uint8_t MP6050_ReadReg(uint8_t RegAddr)
{uint8_t data = 0;//起始条件I2C_GenerateSTART(I2C2, ENABLE);	//产生Start起始位while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS);	//等待EV5事件//发送I2C从机地址I2C_Send7bitAddress(I2C2, MP6050_I2CADDR, I2C_Direction_Transmitter);while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != SUCCESS); //等待EV6事件//发送寄存器地址//这里需要等待EV8_2事件等待数据传输完成,TRANSMITTED 而不是 TRANSMITTING 正在传输I2C_SendData(I2C2, RegAddr);while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS); //等待EV8_2事件//重复起始条件I2C_GenerateSTART(I2C2, ENABLE);	//产生Start起始位while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS);	//等待EV5事件//发送I2C从机地址I2C_Send7bitAddress(I2C2, MP6050_I2CADDR, I2C_Direction_Receiver);while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) != SUCCESS); //等待EV6事件//只接收一个字节必须在EV6事件之后清除ACK位和应答位I2C_AcknowledgeConfig(I2C2, DISABLE);	//设置NACK非应答位I2C_GenerateSTOP(I2C2, ENABLE);			//停止条件//接收数据while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED) != SUCCESS); //等待EV7事件data = I2C_ReceiveData(I2C2);//回复默认的ACK=1,方便连续接收I2C_AcknowledgeConfig(I2C2, ENABLE);return data;
}
(4)初始化配置
(5)获取MPU6050寄存器数据
4.主函数代码

这部分其实跟软件I2C读写MPU6050的是一样的。

MP6050.c

#include "stm32f10x.h"                  // Device header
#include "MP6050.h"
#include "MyI2C.h"
#include "Delay.h"
#include "MP6050_Reg.h"
#include "OLED.h"#define MP6050_I2CADDR 		(0x68 << 1)
#define MP6050_I2CRead_DIR	0x01
#define MP6050_I2CWrit_DIR	0x00void MP6050_Init(void)
{//使能RCC外设时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//配置GPIOGPIO_InitTypeDef gpioInitStructure;gpioInitStructure.GPIO_Mode = GPIO_Mode_AF_OD;			//复用开漏输出模式gpioInitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;	//使用GPIOB_Pin10, Pin11gpioInitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &gpioInitStructure);//配置I2C外设I2C_InitTypeDef I2C_InitStruct;I2C_StructInit(&I2C_InitStruct);I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;				//I2C工作方式I2C_InitStruct.I2C_ClockSpeed = 100*1000;			//I2C时钟频率,不超过400KHzI2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_16_9;	//I2C时钟占空比I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;			//I2C应答I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;	//I2C从机7位模式I2C_InitStruct.I2C_OwnAddress1 = 0x01;				//I2C从机模式使用,自身地址寄存器I2C_Init(I2C2, &I2C_InitStruct);//使能I2C外设I2C_Cmd(I2C2, ENABLE);MP6050_WriteReg(MP6050_PWM_MGMT_1, 0x01);	//关闭MP6050睡眠模式,采样时钟选择内部GyroX轴时钟MP6050_WriteReg(MP6050_PWM_MGMT_2, 0x00);	//MP6050 6轴都使能,不使用Wakeup模式MP6050_WriteReg(MP6050_SMPLRT_DIV, 0x09);	//MP6050采样分频值10分频,实际采样频率=时钟频率/(分频值+1)MP6050_WriteReg(MP6050_CONFIG, 0x06);		//MP6050不使用FSYNC,DLPF数字低通滤波器选择6最平滑滤波MP6050_WriteReg(MP6050_GYRO_CONFIG, 0x18);	//陀螺仪量程选择最大量程MP6050_WriteReg(MP6050_ACCEL_CONFIG, 0x18);	//加速度计量程选择最大量程,不使用高通滤波MP6050_ReadReg(MP6050_WHO_AM_I);}void MP6050_WriteReg(uint8_t RegAddr, uint8_t data)
{//起始条件I2C_GenerateSTART(I2C2, ENABLE);	//产生Start起始位while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS);	//等待EV5事件//发送I2C从机地址I2C_Send7bitAddress(I2C2, MP6050_I2CADDR, I2C_Direction_Transmitter);while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != SUCCESS); //等待EV6事件//发送寄存器地址I2C_SendData(I2C2, RegAddr);while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING) != SUCCESS); //等待EV8事件//发送数据I2C_SendData(I2C2, data);while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING) != SUCCESS); //等待EV8事件//发送停止位while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS); //等待EV8_2事件I2C_GenerateSTOP(I2C2, ENABLE);
}uint8_t MP6050_ReadReg(uint8_t RegAddr)
{uint8_t data = 0;//起始条件I2C_GenerateSTART(I2C2, ENABLE);	//产生Start起始位while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS);	//等待EV5事件//发送I2C从机地址I2C_Send7bitAddress(I2C2, MP6050_I2CADDR, I2C_Direction_Transmitter);while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != SUCCESS); //等待EV6事件//发送寄存器地址//这里需要等待EV8_2事件等待数据传输完成,TRANSMITTED 而不是 TRANSMITTING 正在传输I2C_SendData(I2C2, RegAddr);while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS); //等待EV8_2事件//重复起始条件I2C_GenerateSTART(I2C2, ENABLE);	//产生Start起始位while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS);	//等待EV5事件//发送I2C从机地址I2C_Send7bitAddress(I2C2, MP6050_I2CADDR, I2C_Direction_Receiver);while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) != SUCCESS); //等待EV6事件//只接收一个字节必须在EV6事件之后清除ACK位和应答位I2C_AcknowledgeConfig(I2C2, DISABLE);	//设置NACK非应答位I2C_GenerateSTOP(I2C2, ENABLE);			//停止条件//接收数据while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED) != SUCCESS); //等待EV7事件data = I2C_ReceiveData(I2C2);//回复默认的ACK=1,方便连续接收I2C_AcknowledgeConfig(I2C2, ENABLE);return data;
}void MP6050_GetData(struct MP6050_Data_ParaOut *MP6050ParaOut)
{uint8_t Data_H = 0;uint8_t Data_L = 0;Data_H = MP6050_ReadReg(MP6050_ACCEL_XOUT_H);Data_L = MP6050_ReadReg(MP6050_ACCEL_XOUT_L);MP6050ParaOut->AccelX = (Data_H << 8) | Data_L;		//MP6050加速度计X轴Data_H = MP6050_ReadReg(MP6050_ACCEL_YOUT_H);Data_L = MP6050_ReadReg(MP6050_ACCEL_YOUT_L);MP6050ParaOut->AccelY = (Data_H << 8) | Data_L;		//MP6050加速度计Y轴Data_H = MP6050_ReadReg(MP6050_ACCEL_ZOUT_H);Data_L = MP6050_ReadReg(MP6050_ACCEL_ZOUT_L);MP6050ParaOut->AccelZ = (Data_H << 8) | Data_L;		//MP6050加速度计Z轴Data_H = MP6050_ReadReg(MP6050_GYRO_XOUT_H);Data_L = MP6050_ReadReg(MP6050_GYRO_XOUT_L);MP6050ParaOut->GyroX = (Data_H << 8) | Data_L;		//MP6050角速度计X轴Data_H = MP6050_ReadReg(MP6050_GYRO_YOUT_H);Data_L = MP6050_ReadReg(MP6050_GYRO_YOUT_L);MP6050ParaOut->GyroY = (Data_H << 8) | Data_L;		//MP6050角速度计X轴Data_H = MP6050_ReadReg(MP6050_GYRO_ZOUT_H);Data_L = MP6050_ReadReg(MP6050_GYRO_ZOUT_L);MP6050ParaOut->GyroZ = (Data_H << 8) | Data_L;		//MP6050角速度计X轴
}

Main.c

#include "stm32f10x.h"                  // Device header
#include "oled.h"
#include "Countersensor.h"
#include "Encoder.h"
#include "Timer.h"
#include "AD.h"
#include "Delay.h"
#include "MyDMA.h"
#include "UART.h"
#include <stdio.h>
#include "Key.h"
#include "String.h"
#include "LED.h"
#include "MyI2C.h"
#include "MP6050.h"
#include "MP6050_Reg.h"#define MP6050_REG_ID		0x75
#define MP6050_REG_PWRMNG2	0x6B
#define MP6050_REG_SIMPDIV	0x19int main(int argc, char *argv[])
{uint8_t AckBit = 0;uint8_t MP6050Id;uint8_t RegVal = 0;struct MP6050_Data_ParaOut MP6050Data = {0};OLED_Init();MP6050_Init();while(1)                                                                                 {MP6050_GetData(&MP6050Data);OLED_ShowSignedNum(1, 1, MP6050Data.AccelX ,5);OLED_ShowSignedNum(1, 8, MP6050Data.AccelY ,5);OLED_ShowSignedNum(2, 1, MP6050Data.AccelZ ,5);OLED_ShowSignedNum(3, 1, MP6050Data.GyroX ,5);OLED_ShowSignedNum(3, 8, MP6050Data.GyroY ,5);OLED_ShowSignedNum(4, 1, MP6050Data.GyroZ ,5);Delay_ms(100);}return 1;
}

实验结果:

使用淘宝购买的19块钱的24MHz 8通过逻辑分析仪抓取下硬件I2C读取时的通信时序。

可以看到硬件I2C的时序,SCLK时钟特别规整,SDA的变化也紧跟着SCK的下降沿。

3🚚实验问题记录和经验分享

本节硬件I2C实验遇到了一个问题,就是I2C_ReceiveData()读取出来的数据总是固定的值 '0xD',反复排查才发现是因为在读取I2C DR接收寄存器之前没有等待EV7事件。如果不等待EV7事件就直接读取I2C DR寄存器,根据STM32的主接收时序此时DR寄存器的值还是上一次的值,I2C数据还没有开始接收,所以此时立即读I2C DR寄存器就总是读取到的上一次值。

正确的做法是,接收时先等待EV7事件确认I2C 已经接收到数据,再读取I2C DR寄存器,此时读取到的才是正确的接收数据。

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

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

相关文章

39页PDF | 华为数据架构建设交流材料(限免下载)

一、前言 这份报告是关于企业数据架构建设的交流材料&#xff0c;详细介绍了数据架构在企业架构中的重要性&#xff0c;阐述了数据架构的定义、包含的四个核心组件&#xff08;数据资产目录、数据标准、数据模型和数据分布&#xff09;&#xff0c;并通过交通和城市政务服务的…

三周精通FastAPI:27 使用使用SQLModel操作SQL (关系型) 数据库

官网文档&#xff1a;https://fastapi.tiangolo.com/zh/tutorial/sql-databases/ SQL (关系型) 数据库 FastAPI不需要你使用SQL(关系型)数据库。 但是您可以使用任何您想要的关系型数据库。 这里我们将看到一个使用SQLModel的示例。 SQLModel是在SQLAlchemy和Pydantic的基础…

专业140+总分430+四川大学854信号与系统考研川大原951电子信息与通信工程,真题,大纲,参考书。

川大854(原951)信号与系统140&#xff0c;总分430&#xff0c;顺利上岸&#xff0c;目前已经研究生在读&#xff0c;群里不少同学希望分享一下我的考研经历&#xff0c;回首考研这一年的复习经历&#xff0c;历历在目&#xff0c;好像就在昨天&#xff0c;期间有过迷惑&#xf…

蓝桥杯第21场小白入门赛补题

5.蓝桥派对 思路 &#xff1a;一个区间与多少个其他区间有关联&#xff0c;先对所有区间左端点和右端点从小到大排序&#xff0c;对于每个询问&#xff0c;我们先算出[1,r]这个区间里有多少个区间的起点即区间总数&#xff0c;使用upper_bound函数&#xff0c;然后使用lower_bo…

【再谈设计模式】原型模式~复制的魔法师

一、引言 在软件工程、软件开发中&#xff0c;创建对象的过程常常涉及复杂的初始化和配置。在某些情况下&#xff0c;直接复制现有对象比从头开始创建新对象更为高效。原型模式&#xff08;Prototype Pattern&#xff09;是一种创建型设计模式&#xff0c;允许我们通过复制现有…

技术分享 —— JMeter接口与性能测试实战!

前言 在软件开发和运维过程中&#xff0c;接口性能测试是一项至关重要的工作。JMeter作为一款开源的Java应用&#xff0c;被广泛用于进行各种性能测试&#xff0c;包括接口性能测试。本文将详细介绍如何使用JMeter进行接口性能测试的过程和步骤。 JMeter是Apache组织开发的基…

Data+AI━━数据安全的警钟:智能化分类分级治理

DataAI━━数据安全的警钟&#xff1a;智能化分类分级治理 前言数据的分类体系数据分级与智能化实践深度案例解析与未来展望 前言 OpenAI数据泄露事件让数据安全再次成为科技圈的热门话题。2024年3月,一名研究员发现OpenAI的API存在安全漏洞,导致部分用户的对话记录泄露。 这一…

【K8S问题系列】Kubernetes Pod节点CrashLoopBackOff 状态【已解决】

在 Kubernetes 中&#xff0c;Pod 的状态为 CrashLoopBackOff 表示某个容器在启动后崩溃&#xff0c;Kubernetes 尝试重启该容器&#xff0c;但由于持续崩溃&#xff0c;重启的间隔时间逐渐增加。下面将详细介绍 CrashLoopBackOff 状态的原因、解决方案及相关命令的输出解释。 …

图像信号处理器(ISP,Image Signal Processor)详解

简介&#xff1a;个人学习分享&#xff0c;如有错误&#xff0c;欢迎批评指正。 图像信号处理器&#xff08;ISP&#xff0c;Image Signal Processor&#xff09; 是专门用于处理图像信号的硬件或处理单元&#xff0c;广泛应用于图像传感器&#xff08;如 CMOS 或 CCD 传感器&a…

u盘怎么重装电脑系统_u盘重装电脑系统步骤和详细教程【新手宝典】

u盘怎么重装电脑系统&#xff1f;一个u盘怎么重装电脑系统呢&#xff0c;需要将u盘制作成u盘启动盘pe&#xff0c;然后通过U盘启动盘进入pe进行安装系统&#xff0c;下面小编就教大家u盘重装电脑系统步骤和详细教程。 u盘启动是什么意思&#xff1f; U盘启动盘是一种具有特殊功…

SpringBoot健身房管理:技术与实践

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

Sigrity Power SI 3D-EM Inductance Extraction模式如何进行电感的提取操作指导(一)

Sigrity Power SI 3D-EM Inductance Extraction模式如何进行电感的提取操作指导(一) Sigrity Power SI使用3D-EM Inductance Extraction模式可以进行电感的提取,以下图为例 2D 视图 <

Fsm serialdata

现在您有了一个有限状态机&#xff0c;可以识别串行比特流中何时正确接收字节&#xff0c;添加一个数据路径&#xff0c;输出正确接收的数据字节。当done为1时&#xff0c;out_byte必须有效&#xff0c;否则为not。 请注意&#xff0c;串行协议首先发送最低有效位。 此题&#…

【GESP】C++一级真题练习(202309)luogu-B3863,买文具

GESP一级真题练习。为2023年9月一级认证真题。属于数值计算条件判断的问题。 题目题解详见&#xff1a;https://www.coderli.com/gesp-1-luogu-b3863/ 【GESP】C一级真题练习(202309)luogu-B3863&#xff0c;买文具 | OneCoderGESP一级真题练习。为2023年9月一级认证真题。属…

《Python游戏编程入门》注-第5章4

2.3 随机改变颜色 从图1中可以看出,当完全显示了一个大圆之后,会改变颜色继续显示该大圆。也就是当圆心角angle的值大于等于360度时,随机改变颜色,代码如图6所示。 图6 随机改变颜色的代码 其中,第18行代码判断是否完全显示了一个大圆,如果是,圆心角的角度设置为0,第…

健康生活,注重养生

在快节奏的现代生活中&#xff0c;健康养生已成为我们不可忽视的重要课题。它不仅仅关乎身体的强健&#xff0c;更涉及到心灵的平和与愉悦。以下是一些实用的健康养生建议&#xff0c;帮助我们在日常生活中&#xff0c;以自然和谐的方式&#xff0c;滋养身心&#xff0c;享受生…

气膜体育馆:高效便捷的现代运动新选择—轻空间

随着城市发展和人们健康意识的提高&#xff0c;体育场馆的需求日益增加。然而&#xff0c;传统体育馆的建设周期长、成本高和多功能性有限&#xff0c;往往无法满足快速发展的城市需求。那么&#xff0c;为什么选择气膜体育馆作为您的场馆建设方案呢&#xff1f;今天&#xff0…

SSLHandshakeException错误解决方案

1、错误提示 调用Http工具报如下异常信息&#xff1a; cn.hutool.core.io.IORuntimeException: SSLHandshakeException: Received fatal alert: handshake_failure2、查询问题 一开始我以为是代码bug&#xff0c;网络bug甚至是配置环境未生效&#xff0c;找了一大圈&#xf…

第十八周:机器学习

目录 摘要 abstract 一、BERT 1、应用场景 任务一&#xff1a;单句子分类任务 任务二&#xff1a;单句子标注任务 任务三&#xff1a;句子对分类任务 任务四&#xff1a;问答系统 2、pre-train model 3、fine tune微调 input&output how to fine tune 二、…

从0开始搭建一个生产级SpringBoot2.0.X项目(十二)SpringBoot接口SpringSecurity JWT鉴权

前言 最近有个想法想整理一个内容比较完整springboot项目初始化Demo。 SpringBoot接口权限控制 SpringSecurity 接口使用 Bearer token类型 JWT 鉴权 一、pom文件新增依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>s…