【STM32】IIC的基本原理(实例:普通IO口模拟IIC时序读取24C02)(转载)

版权声明:本文为博主原创文章,允许转载,但希望标注转载来源。 https://blog.csdn.net/qq_38410730/article/details/80312357

IIC的基本介绍

IIC的简介

IIC(Inter-Integrated Circuit)总线是一种由PHILIPS公司在80年代开发的两线式串行总线,用于连接微控制器及其外围设备。它是半双工通信方式。

  • IIC总线最主要的优点是其简单性和有效性。由于接口直接在组件之上,因此IIC总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。总线的长度可高达25英尺,并且能够以10Kbps的最大传输速率支持40个组件。
  • IIC总线的另一个优点是,它支持多主控(multimastering), 其中任何能够进行发送和接收的设备都可以成为主总线。一个主控能够控制信号的传输和时钟频率。当然,在任何时间点上只能有一个主控。

IIC串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL,其时钟信号是由主控器件产生。所有接到IIC总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。对于并联在一条总线上的每个IC都有唯一的地址。

一般情况下,数据线SDA和时钟线SCL都是处于上拉电阻状态。因为:在总线空闲状态时,这两根线一般被上面所接的上拉电阻拉高,保持着高电平。

STM32的IIC接口

目前绝大多数的MCU都附带IIC总线接口,STM32也不例外。但是在本文中,我们不使用STM32的硬件IIC来读取24C02,而是通过软件的方式来模拟。

原因是因为:STM32的硬件IIC非常复杂,更重要的是它并不稳定,故不推荐使用。

 

IIC协议

IIC总线在传输数据的过程中一共有三种类型信号,分别为:开始信号、结束信号和应答信号。这些信号中,起始信号是必需的,结束信号和应答信号,都可以不要。同时我们还要介绍其空闲状态、数据的有效性、数据传输。

先来看一下IIC总线的时序图:

这可能会比较复杂,可以先看一份简化了的时序图:

空闲状态

当IIC总线的数据线SDA和时钟线SCL两条信号线同时处于高电平时,规定为总线的空闲状态。此时各个器件的输出级场效应管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。 

起始信号与停止信号

  • 起始信号:当时钟线SCL为高期间,数据线SDA由高到低的跳变;启动信号是一种电平跳变时序信号,而不是一个电平信号;
  • 停止信号:当时钟线SCL为高期间,数据线SDA由低到高的跳变;停止信号也是一种电平跳变时序信号,而不是一个电平信号。

应答信号

发送器每发送一个字节(8个bit),就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。 

  • 应答信号为低电平时,规定为有效应答位(ACK,简称应答位),表示接收器已经成功地接收了该字节;
  • 应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。 

对于反馈有效应答位ACK的要求是:接收器在第9个时钟脉冲之前的低电平期间将数据线SDA拉低,并且确保在该时钟的高电平期间为稳定的低电平。 如果接收器是主控器,则在它收到最后一个字节后,发送一个NACK信号,以通知被控发送器结束数据发送,并释放数据线SDA,以便主控接收器发送一个停止信号P。

数据有效性

IIC总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定;只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。 

即:数据在时钟线SCL的上升沿到来之前就需准备好。并在在下降沿到来之前必须稳定。

数据的传达

在IIC总线上传送的每一位数据都有一个时钟脉冲相对应(或同步控制),即在SCL串行时钟的配合下,在SDA上逐位地串行传送每一位数据。数据位的传输是边沿触发。

延时时间

 

IIC总线的数据传送

IIC总线上的每一个设备都可以作为主设备或者从设备,而且每一个设备都会对应一个唯一的地址(地址通过物理接地或者拉高),主从设备之间就通过这个地址来确定与哪个器件进行通信,在通常的应用中,我们把CPU带I2C总线接口的模块作为主设备,把挂接在总线上的其他设备都作为从设备。

也就是说,主设备在传输有效数据之前要先指定从设备的地址,地址指定的过程和上面数据传输的过程一样,只不过大多数从设备的地址是7位的,然后协议规定再给地址添加一个最低位用来表示接下来数据传输的方向,0表示主设备向从设备写数据,1表示主设备向从设备读数据。

  • 主设备往从设备中写数据。数据传输格式如下:

淡蓝色部分表示数据由主机向从机传送,粉红色部分则表示数据由从机向主机传送。

写用0来表示(低电平),读用1来表示(高电平)。

  • 主设备从从设备中读数据。数据传输格式如下:

在从机产生响应时,主机从发送变成接收,从机从接收变成发送。之后,数据由从机发送,主机接收,每个应答由主机产生,时钟信号仍由主机产生。若主机要终止本次传输,则发送一个非应答信号,接着主机产生停止条件。

  •  主设备往从设备中写数据,然后重启起始条件,紧接着从从设备中读取数据;或者是主设备从从设备中读数据,然后重启起始条件,紧接着主设备往从设备中写数据。数据传输格式如下:

在多主的通信系统中,总线上有多个节点,它们都有自己的寻址地址,可以作为从节点被别的节点访问,同时它们都可以作为主节点向其它的节点发送控制字节和传送数据。但是如果有两个或两个以上的节点都向总线上发送启动信号并开始传送数据,这样就形成了冲突。要解决这种冲突,就要进行仲裁的判决,这就是I2C总线上的仲裁。

I2C总线上的仲裁分两部分:SCL线的同步和SDA线的仲裁。

这部分就暂时不介绍了,想要了解:可以参考链接浅谈I2C总线或I2C总线协议图解。

 

IIC底层驱动程序分析

现拟采用PB6、PB7来模拟IIC时序,其中:PB6为时钟线,PB7为数据线。

首先进行一些必要的宏定义:

  1. //IO方向设置
  2. #define SDA_IN() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
  3. #define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}
  4. //IO操作函数
  5. #define IIC_SCL PBout(6) //SCL
  6. #define IIC_SDA PBout(7) //SDA
  7. #define READ_SDA PBin(7) //输入SDA
  8. //IIC所有操作函数
  9. void IIC_Init(void); //初始化IIC的IO口
  10. void IIC_Start(void); //发送IIC开始信号
  11. void IIC_Stop(void); //发送IIC停止信号
  12. void IIC_Send_Byte(u8 txd); //IIC发送一个字节
  13. u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
  14. u8 IIC_Wait_Ack(void); //IIC等待ACK信号
  15. void IIC_Ack(void); //IIC发送ACK信号
  16. void IIC_NAck(void); //IIC不发送ACK信号

由于IIC是半双工通信方式,因而数据线SDA可能会数据输入,也可能是数据输出,需要定义IIC_SDA来进行输出、READ_SDA来进行输入,与此同时就要对IO口进行模式配置:SDA_IN()和SDA_OUT()。

而时钟线SCL一直是输出的,所以就没有数据线SDA麻烦了。

  1. //初始化IIC
  2. void IIC_Init(void)
  3. {
  4. GPIO_InitTypeDef GPIO_InitStructure;
  5. RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //使能GPIOB时钟
  6. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
  7. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出
  8. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  9. GPIO_Init(GPIOB, &GPIO_InitStructure);
  10. GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); //PB6,PB7 输出高,空闲状态
  11. }
  12. //产生IIC起始信号
  13. void IIC_Start(void)
  14. {
  15. SDA_OUT(); //sda线输出
  16. IIC_SDA=1;
  17. IIC_SCL=1;
  18. delay_us(4);
  19. IIC_SDA=0;    //START:when CLK is high,DATA change form high to low
  20. delay_us(4);
  21. IIC_SCL=0;    //钳住I2C总线,准备发送或接收数据
  22. }
  23. //产生IIC停止信号
  24. void IIC_Stop(void)
  25. {
  26. SDA_OUT();    //sda线输出
  27. IIC_SCL=0;
  28. IIC_SDA=0;    //STOP:when CLK is high DATA change form low to high
  29. delay_us(4);
  30. IIC_SCL=1;
  31. IIC_SDA=1;    //发送I2C总线结束信号
  32. delay_us(4);
  33. }
  34. //发送数据后,等待应答信号到来
  35. //返回值:1,接收应答失败,IIC直接退出
  36. // 0,接收应答成功,什么都不做
  37. u8 IIC_Wait_Ack(void)
  38. {
  39. u8 ucErrTime=0;
  40. SDA_IN(); //SDA设置为输入
  41. IIC_SDA=1;delay_us(1);
  42. IIC_SCL=1;delay_us(1);
  43. while(READ_SDA)
  44. {
  45. ucErrTime++;
  46. if(ucErrTime>250)
  47. {
  48. IIC_Stop();
  49. return 1;
  50. }
  51. }
  52. IIC_SCL=0;    //时钟输出0
  53. return 0;
  54. }
  55. //产生ACK应答
  56. void IIC_Ack(void)
  57. {
  58. IIC_SCL=0;
  59. SDA_OUT();
  60. IIC_SDA=0;
  61. delay_us(2);
  62. IIC_SCL=1;
  63. delay_us(2);
  64. IIC_SCL=0;
  65. }
  66. //不产生ACK应答
  67. void IIC_NAck(void)
  68. {
  69. IIC_SCL=0;
  70. SDA_OUT();
  71. IIC_SDA=1;
  72. delay_us(2);
  73. IIC_SCL=1;
  74. delay_us(2);
  75. IIC_SCL=0;
  76. }
  77. //IIC发送一个字节
  78. //返回从机有无应答
  79. //1,有应答
  80. //0,无应答
  81. void IIC_Send_Byte(u8 txd)
  82. {
  83. u8 t;
  84. SDA_OUT();
  85. IIC_SCL=0;            //拉低时钟开始数据传输
  86. for(t=0;t<8;t++)
  87. {
  88. //IIC_SDA=(txd&0x80)>>7;
  89. if((txd&0x80)>>7)
  90. IIC_SDA=1;
  91. else
  92. IIC_SDA=0;
  93. txd<<=1;
  94. delay_us(2);     //对TEA5767这三个延时都是必须的
  95. IIC_SCL=1;
  96. delay_us(2);
  97. IIC_SCL=0;
  98. delay_us(2);
  99. }
  100. }
  101. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK
  102. u8 IIC_Read_Byte(unsigned char ack)
  103. {
  104. unsigned char i,receive=0;
  105. SDA_IN();        //SDA设置为输入
  106. for(i=0;i<8;i++ )
  107. {
  108. IIC_SCL=0;
  109. delay_us(2);
  110. IIC_SCL=1;
  111. receive<<=1;
  112. if(READ_SDA)receive++;
  113. delay_us(1);
  114. }
  115. if (!ack)
  116. IIC_NAck();        //发送nACK
  117. else
  118. IIC_Ack();         //发送ACK
  119. return receive;
  120. }

这里是通过普通IO口(PB6、PB7)来模拟IIC时序的程序,其实本质上都是严格按照IIC的时序图进行的,认真读,仔细对比,应该是没有什么困难的。

就提一下:IIC_Read_Byte()函数,这个函数的参数表示读取一个字节之后,需要给对方应答信号或非应答信号。

 

普通IO口模拟IIC时序读取24C02

24C02芯片介绍

EEPROM (Electrically Erasable Programmable read only memory),带电可擦可编程只读存储器——一种掉电后数据不丢失的存储芯片。 

24Cxx芯片是EEPROM芯片的一种,它是基于IIC总线的存储器件,遵循二线制协议,由于其具有接口方便,体积小,数据掉电不丢失等特点,在仪器仪表及工业自动化控制中得到大量的应用。24Cxx在电路的作用主要是在掉电的情况下保存数据。

本文使用的是24C02芯片,总容量是2k个bit(256个字节)。这里芯片名称里的02代表着总容量。

24C02芯片的引脚分布和具体的作用见下图:

 

24C02芯片的引脚说明
引脚名称说明
A0-A2地址输入线
SDA数据线
SCL时钟线
WP写保护
GND、VCC提供电源

下图是本文中24C02和STM32的引脚连接图:

从图中可以看出:A0、A1、A2都为0。

对于并联在一条IIC总线上的每个IC都有唯一的地址。那么看一下从器件地址,可以看出对于不同大小的24Cxx,具有不同的从器件地址。由于24C02为2k容量,也就是说只需要参考图中第一行的内容:

根据图中的内容:如果是写24C02的时候,从器件地址为10100000(0xA0);读24C02的时候,从器件地址为10100001(0xA1)。

24C02芯片的时序图

这部分的内容应结合上文:I2C总线的数据传送的内容一起理解。

24C02字节写时序

对24C02芯片进行写字节操作的时候,步骤如下:

  1. 开始位,后面紧跟从器件地址位(0xA0),等待应答,这是为了在IIC总线上确定24C02的从地址位置;
  2. 确定操作24C02的地址,等待应答,也就是将字节写入到24C02中256个字节中的位置;
  3. 确定需要写入24C02芯片的字节,等待应答,停止位。

24C02字节读时序

对24C02芯片进行读字节操作的时候,步骤如下:

  1. 开始位,后面紧跟从器件地址位(0xA0),等待应答,这是为了在IIC总线上确定24C02的从地址位置;
  2. 确定操作24C02的地址,等待应答,也就是从24C02中256个字节中读取字节的位置;
  3. 再次开始位,后面紧跟从器件地址位(0xA1),等待应答;
  4. 获取从24C02芯片中读取的字节,发出非应答信号,停止位。

读取24C02芯片程序

  1. #define AT24C01 127
  2. #define AT24C02 255
  3. #define AT24C04 511
  4. #define AT24C08 1023
  5. #define AT24C16 2047
  6. #define AT24C32 4095
  7. #define AT24C64 8191
  8. #define AT24C128 16383
  9. #define AT24C256 32767
  10. //Mini STM32开发板使用的是24c02,所以定义EE_TYPE为AT24C02
  11. #define EE_TYPE AT24C02
  1. //初始化IIC接口
  2. void AT24CXX_Init(void)
  3. {
  4. IIC_Init();
  5. }
  6. //在AT24CXX指定地址读出一个数据
  7. //ReadAddr:开始读数的地址
  8. //返回值 :读到的数据
  9. u8 AT24CXX_ReadOneByte(u16 ReadAddr)
  10. {
  11. u8 temp=0;
  12. IIC_Start();
  13. if(EE_TYPE>AT24C16)            //为了兼容24Cxx中其他的版本
  14. {
  15. IIC_Send_Byte(0XA0); //发送写命令
  16. IIC_Wait_Ack();
  17. IIC_Send_Byte(ReadAddr>>8);    //发送高地址
  18. IIC_Wait_Ack();
  19. }else     IIC_Send_Byte(0XA0+((ReadAddr/256)<<1)); //发送器件地址0XA0,写数据
  20. IIC_Wait_Ack();
  21. IIC_Send_Byte(ReadAddr%256); //发送低地址
  22. IIC_Wait_Ack();
  23. IIC_Start();
  24. IIC_Send_Byte(0XA1); //进入接收模式
  25. IIC_Wait_Ack();
  26. temp=IIC_Read_Byte(0);     //读一个字节,非应答信号信号
  27. IIC_Stop();        //产生一个停止条件
  28. return temp;
  29. }
  30. //在AT24CXX指定地址写入一个数据
  31. //WriteAddr :写入数据的目的地址
  32. //DataToWrite:要写入的数据
  33. void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
  34. {
  35. IIC_Start();
  36. if(EE_TYPE>AT24C16)
  37. {
  38. IIC_Send_Byte(0XA0); //发送写命令
  39. IIC_Wait_Ack();
  40. IIC_Send_Byte(WriteAddr>>8);    //发送高地址
  41. }else
  42. {
  43. IIC_Send_Byte(0XA0+((WriteAddr/256)<<1)); //发送器件地址0XA0,写数据
  44. }
  45. IIC_Wait_Ack();
  46. IIC_Send_Byte(WriteAddr%256); //发送低地址
  47. IIC_Wait_Ack();
  48. IIC_Send_Byte(DataToWrite); //发送字节
  49. IIC_Wait_Ack();
  50. IIC_Stop();    //产生一个停止条件
  51. delay_ms(10);
  52. }
  53. //在AT24CXX里面的指定地址开始写入长度为Len的数据
  54. //该函数用于写入16bit或者32bit的数据.
  55. //WriteAddr :开始写入的地址
  56. //DataToWrite:数据数组首地址
  57. //Len :要写入数据的长度2,4
  58. void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len)
  59. {
  60. u8 t;
  61. for(t=0;t<Len;t++)
  62. {
  63. AT24CXX_WriteOneByte(WriteAddr+t,(DataToWrite>>(8*t))&0xff);
  64. }
  65. }
  66. //在AT24CXX里面的指定地址开始读出长度为Len的数据
  67. //该函数用于读出16bit或者32bit的数据.
  68. //ReadAddr :开始读出的地址
  69. //返回值 :数据
  70. //Len :要读出数据的长度2,4
  71. u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len)
  72. {
  73. u8 t;
  74. u32 temp=0;
  75. for(t=0;t<Len;t++)
  76. {
  77. temp<<=8;
  78. temp+=AT24CXX_ReadOneByte(ReadAddr+Len-t-1);
  79. }
  80. return temp;
  81. }
  82. //检查AT24CXX是否正常
  83. //这里用了24XX的最后一个地址(255)来存储标志字.
  84. //如果用其他24C系列,这个地址要修改
  85. //返回1:检测失败
  86. //返回0:检测成功
  87. u8 AT24CXX_Check(void)
  88. {
  89. u8 temp;
  90. temp=AT24CXX_ReadOneByte(255);//避免每次开机都写AT24CXX
  91. if(temp==0X55)return 0;
  92. else//排除第一次初始化的情况
  93. {
  94. AT24CXX_WriteOneByte(255,0X55);
  95. temp=AT24CXX_ReadOneByte(255);
  96. if(temp==0X55)return 0;
  97. }
  98. return 1;
  99. }
  100. //在AT24CXX里面的指定地址开始读出指定个数的数据
  101. //ReadAddr :开始读出的地址 对24c02为0~255
  102. //pBuffer :数据数组首地址
  103. //NumToRead:要读出数据的个数
  104. void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
  105. {
  106. while(NumToRead)
  107. {
  108. *pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);
  109. NumToRead--;
  110. }
  111. }
  112. //在AT24CXX里面的指定地址开始写入指定个数的数据
  113. //WriteAddr :开始写入的地址 对24c02为0~255
  114. //pBuffer :数据数组首地址
  115. //NumToWrite:要写入数据的个数
  116. void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
  117. {
  118. while(NumToWrite--)
  119. {
  120. AT24CXX_WriteOneByte(WriteAddr,*pBuffer);
  121. WriteAddr++;
  122. pBuffer++;
  123. }
  124. }
  1. //要写入到24c02的字符串数组
  2. const u8 TEXT_Buffer[]={"WarShipSTM32 IIC TEST"};
  3. #define SIZE sizeof(TEXT_Buffer)
  4. int main(void)
  5. {
  6. u8 key;
  7. u16 i=0;
  8. u8 datatemp[SIZE];
  9. delay_init(); //延时函数初始化
  10. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
  11. uart_init(115200); //串口初始化为115200
  12. LED_Init(); //初始化与LED连接的硬件接口
  13. LCD_Init(); //初始化LCD
  14. KEY_Init(); //按键初始化
  15. AT24CXX_Init(); //IIC初始化
  16. POINT_COLOR=RED;//设置字体为红色
  17. LCD_ShowString(30,50,200,16,16,"WarShip STM32");
  18. LCD_ShowString(30,70,200,16,16,"IIC TEST");
  19. LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
  20. LCD_ShowString(30,110,200,16,16,"2015/1/15");
  21. LCD_ShowString(30,130,200,16,16,"KEY1:Write KEY0:Read"); //显示提示信息
  22. while(AT24CXX_Check())//检测不到24c02
  23. {
  24. LCD_ShowString(30,150,200,16,16,"24C02 Check Failed!");
  25. delay_ms(500);
  26. LCD_ShowString(30,150,200,16,16,"Please Check! ");
  27. delay_ms(500);
  28. LED0=!LED0;//DS0闪烁
  29. }
  30. LCD_ShowString(30,150,200,16,16,"24C02 Ready!");
  31. POINT_COLOR=BLUE;//设置字体为蓝色
  32. while(1)
  33. {
  34. key=KEY_Scan(0);
  35. if(key==KEY1_PRES)//KEY_UP按下,写入24C02
  36. {
  37. LCD_Fill(0,170,239,319,WHITE);//清除半屏
  38. LCD_ShowString(30,170,200,16,16,"Start Write 24C02....");
  39. AT24CXX_Write(0,(u8*)TEXT_Buffer,SIZE);
  40. LCD_ShowString(30,170,200,16,16,"24C02 Write Finished!");//提示传送完成
  41. }
  42. if(key==KEY0_PRES)//KEY1按下,读取字符串并显示
  43. {
  44. LCD_ShowString(30,170,200,16,16,"Start Read 24C02.... ");
  45. AT24CXX_Read(0,datatemp,SIZE);
  46. LCD_ShowString(30,170,200,16,16,"The Data Readed Is: ");//提示传送完成
  47. LCD_ShowString(30,190,200,16,16,datatemp);//显示读到的字符串
  48. }
  49. i++;
  50. delay_ms(10);
  51. if(i==20)
  52. {
  53. LED0=!LED0;//提示系统正在运行
  54. i=0;
  55. }
  56. }
  57. }

 

IIC总结

  1. 进行数据传送时,在SCL为高电平期间,SDA线上电平必须保持稳定,只有SCL为低时,才允许SDA线上电平改变状态。并且每个字节传送时都是高位在前;
  2. 对于应答信号,ACK=0时为有效应答位,说明从机已经成功接收到该字节,若为1则说明接受不成功;
  3. 如果从机需要延迟下一个数据字节开始传送的时间,可以通过把SCL电平拉低并保持来强制主机进入等待状态;
  4. 主机完成一次通信后还想继续占用总线在进行一次通信,而又不释放总线,就要利用重启动信号。它既作为前一次数据传输的结束,又作为后一次传输的开始;
  5. 总线冲突时,按“低电平优先”的仲裁原则,把总线判给在数据线上先发送低电平的主器件;
  6. 在特殊情况下,若需禁止所有发生在I2C总线上的通信,可采用封锁或关闭总线,具体操作为在总线上的任一器件将SCL锁定在低电平即可;
  7. SDA仲裁和SCL时钟同步处理过程没有先后关系,而是同时进行的。

 

转载于:https://www.cnblogs.com/CodeWorkerLiMing/p/10830459.html

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

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

相关文章

【数据结构与算法】广度优先遍历(BFS) 深度优先遍历(DFS)

一、 搜索算法 深度优先搜索和广度优先搜索是最暴力的图的搜索算法。算法的目标是&#xff0c;给定一张图&#xff0c;一对初始和终止节点&#xff0c;找到两节点之间的节点路径。&#xff08;代码均是找到两个节点之间的路径&#xff09; 广度优先搜索是一层一层搜索&#xf…

stack专题

20 Valid Parentheses 问题&#xff1a;没有意识到字符串中只包含字符&#xff1a;’(‘, ‘)’, ‘{‘, ‘}’, ‘[’ and ‘]’ 代码&#xff1a;git代码 682 Baseball Game 问题&#xff1a;错误在操作&#xff1a;top1 先弹出&#xff0c;top2 再弹出&#xff0c;还原到…

第三十期:简单好用的9个电脑必备工具!让你轻松10倍

下面 9 款工具都是精心挑选的电脑必备神器&#xff0c;涵盖你需要的各个方面&#xff0c;无论是安全防护、文件查找、解压加密还是娱乐都在其中&#xff1b;最最最重要的是&#xff0c;它们不但各个功能强大&#xff0c;而且非常轻便&#xff0c;没有弹窗广告、没有捆绑安装、也…

【数据结构与算法】字符串匹配 BF算法 RK算法

单模式串匹配 BF 算法和 RK 算法 BM 算法和 KMP 算法多模式串匹配算法 Trie 树和 AC 自动机 一、BF 算法 1&#xff0c;BF算法是Brute Force的缩写&#xff0c;中文译作暴力匹配算法&#xff0c;也叫朴素匹配算法。 2&#xff0c;两个概念&#xff1a;主串和模式串 如在字符串…

第三十一期:大数据分析师学习入门,10个数据可视化技巧

在这篇文章&#xff0c;我想和大家分享 10 个基本的中级和高级的绘图工具。我发现在现实生活中&#xff0c;当涉及到绘图解释你的数据时&#xff0c;这些工具非常有用。 作者&#xff1a;加米谷大数据来源&#xff1a;今日头条 我必须对你说实话&#xff1a;当我学习数据科学时…

[Leetcode][第491题][JAVA][递增子序列][回溯][RK算法]

【问题描述】[中等] 【解答思路】 1. 二进制枚举 哈希 复杂度 class Solution {List<Integer> temp new ArrayList<Integer>();List<List<Integer>> ans new ArrayList<List<Integer>>();Set<Integer> set new HashSet<In…

第五十七期:小型企业将如何从5G中受益

在足够多的新设备进入主流市场之前&#xff0c;5G已经在许多领域引起了越来越多的关注。从IT、零售、交通和制造业到医疗、娱乐、教育和农业&#xff0c;几乎每个行业都将在某种程度上受到5G的影响。 作者&#xff1a;李雪薇来源&#xff1a;IT168网站 在足够多的新设备进入主…

第三十二期:MySQL常见的图形化工具

MySQL作为一款非常流行的、开源的关系型数据库&#xff0c;应用非常广泛。因为MySQL开源的缘故&#xff0c;图形化管理维护工众多&#xff0c;除了系统自带的命令行管理工具之外&#xff0c;还有许多其他的图形化管理工具&#xff0c;这里介绍几个经常使用的MySQL图形化管理工具…

centos7 源码安装goaccess

1. 使用yum安装在不同服务器上可能失败, 推荐使用源码安装goaccess # 安装依赖 yum install -y ncurses-devel GeoIP-devel.x86_64 tokyocabinet-devel openssl-devel# 下载源码包并安装 cd /usr/local/software wget http://tar.goaccess.io/goaccess-1.3.tar.gz tar -xvf goa…

【数据结构与算法】字符串匹配 BM算法

单模式串匹配 BF 算法和 RK 算法 BM 算法和 KMP 算法多模式串匹配算法 Trie 树和 AC 自动机 BM算法 BM算法的核心思想是通过将模式串沿着主串大踏步的向后滑动&#xff0c;从而大大减少比较次数&#xff0c;降低时间复杂度。而算法的关键在于如何兼顾步子迈得足够大与无遗漏&…

第五十八期:AI艺术日渐繁荣,未来何去何从?

本文的配图都是AI艺术领域领导者、德国艺术家马里奥克林格曼(Mario Klingemann)利用人工智能创作的作品。 利用人工智能创作而成的画作近年来越来越受瞩目&#xff0c;有的作品甚至能在知名拍卖行拍得高价。但这类作品仍有不少问题需要解答&#xff0c;比如它的作者是开发出算…

【数据结构与算法】字符串匹配 KMP 算法

单模式串匹配 BF 算法和 RK 算法 BM 算法和 KMP 算法多模式串匹配算法 Trie 树和 AC 自动机 KMP 算法 KMP 算法是根据三位作者&#xff08;D.E.Knuth&#xff0c;J.H.Morris 和 V.R.Pratt&#xff09;的名字来命名的&#xff0c;算法的全称是 Knuth Morris Pratt 算法&#x…

第五十九期:商用数据库之死:Oracle 面临困境

作者&#xff1a;John Freeman、Fred McClimans 和 Zach Mitchell 我们预计到 2021 年&#xff0c;年产值 296 亿美元的商业数据库市场会收缩 20% 至 30%&#xff0c;认为 Oracle 无法让收入来源足够快地实现转型&#xff08;从传统的商业数据库转向基于云的订购产品&#xff0…

第六十期:华为:希望把VR/AR打造成下个智能手机产业

网易科技讯 10 月 19 日消息&#xff0c;2019 世界 VR 产业大会在江西省南昌市举行。华为轮值董事长郭平发表了《打造 VR/AR 信息高速公路&#xff0c;支撑产业繁荣》的主题演讲。郭平认为&#xff0c;VR/AR 将成为 5G 时代的首批应用&#xff0c;与 5G 产业发展节奏高度匹配并…

【数据结构与算法】字符串匹配 AC自动机

单模式串匹配 BF 算法和 RK 算法 BM 算法和 KMP 算法多模式串匹配算法 Trie 树和 AC 自动机 AC 自动机 AC 自动机实际上就是在 Trie 树之上&#xff0c;加了类似 KMP 的 next 数组&#xff0c;只不过此处的 next 数组是构建在树上罢了。 AC 自动机的构建 将多个模式串构建成…

第六十一期:中国农民花3000块,发明史上最牛输入法!曾火遍中国20年

投递人 itwriter “王旁青头戋(兼)五一&#xff0c;土十二干士寸雨” 如果你还能熟练的背出这段口诀&#xff0c;恭喜你&#xff0c;又暴露年龄了。 倒回到十几年前&#xff0c;在刀哥被老师带到穿鞋套才能进神秘的机房&#xff0c;练习打字的时候&#xff0c;会五笔的人简直是…

第六十二期:腾讯云发布“小程序·云开发十大优秀实践”:猫眼、唯品会等入选

作者&#xff1a;周小白 【TechWeb】10 月 19 日消息&#xff0c;今日&#xff0c;腾讯云首次对外公布了“小程序云开发十大优秀实践”&#xff0c;包括白鹭引擎、千墨科技、腾讯新闻、即速应用、微盟、唯品会、猫眼、香格里拉、微信读书、微信支付等&#xff0c;涉及多个行业。…

[Leetcode][第17题][JAVA][电话号码的字母组合][回溯]

【问题描述】[中等] 【解答思路】 用哈希表/数组存储每个数字对应的所有可能的字母&#xff0c;然后进行回溯操作。 回溯过程中维护一个字符串&#xff0c;表示已有的字母排列&#xff08;如果未遍历完电话号码的所有数字&#xff0c;则已有的字母排列是不完整的&#xff09;…

(68)zabbix windows性能计数器使用详解

概述 windows下的性能计数器让zabbix监控更加轻松&#xff0c;直接获取性能计数器的数值即可完成windows监控。性能计数器如下&#xff1a; 1perf_counter["\Processor(0)\Interrupts/sec"]或 1perf_counter["\Processor(0)\Interrupts/sec", 10]获取所有性…

第六十三期:微软与阿里云合作推出“开放应用模型(OAM)”

投递人 itseeker 英文原文&#xff1a;Announcing the Open Application Model (OAM) 原文标题&#xff1a;微软与阿里云合作推出“开放应用模型&#xff08;OAM&#xff09;” 用于 Kubernetes 及更多平台的应用开发、运行的开放标准 Kubernetes 已经成为业界领先的容器编排环…