26、江科大stm32视频学习笔记——I2C读写W25Q64

一、W25Q64简介

1、W25Q64的内存空间结构:  一页256字节,4K(4096 字节)为一个扇区,16个扇区为1块,容量为8M字节,共有128个块,2048 个扇区。  

2、W25Q64每页大小由256字节组成,每页的256字节用一次页编程指令即可完成。

3、擦除指令分别支持: 16页(1个扇区)、128页、256页、全片擦除。 

二、电路图

1、软件模拟的SPI:线可以任意接

2、硬件模拟的SPI:要按以下方式连接

3、本次软件模拟和硬件模拟使用同一个电路图,方便切换

CS(片选):PA4                                   DO(从机输出):PA6

CLK(时钟):PA5                                 DI(从机输入):PA7

三、软件SPI读写W25Q64

1、SPI.c(初始化寄存器,实现读取一个字节的功能)

#include "stm32f10x.h"                  // Device headervoid MySPI_W_SS(uint8_t BitValue)
{GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue);
}void MySPI_W_SCK(uint8_t BitValue)
{GPIO_WriteBit(GPIOA, GPIO_Pin_5, (BitAction)BitValue);
}void MySPI_W_MOSI(uint8_t BitValue)
{GPIO_WriteBit(GPIOA, GPIO_Pin_7, (BitAction)BitValue);
}uint8_t MySPI_R_MISO(void)
{return GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6);
}void MySPI_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7;  //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;                            //上拉输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);MySPI_W_SS(1);      //SS默认高电平(下降沿为开始工作,低电平状态为工作中,上升沿为结束工作)MySPI_W_SCK(0);     //SCK默认为低电平(上升沿移入数据,下降沿移出数据)
}void MySPI_Start(void)
{MySPI_W_SS(0);
}void MySPI_Stop(void)
{MySPI_W_SS(1);
}//模式0
uint8_t MySPI_SwapByte(uint8_t ByteSend)
{uint8_t i, ByteReceive = 0x00;for (i = 0; i < 8; i ++){//先SS下降沿,移出数据,SCK上升沿,移入数据,再SCK下降沿,移出数据,下面只管主机,MySPI_W_MOSI(ByteSend & (0x80 >> i));   //将数据移出到MOSI线MySPI_W_SCK(1);                         //上升沿移入数据//当MISO为1时,置变量指定位为1,当MISO为0时,不做处理,指定位为默认的初值0if (MySPI_R_MISO() == 1){ByteReceive |= (0x80 >> i);}  //将移入的数据读取出来MySPI_W_SCK(0);                         //下降沿移出数据}return ByteReceive;                         //读取出来的数据
}
/*1、for循环的优化MySPI_W_MOSI(ByteSend & 0x80 );   //将数据移出到MOSI线ByteSend << 1;                    //将数据左移动1位,去掉最高位,最低位置0MySPI_W_SCK(1);                         //上升沿移入数据if (MySPI_R_MISO() == 1){ByteSend |= 0x01;}  //将移入的数据读取出来,如果是0不管,如果是1,将最低位置1MySPI_W_SCK(0);                         //下降沿移出数据2、模式1MySPI_W_SCK(1);                         //上升沿移出来数据MySPI_W_MOSI(ByteSend & (0x80 >> i));   //将数据移出到MOSI线MySPI_W_SCK(0);                         //下降沿移入数据if (MySPI_R_MISO() == 1){ByteReceive |= (0x80 >> i);}  //将移入的数据读取出来
*/

2、W25Q64.c

#include "stm32f10x.h"                  // Device header
#include "MySPI.h"
#include "W25Q64_Ins.h"/*** 函    数:W25Q64初始化* 参    数:无* 返 回 值:无*/
void W25Q64_Init(void)
{MySPI_Init();					//先初始化底层的SPI
}/*** 函    数:MPU6050读取ID号* 参    数:MID 工厂ID,使用输出参数的形式返回* 参    数:DID 设备ID,使用输出参数的形式返回* 返 回 值:无*/
void W25Q64_ReadID(uint8_t *MID, uint16_t *DID)
{MySPI_Start();								//SPI起始MySPI_SwapByte(W25Q64_JEDEC_ID);			//交换发送读取ID的指令*MID = MySPI_SwapByte(W25Q64_DUMMY_BYTE);	//交换接收MID,通过输出参数返回*DID = MySPI_SwapByte(W25Q64_DUMMY_BYTE);	//交换接收DID高8位*DID <<= 8;									//高8位移到高位*DID |= MySPI_SwapByte(W25Q64_DUMMY_BYTE);	//或上交换接收DID的低8位,通过输出参数返回MySPI_Stop();								//SPI终止
}/*** 函    数:W25Q64写使能* 参    数:无* 返 回 值:无*/
void W25Q64_WriteEnable(void)
{MySPI_Start();								//SPI起始MySPI_SwapByte(W25Q64_WRITE_ENABLE);		//交换发送写使能的指令MySPI_Stop();								//SPI终止
}/*** 函    数:W25Q64等待忙* 参    数:无* 返 回 值:无*/
void W25Q64_WaitBusy(void)
{uint32_t Timeout;MySPI_Start();								//SPI起始MySPI_SwapByte(W25Q64_READ_STATUS_REGISTER_1);				//交换发送读状态寄存器1的指令Timeout = 100000;							//给定超时计数时间while ((MySPI_SwapByte(W25Q64_DUMMY_BYTE) & 0x01) == 0x01)	//循环等待忙标志位{Timeout --;								//等待时,计数值自减if (Timeout == 0)						//自减到0后,等待超时{/*超时的错误处理代码,可以添加到此处*/break;								//跳出等待,不等了}}MySPI_Stop();								//SPI终止
}/*** 函    数:W25Q64页编程* 参    数:Address 页编程的起始地址,范围:0x000000~0x7FFFFF* 参    数:DataArray	用于写入数据的数组* 参    数:Count 要写入数据的数量,范围:0~256* 返 回 值:无* 注意事项:写入的地址范围不能跨页*/
void W25Q64_PageProgram(uint32_t Address, uint8_t *DataArray, uint16_t Count)
{uint16_t i;W25Q64_WriteEnable();						//写使能MySPI_Start();								//SPI起始MySPI_SwapByte(W25Q64_PAGE_PROGRAM);		//交换发送页编程的指令MySPI_SwapByte(Address >> 16);				//交换发送地址23~16位MySPI_SwapByte(Address >> 8);				//交换发送地址15~8位MySPI_SwapByte(Address);					//交换发送地址7~0位for (i = 0; i < Count; i ++)				//循环Count次{MySPI_SwapByte(DataArray[i]);			//依次在起始地址后写入数据}MySPI_Stop();								//SPI终止W25Q64_WaitBusy();							//等待忙
}/*** 函    数:W25Q64扇区擦除(4KB)* 参    数:Address 指定扇区的地址,范围:0x000000~0x7FFFFF* 返 回 值:无*/
void W25Q64_SectorErase(uint32_t Address)
{W25Q64_WriteEnable();						//写使能MySPI_Start();								//SPI起始MySPI_SwapByte(W25Q64_SECTOR_ERASE_4KB);	//交换发送扇区擦除的指令MySPI_SwapByte(Address >> 16);				//交换发送地址23~16位MySPI_SwapByte(Address >> 8);				//交换发送地址15~8位MySPI_SwapByte(Address);					//交换发送地址7~0位MySPI_Stop();								//SPI终止W25Q64_WaitBusy();							//等待忙
}/*** 函    数:W25Q64读取数据* 参    数:Address 读取数据的起始地址,范围:0x000000~0x7FFFFF* 参    数:DataArray 用于接收读取数据的数组,通过输出参数返回* 参    数:Count 要读取数据的数量,范围:0~0x800000* 返 回 值:无*/
void W25Q64_ReadData(uint32_t Address, uint8_t *DataArray, uint32_t Count)
{uint32_t i;MySPI_Start();								//SPI起始MySPI_SwapByte(W25Q64_READ_DATA);			//交换发送读取数据的指令MySPI_SwapByte(Address >> 16);				//交换发送地址23~16位MySPI_SwapByte(Address >> 8);				//交换发送地址15~8位MySPI_SwapByte(Address);					//交换发送地址7~0位for (i = 0; i < Count; i ++)				//循环Count次{DataArray[i] = MySPI_SwapByte(W25Q64_DUMMY_BYTE);	//依次在起始地址后读取数据}MySPI_Stop();								//SPI终止
}

3、main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "W25Q64.h"uint8_t MID;							//定义用于存放MID号的变量
uint16_t DID;							//定义用于存放DID号的变量uint8_t ArrayWrite[] = {0x01, 0x02, 0x03, 0x04};	//定义要写入数据的测试数组
uint8_t ArrayRead[4];								//定义要读取数据的测试数组int main(void)
{/*模块初始化*/OLED_Init();						//OLED初始化W25Q64_Init();						//W25Q64初始化/*显示静态字符串*/OLED_ShowString(1, 1, "MID:   DID:");OLED_ShowString(2, 1, "W:");OLED_ShowString(3, 1, "R:");/*显示ID号*/W25Q64_ReadID(&MID, &DID);			//获取W25Q64的ID号OLED_ShowHexNum(1, 5, MID, 2);		//显示MIDOLED_ShowHexNum(1, 12, DID, 4);		//显示DIDW25Q64_SectorErase(0x000000);					//扇区擦除/*验证扇区擦除功能(方法:注释掉这一句)如果不擦除,一开始写入AA、BB、CC、DD,后面再次写入55、66、77、88,则读出来00、22、44、88即如果不进行擦除,则读出的数据=原始数据&写入的数据*/W25Q64_PageProgram(0x000000, ArrayWrite, 4);	//将写入数据的测试数组写入到W25Q64中W25Q64_ReadData(0x000000, ArrayRead, 4);		//读取刚写入的测试数据到读取数据的测试数组中/*数据是不能跨页写入验证:若写入55  66  77  88  W25Q64_PageProgram(0x0000FF, ArrayWrite, 4);	//数据不能跨页写入,66  77  88返回到页首写入W25Q64_ReadData(0x0000FF, ArrayRead, 4);		//读取数据可以跨页读出则读出的是55 FF FF FF  ,FF为第二页的数据,第二页是擦除了的,没有写入,默认是FFW25Q64_PageProgram(0x0000FF, ArrayWrite, 4);W25Q64_ReadData(0x000000, ArrayRead, 4);		//读出:66 77 88 FF*//*显示数据*/OLED_ShowHexNum(2, 3, ArrayWrite[0], 2);		//显示写入数据的测试数组OLED_ShowHexNum(2, 6, ArrayWrite[1], 2);OLED_ShowHexNum(2, 9, ArrayWrite[2], 2);OLED_ShowHexNum(2, 12, ArrayWrite[3], 2);OLED_ShowHexNum(3, 3, ArrayRead[0], 2);			//显示读取数据的测试数组OLED_ShowHexNum(3, 6, ArrayRead[1], 2);OLED_ShowHexNum(3, 9, ArrayRead[2], 2);OLED_ShowHexNum(3, 12, ArrayRead[3], 2);while (1){}
}

 四、硬件读写I2C

只需要在软件的基础上添加以下的代码

#include "stm32f10x.h"                  // Device headervoid MySPI_W_SS(uint8_t BitValue)//SS还是软件模拟
{GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue);
}/*初始化步骤1、开启时钟2、初始化GPIO口(1)SCK、MOSI是由硬件外设控制的输出信号:复用推挽输出(2)MISO是硬件外设的输入信号:上拉输入(输入设备可以有很多个,不存在复用输入)(3)SS为软件控制的输出信号,配置为通用推挽输出3、配置SPI外设:	用结构体4、开关控制:调用SPI_Cmd,给SPI使能	
*/
void MySPI_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//通用推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	//上拉输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);SPI_InitTypeDef SPI_InitStructure;SPI_InitStructure.SPI_Mode = SPI_Mode_Master;   	//主机SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //双线全双工SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;   //8位数据帧SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;  //高位先行SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;  //波特率预分频器,配置SCK时钟的频率.SPI1:72MHz/128,SPI2:36MHz/128SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;    //默认低电平,空闲默认低电平SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;   //第一个边沿开始采样(移入)SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;      //一般选择软件NSS模式(不用了解)SPI_InitStructure.SPI_CRCPolynomial = 7;		//随便填SPI_Init(SPI1, &SPI_InitStructure);SPI_Cmd(SPI1, ENABLE);MySPI_W_SS(1);//默认不选中从机
}void MySPI_Start(void)
{MySPI_W_SS(0);
}void MySPI_Stop(void)
{MySPI_W_SS(1);
}/*等待TXE为1,发送寄存器为空,发送寄存器不为空,先不着急写过程:写入数据到TDR-->转移到移位寄存器——>一旦移位寄存器有数据,时序波形就会自动产生(则ByteSend就会通过MOSI一位一位地移出去)——>在MOSI线上,就自动产生发送的时序波形由于是非连续传输,时序产生的时间内,不必提前把下个数据放到TDR,直接等待这段时间过去就行在发送的同时,MISO会移位进行接收发送和接收是同步接收移位完成时,会收到一个字节数据这时会置标志位置RXNE
*/
/*步骤总结(完成一个字节的交换)1、等待TXE为12、写发送的数据至TDR,一旦TDR写出数据来。时序就会自动生成3、等待RXNE为1,发送完成,即接收完成,RXNE置14、读取RDR接收的数据,就是置换接收的一个字节
注意:(1)必须是发送,同时接收,要先写东西,触发时序(2)根据手册,发送缓冲器空闲标志(TXE):写入DR时,会顺便执行清楚TXE的操作,无须手动清除接收缓冲器非空(RXNE):读取SPI数据寄存器可以清除此标志
*/
uint8_t MySPI_SwapByte(uint8_t ByteSend)
{while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) != SET);//若没有数据,则MOSI线为SETSPI_I2S_SendData(SPI1, ByteSend);//ByteSend为要写入到DR,即TDR的数据(要发送的数据),之后会转入到移位寄存器while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != SET);//接收数据完毕的时候,MISO线有标志位RXNEreturn SPI_I2S_ReceiveData(SPI1);//读取DR,从RDR中,把交换接收的数据读取出来,返回值为RDR接收的数据
}

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

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

相关文章

保姆级:Palworld幻兽帕鲁32人服务器一键部署

创建幻兽帕鲁服务器1分钟部署教程&#xff0c;阿里云和腾讯云均推出幻兽帕鲁服务器服务器和部署教程&#xff0c;4核16G和4核32G配置可选&#xff0c;阿腾云atengyun.com分享1分钟自建幻兽帕鲁Palworld服务器教程&#xff1a; 幻兽帕鲁服务器创建教程 幻兽帕鲁服务器官方推荐…

【模拟通信】AM、FM等的调制解调

调制相关的概念 调制&#xff1a;控制载波的参数&#xff0c;使载波参数随调制信号的规律变化 已调信号&#xff1a;受调载波&#xff0c;含有调制信号的全部特征 调制的作用: 提高发射效率多路复用&#xff0c;提高信道利用率提高系统抗干扰能力 两种调制方式 线性调制&a…

​第20课 在Android Native开发中加入新的C++类

​这节课我们开始利用ffmpeg和opencv在Android环境下来实现一个rtmp播放器&#xff0c;与第2课在PC端实现播放器的思路类似&#xff0c;只不过在处理音视频显示和播放的细节略有不同。 1.压缩备份上节课工程文件夹并修改工程文件夹为demo20&#xff0c;将demo20导入到Eclipse或…

RBD —— 简介

目录 General workflow Tips RBD SOP inputs and outputs Clustering Importing a fractured object into DOPs RBD SOP support nodes Related SOPs Low-level SOPs 通常在刚体模拟中&#xff0c;希望实体对象会因某些碰撞或力而破碎&#xff1b;Houdini内大多数破碎…

C# Bitmap类学习1

Bitmap对象封装了GDI中的一个位图&#xff0c;此位图由图形图像及其属性的像素数据组成.因此Bitmap是用于处理由像素数据定义的图像的对象。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using …

教你如何低成本自建「幻兽帕鲁」服务器,快速一键部署

创建幻兽帕鲁服务器1分钟部署教程&#xff0c;阿里云和腾讯云均推出幻兽帕鲁服务器服务器和部署教程&#xff0c;4核16G和4核32G配置可选&#xff0c;阿腾云atengyun.com分享1分钟自建幻兽帕鲁Palworld服务器教程&#xff1a; 幻兽帕鲁服务器创建教程 幻兽帕鲁服务器官方推荐…

EF core连接数据库的前期完整配置流程-开发环境搭建

EF core连接数据库完整流程-开发环境搭建 前置&#xff1a;.net6 core webapi不勾选任何配置 声明&#xff1a;这里是以两个配置类来做的&#xff0c;一个T_Books表&#xff0c;一个T_Person表 Book&#xff1a;创建属性及类型 BookConfig&#xff1a;对创建的进行属性数据表…

66.Spring是如何整合MyBatis将Mapper接口注册为Bean的原理?

原理 首先MyBatis的Mapper接口核心是JDK动态代理 Spring会排除接口&#xff0c;无法注册到IOC容器中 MyBatis 实现了BeanDefinitionRegistryPostProcessor 可以动态注册BeanDefinition 需要自定义扫描器&#xff08;继承Spring内部扫描器ClassPathBeanDefinitionScanner ) 重…

物业app开发实战:10大功能必备,打造智能社区生活

随着智能科技的快速发展&#xff0c;物业管理也逐渐迈入数字化时代。物业app开发成为了提升社区管理效率、改善居民生活质量的重要途径。在本文中&#xff0c;我将分享10大必备功能&#xff0c;帮助开发者打造智能社区生活的物业app。 1. 便捷的社区公告发布功能 通过物业app…

R语言VRPM包绘制多种模型的彩色列线图

列线图&#xff0c;又称诺莫图&#xff08;Nomogram&#xff09;&#xff0c;它是建立在回归分析的基础上&#xff0c;使用多个临床指标或者生物属性&#xff0c;然后采用带有分数高低的线段&#xff0c;从而达到设置的目的&#xff1a;基于多个变量的值预测一定的临床结局或者…

免费畅享,打破写作瓶颈:星火写作助手覆盖全面,助你轻松创作

啰嗦几句 最近年终岁末&#xff0c;公司的各种文案各种总结&#xff0c;写得人是头晕脑胀&#xff0c;所以好多小伙伴最近在求智能写作的软件&#xff0c;最好是ChatGPT。 ChatGPT是国外产品&#xff0c;在国内并不能访问。而就智能写作来说&#xff0c;我们何必舍近求远呢&am…

1.新建项目

愿你出走半生,归来仍是少年&#xff01; 环境&#xff1a;.NET 7、MAUI 1.新建项目 打开VS2022,点击“创建新项目”。 新建项目 2.选择项目类型 在搜索框输入“Maui”&#xff0c;选择“NET MAUI应用”&#xff0c;配置项目名称、保存地址等&#xff0c;并选择框架版本。 项目…

精准监测,守护城市脉搏:管网压力、流量监测设备

在繁忙的城市中&#xff0c;每一个管道都如同城市的血脉&#xff0c;承载着重要的使命。为了确保城市的正常运行&#xff0c;我们提供精准的管网压力、流量监测设备&#xff0c;用科技守护城市的脉搏。 我们的设备采用最新的技术&#xff0c;可以实时监测管网的压力和流量&…

【11.PWM捕获】蓝桥杯嵌入式一周拿奖速成系列

系列文章目录 蓝桥杯嵌入式系列文章目录(更多此系列文章可见) PWM捕获 系列文章目录一、STM32CUBEMX配置二、项目代码1.mian.c --> HAL_TIM_IC_CatureCallback 总结 一、STM32CUBEMX配置 STM32CUBEMX PA15 ->TIM2_CH1; PB4-> TIM3_CH1 预分频设置为79,自动重装载设置…

HTML实战

HTML实战 标题 标题排版 img标签路径书写的两种方式&#xff1a; 绝对路径 绝对磁盘路径&#xff1a;C:\User…绝对网络路径&#xff1a;https://i2.sinaimg.cn/dy/deco/2012/0613/yocc20120613img01/news_logo.png 相对路径 ./ : 当前目录 ../ &#xff1a; 上一级目录宽…

Spring基于dynamic-datasource实现MySQL多数据源

目录 多数据源实现 引入依赖 yml配置文件 业务代码 案例演示 多数据源实现 引入依赖 <dependency><groupId>com.baomidou</groupId><artifactId>dynamicdatasourcespringbootstarter</artifactId><version>3.5.0</version> &…

Programming Abstractions in C阅读笔记:p248-p253

《Programming Abstractions in C》学习第69天&#xff0c;p248-p253总结&#xff0c;总计6页。 一、技术总结 “A generalized program for two-player games”如标题所示&#xff0c;该小节强调要学会从一个复杂的程序中抽象出通用的内容——这也是本书的主旨——“Program…

Linux快速入门

目录 一. Linux的结构目录 1.1 Linux的目录结构 1.2 常用的目录介绍 二. 常用命令 # 与 $ 提示的区别 查看ip地址&#xff1a;ifconfig su&#xff1a;切换用户 cd 目录查看 查看文件内容 创建目录及文件 复制和移动 其他 tar which whereis find chmod 三. vim一般使用 四…

C4.5决策树的基本建模流程

C4.5决策树的基本建模流程 作为ID3算法的升级版&#xff0c;C4.5在三个方面对ID3进行了优化&#xff1a; &#xff08;1&#xff09;它引入了信息值&#xff08;information value&#xff09;的概念来修正信息熵的计算结果&#xff0c;以抑制ID3更偏向于选择具有更多分类水平…

<C++>STL->vector

vector的介绍 vector的使用文档 vector是一个可改变数组大小的序列容器vector和数组一样采取连续的空间存放数据&#xff0c;可以使用方括号访问vector的元素&#xff0c;和数组一样高效。但是vector的大小可以动态增长&#xff0c;而数组不行实际上vector内部使用一个动态分…