stm32入门-----硬件I2C读写MPU6050

news2024/10/1 9:42:01

 目录

前言

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

1.初始化

2.使能操作

3.生成起始位和结束位标志

4.发送I2C从机地址

5.发送数据和接收数据

6.发送应答位

7.状态检测

二、硬件I2C读取MPU6050

1.电路连线图

2.主要工程文件 

3.MPU6050.c代码剖析

(1)检测步骤超时操作

(2)指定地址写

(3)指定地址读

(4)初始化配置

(5)获取MPU6050寄存器数据

4.主函数代码


前言

        上一期讲了硬件I2C的相关基本内容(链接stm32入门-----硬件I2C外设-CSDN博客),本期我们就来学习硬件I2C读写MPU6050的项目实操,在前面我们试过了用软件I2C来去读写MPU6050的操作,这里我们可以去对比看看硬件跟软件操作上有什么不同以及硬件上又有哪方面比软件要强。(视频:STM32入门教程-2023版 细致讲解 中文字幕_哔哩哔哩_bilibili)

本期项目代码我已上传至百度网盘,可自行下载
链接:https://pan.baidu.com/s/1W_2qnkWsUkOBzRjhkJhRVg?pwd=0721 
提取码:0721 

 一、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; //选择时钟的频率,不得大于400kHz
    I2C_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);//I2C使能
void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState); //开启I2C的DMA使能
void I2C_DMALastTransferCmd(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)

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

二、硬件I2C读取MPU6050

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

1.电路连线图

2.主要工程文件 

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

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

 MPU6050_reg.h文件数据如下:

#ifndef __MPU6050_REG_h
#define __MPU6050_REG_h

//这里存放的是MPU6050的寄存器地址
#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 // !__MPU6050_REG_h

这里我们主要去讲解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 MPU6050_writereg(uint8_t regaddress, uint8_t data) {
    
    //开启I2C发送模式
    I2C_GenerateSTART(I2C2, ENABLE);
    MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT);//监测EV5事件,返回值有SUCCESS和ERROR
    //发送地址,点名
    I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter);//I2C_SendData()函数也是用来发送的,不过I2C_Send7bitAddress这个可以选择7位的发送和接收地址位两种模式
    MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);//监测EV6事件,返回值有SUCCESS和ERROR
    //选择寄存器地址
    I2C_SendData(I2C2, regaddress); //选择从机的寄存器地址
    MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING);//监测EV8事件,返回值有SUCCESS和ERROR
    //发送数据
    I2C_SendData(I2C2, data); //选择从机的寄存器地址
    MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED);//监测EV8_2事件表示结束,返回值有SUCCESS和ERROR

    I2C_GenerateSTOP(I2C2, ENABLE);
}
(3)指定地址读

//指定地址读
uint8_t MPU6050_readreg(uint8_t regaddress) {
    uint8_t result;

//这里指定地址
    //开启I2C发送模式
    I2C_GenerateSTART(I2C2, ENABLE);
    MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT);//监测EV5事件,返回值有SUCCESS和ERROR
    //选择发送地址,点名
    I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter);//I2C_Send7bitAddress这个可以选择7位的发送和接收地址位两种模式,选择方向和从机地址
    MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);//监测EV6事件,返回值有SUCCESS和ERROR
    //选择寄存器地址
    I2C_SendData(I2C2, regaddress); //选择从机的寄存器地址
    MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING);//监测EV8事件,返回值有SUCCESS和ERROR

//这里就开始读取这个寄存器的数据
    //重新开启
    I2C_GenerateSTART(I2C2, ENABLE);
    MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT);//监测EV5事件,返回值有SUCCESS和ERROR

    //发送地址,点名
    I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Receiver);//这里选择接收的方向
    MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED);//监测EV6事件,返回值有SUCCESS和ERROR

    //如果是读取多个字节的时候,那读取最后一个字节之前在这里需要去先去给应答置0,提前终止接收stop置1
    //如果读取一个字节的时候,那么要在EV6之后在这里应答ack置0,stop置1
    //这里提前设置的终止stop的时候不会影响数据的收到,回等待最后一个字节数据接收完成之后才去执行终止
    I2C_AcknowledgeConfig(I2C2, DISABLE);
    I2C_GenerateSTOP(I2C2, ENABLE);
    MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED);//监测EV6事件,返回值有SUCCESS和ERROR

    //读取DR
    result = I2C_ReceiveData(I2C2);
    I2C_AcknowledgeConfig(I2C2, ENABLE);
    
    return result;
}
(4)初始化配置
//初始化
void MPU6050_init() {
    // I2C_init();

    //1.开启时钟,GPIO和I2C的时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    // 2.初始化引脚
    GPIO_InitTypeDef GPIO_initstruct;
	GPIO_initstruct.GPIO_Mode=GPIO_Mode_AF_OD; //选择使用复用开漏输出模式 
	GPIO_initstruct.GPIO_Pin=GPIO_Pin_11 | GPIO_Pin_10;
	GPIO_initstruct.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_initstruct);

    // 3.配置初始化I2C外设
    I2C_InitTypeDef I2C_initstruct;
    I2C_initstruct.I2C_Mode = I2C_Mode_I2C; //选择模式,这里选定使用I2C模式
    I2C_initstruct.I2C_ClockSpeed = 100000; //选择时钟的频率,不得大于400kHz
    I2C_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);


    MPU6050_writereg(MPU6050_PWR_MGMT_1, 0x01); //电源管理器1
    MPU6050_writereg(MPU6050_PWR_MGMT_2, 0x00); //电源管理器2
    MPU6050_writereg(MPU6050_SMPLRT_DIV, 0x09); //分频器
    MPU6050_writereg(MPU6050_CONFIG, 0x06); //配置寄存器
    MPU6050_writereg(MPU6050_GYRO_CONFIG, 0x18); //陀螺仪配置寄存器
    MPU6050_writereg(MPU6050_ACCEL_CONFIG, 0x18);//加速度计配置寄存器
}
(5)获取MPU6050寄存器数据
//获取当前的ID号,也就是MPU6050的I2C地址
uint8_t MPU6050_getID() {
    return MPU6050_readreg(MPU6050_WHO_AM_I);
}

//获取MPU6050转换出加速度和角速度的值
void MPU6050_getdata(int16_t* accX, int16_t* accY, int16_t* accZ,
                    int16_t* gyroX, int16_t* gyroY, int16_t* gyroZ)
{
    uint16_t dataH, dataL;
    //加速度值数据
    dataH = MPU6050_readreg(MPU6050_ACCEL_XOUT_H);
    dataL = MPU6050_readreg(MPU6050_ACCEL_XOUT_L);
    *accX = (dataH << 8) | dataL;

    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;
}
    

4.主函数代码

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

#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);
	}
}

以上就是本期的全部内容了,我们下次见!

今日壁纸:

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

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

相关文章

WordPress网站被入侵,劫持收录事件分析

7.15&#xff0c;网站被入侵&#xff0c;但是直到7月17日&#xff0c;我才发现被入侵。 16日&#xff0c;17日正常更新文章&#xff0c;17日查询网站收录数据时&#xff0c;在站长资源平台【流量与关键词】查询上&#xff0c;我发现了比较奇怪的关键词。 乱码关键词排名 起初…

案例分享:如何使用原生的NodeJs下载视频网站上的视频资源到本地生成MP4文件

如何使用原生的NodeJs下载视频网站上的视频资源到本地生成MP4文件 1、当下视频网站的视频资源无法通过常规手段下载的原因2、什么是M3U8是什么视频文件?3、如何下载M3U8文件中的TS文件并在本地合并为MP4文件?3.1 FFmpeg 是什么工具?3.2 安装 FFmpeg 工具3.3 使用 FFmpeg 工具…

每天五分钟深度学习:向量化方式完成逻辑回归模型的参数更新

本文重点 上一节课程中,我们学习了m个样本的前向传播的向量化,我们可以同时完成m个样本的前向传播,也就是m个样本z的计算,然后a的计算。本节课程我们将学习dw和db参数更新的向量化,最终得到整个逻辑回归算法的参数更新的向量化表示。 非向量化的逻辑回归梯度下降算法 如…

学习日志8.4--DHCP攻击防范

目录 DHCP饿死攻击 DHCP Sever仿冒攻击 DHCP攻击防范 DHCP动态主机配置协议&#xff0c;是给主机提供自动获取IP地址等配置信息的服务。在主机对DHCP服务器发送DHCP Discover请求之后&#xff0c;服务器回复offer&#xff0c;主机再回复request&#xff0c;最后服务器回复AC…

uni-app开发打包成H5部署到服务器

1. 点击发行 2. 点击进入manifest.json的h5配置里&#xff0c;根据自己的情况配置一些信息。一定要注意配置 “运行的基础路径”&#xff0c;如果出现空白页面或者静态文件404的情况&#xff0c;可能是因为这个路径没有配置好。 3. 填写域名 4. 点击发行后&#xff0c;控制台后…

如何让左右两个div各占50%,并且高度相同?

如何设置两个div各占一半&#xff0c;并且高度随着内容增加&#xff0c;而且两边div的高度一致呢&#xff1f;默认会发现高度不一致&#xff0c;改用flex就可以了&#xff0c;另外发现传统的table也可以轻易实现。不知道不用flex的话是否可以实现。 方法1&#xff08;div实现&a…

二分+dp,CF 1993D - Med-imize

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 D - Med-imize 二、解题报告 1、思路分析 对于n < k的情况直接排序就行 对于n > k的情况 最终的序列长度一定是 (n - 1) % k 1 这个序列是原数组的一个子序列 对于该序列的第一个元素&#xff0…

Spring中使用Async进行异步功能开发实战-以大文件上传为例

目录 前言 一、场景再现 1、Event的同步机制 二、性能优化 1、异步支持配置 2、自定义处理线程池扩展 3、将线程池配置类绑定到异步方法 三、总结 前言 在之前的博客中&#xff0c;曾将讲了在SpringBoot中如何使用Event来进行大文件上传的解耦&#xff0c;原文地址&…

算法回忆录(2)

6.输入一个非递减排列的整数数组nums,和一个目标值target。请找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值target,则输出0&#xff0c;0。请设计一个时间复杂度为0(log n)的算法解决此问题。 输入包括两行&#xff0c;第一行输入两个整数&#xff0c…

【电路笔记】-偏置晶体管

偏置晶体管 文章目录 偏置晶体管1、概述2、共发射极晶体管偏置3、集极反馈偏置4、双反馈晶体管偏置5、发射极反馈配置6、分压器晶体管偏置晶体管偏置是将晶体管直流工作电压或电流条件设置为正确电平的过程,以便晶体管可以正确放大任何交流输入信号 1、概述 双极晶体管的稳态…

DBA | 炼气期,关系数据库及六大范式(NF)理论概述!

[ 知识是人生的灯塔&#xff0c;只有不断学习&#xff0c;才能照亮前行的道路 ] 前言简述 描述&#xff1a;上一章&#xff0c;我们简单了解了关系类型数据库&#xff0c;以及其相关产品&#xff0c;此章节我们由浅入深的学习一下什么是关系型数据库&#xff0c;不过在讲解关系…

中国县城建设统计年鉴(2015-2022年)

数据年限&#xff1a;2015-2022年&#xff0c;年鉴时间即为数据时间 数据格式&#xff1a;pdfexcel 数据内容&#xff1a; 共分12个部分&#xff0c; 包括县城市政公用设施水平&#xff08;人口密度/人均日生活用水量/供水普及率/燃气普及率/人均道路面积/建成区路网密度/污水处…

51单片机—电动车报警器

一. 入门 1.1 开发环境的安装 用什么写代码--语言是C&#xff0c;环境是keilKeil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统&#xff0c;与汇编相比&#xff0c;C语言在功能上、结构性、可读性、可维护性上有明显的优势&#xff0c;因而易学易用。…

江协科技51单片机学习- p37 红外遥控(外部中断)

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

提供三方API接口、调用第三方接口API接口、模拟API接口(三)使用AOP切面编程实现signature签名验证

接着第一篇文章 提供三方API接口、调用第三方接口API接口、模拟API接口&#xff08;一&#xff09;通过signature签名验证&#xff0c;避免参数恶意修改 我们来继续优化&#xff1a; /*** 模拟后端校验签名* param request* param data* return* throws UnsupportedEncodingEx…

[环境配置]C4D OC渲染器解决缺少cudnn_8_0_4Octance正版缺少cudnn_8_0_4_win文件解决方法

关于Octance正版缺少cudnn_8_0_4_win文件解决方法 可在此处https://download.csdn.net/download/FL1623863129/89605383进行下载 放到对应文件位置即可 在计算机图形学领域&#xff0c;Cinema 4D&#xff08;C4D&#xff09;作为一款顶尖的专业3D建模、动画与渲染软件&#x…

学生管理系统之数据模拟与数据显示

学生管理系统之数据模拟与数据显示 设计一个单例 模拟数据 显示数据

CSP-J 2022 填程题19.解析

19. &#xff08;枚举因数&#xff09;从小到大打印正整数 n 的所有正因数。 试补全枚举程序。 01 #include <bits/stdc.h> 02 using namespace std; 03 04 int main() { 05 int n; 06 cin >> n; 07 08 vector<int> fac; 09 fac.reserve((int)ce…

【算法】动态规划---多态dp问题

多态dp问题 一.[leetcode] (打家劫舍I) 17.16.按摩师二. [leetcode] 213. 打家劫舍 II三.[leetcode] 740. 删除并获得点数四.[leetcode] LCR 091. 粉刷房子五.[leetcode] 309. 买卖股票的最佳时机含冷冻期六.[leetcode] 714. 买卖股票的最佳时机含手续费七.[leetcode] 123. 买卖…

职场,要想逆袭,必须要“装”

普通人&#xff0c;没有家庭背景&#xff0c;没有社会资源&#xff0c;没有好学历&#xff0c;如何才能逆袭呢&#xff1f;有朝一日自己熬出头&#xff0c;又如何避免被别人针对呢&#xff1f; 最重要的就是要会“装”。 在社会上&#xff0c;只有资源多的人才能更好的生存&a…