STM32——I2C
通信协议见(STM32——SPI)
一、I2C协议
1.1 I2C协议介绍;
I2C是(Inter IC Bus)是由Philips公司开发的一种通用数据总线;
有多根通信线;
一根SDA(串行通信线);
一根SCL(串行时钟线);
共地GND;
VCC电源线;
同步半双工;
支持总线挂载多设备(一主多从,多主多从);
带数据应答(主机接收一个数据后,会返回应答位,告诉从机是否接收到了数据);
1.2 I2C协议对硬件的规定;
所有设备的SDA连接在一起,SCL连接在一起,GND连接在一起,如果从设备没有单独供电,还需要外接电源VCC;
主机对SCL时钟线具有绝对的控制权,从机只能输入,不能控制时钟线,此时SCL可以配置为推挽输出;
但是SDA主机和从机即可以输入也可以输出,为了避免主机输出同时,从机也输出,形成短路,I2C设计中是禁止所有设备输出强上拉的高电平;
采样外接弱上拉电阻加开漏输出的模式;(阻值一般为4.7千欧);
结构图如下:
原理:设计为开漏模式,此时输入时,直接经过斯密特触发器整流任何时刻都可以输入,输出时,经过开漏设计,低电平导通,为拉下状态低电平,高电平截至处于浮空状态,引脚电平外接上拉电阻弱上拉为高电平;
设计的优点:
作用:
1.避免电路出现短路现象;
2.避免频繁切换引脚模式;
3.线与:一个或者多个输出低电平,呈现低电平,只有全部都输出高电平才输出高电平;执行多主机下的时钟同步和总线仲裁;
过程:当I2C处于空闲状态时,SCL和SDA均由外挂的电阻,拉高至高电平;总线处于高电平状态;当总线需要传输数据时候,SCL保持不变,将SDA从高电平转换为低电平,产生一个下降沿,当从机检测到SCL高电平,SDA下降沿时候,会复位,进入就绪状态;在SDA下降沿后,SCL也从高电平到低电平,一方面占用这个总线,同时拼接单元,完成后传输后,SCL回弹到高电平,产生上升沿后,SDA也回弹到高电平,从机检测后,进入终止;终止后俩个都处于高电平,恢复到平静状态;
1.3 I2C协议对软件的规定;
1.3.1时序单元:
由起始条件,传输字节,应答位,终止条件组成;
起始条件:标志着一个数据帧的开始,SCL高电平的时候,SDA由高电平变成低电平产生下降沿;
终止条件:标志着一个数据帧的间隔,SLC高电平的时候,SDA由低电平转换为高电平产生上升沿;
传输字节:发送一个字节,接收一个字节;
发送一个字节;
分析:SCL高电平期间,SDA由高电平变成低电平,产生下降沿,触发起始条件,之后再SCL低电平时,主机将数据首位放在SDA上,在SCL高电平时,从机从SDA进行采样(读取数据),所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节;
接收一个字节时序:
分析:SCL高电平期间,SDA由高电平变成低电平,产生下降沿,触发起始条件,之后再SCL低电平时,从机机将数据首位放在SDA上,在SCL高电平时,主机从SDA进行采样(读取数据),所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节;主机在接受前,需要先释放总线(需要先使总线恢复到空闲状态,然后从机才能拿到掌控权);
发送和接收一个应答位时序:
分析:
发送一个应答位:主机在接收完一个字节之后,在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答;
接收一个应答位:主机发送完数据后,在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放SDA);
一个完整的时序过程:
I2C一主多从的模型,主机可以访问总线上的任何一个设备,通过地址来确定是哪个设备,首先将每个从机确定一个唯一的设备地址,主机在起始条件后,发送一个字节,从机匹配,响应主机,在同一个I2C总线上,从机的地址必须不同;
从机地址在I2C中分为7位和10位地址;
每个芯片在出厂时候,都会设置一个同类型芯片相同,不同类型芯片不同的7位地址;如果在一个I2C总线上接相同的芯片,此时可以根据芯片的最后几位地址,即可变地址,
根据引脚改变,例如高电平则位1101 0000 低电平位1010 0000;
1.3.2示波器时序分析:
时序1:指定地址写
对于指定设备(从机地址),在指定地址(设备内部寄存器地址)下,写入指定数据;
首先产生起始条件,然后发送一个地址字节(七位或者十位基地址,如果是十位需要发送两个字节第一个字节由5位表示十位基地址的标识+3位地址位,第二字节为剩余7位地址位+一位读写标志位,选择从设备和读写方式),发送一位应答位,之后发送设备内部寄存器地址,然后一位应答位,之后发送有效数据位,如果要连续发送数据位,在指定地址下,连续依次向后写入,就依次发送数据,直到数据位发送完毕后,发送一位应答位,最后发送终止条件;
(因为寄存器是在线系空间连续存放的,通过指针进行操作,所以每次读写后,指针自动++,指向下一位地址,要连续操作几位,就可以找到指定地址后,通过连续写入字节即可)
过程:首先处于平稳状态下,SCL和SDA都是处于高电平,主机需要给从机写入数据时候,在SLC高电平期间,拉低SDA,产生起始条件,随后紧跟的时序,必须是发送一个字节的时序,内容必须是7位从机地址加1位读写位;拉低SCL,产生下降沿,主机开始输出数据,SCL低电平时候,主机将数据位依次放在SDA上(高位先行),然后SCL拉高,从机读取SDA上的数据位,读取过程中即SCL高电平期间,SDA不允许改变,循环八次得到的结果是:从机地址:1101 000 写操作: 0(读操作1),数据时序结束后,紧跟着是应答时序,主机需要释放SDA,根据协议规定,从机需要在此时立刻拉低SDA,产生一个信号,给主机,主机判断从机是否应答(根据线与的关系主机释放SDA后,从机立刻下拉SDA,所以SDA依旧保持低电平,这个过程就表示了应答);SCL为高电平时,主机读取数据,判断结果;从机发送完成后,结束对SDA控制,SDA回调至高电平,因为从机要在低电平尽快变化数据,所以SCL下降沿和SDA上升沿同步发送;读写为给的0为写入操作,所以在应答时序完成后,我们立刻要写入一个字节,类似地址发送的方法重复八次(从机可以自己定义第二个字节的用途),重复应答时序,然后在重新重复写入时序,进行应答时序,直到主机结束发送时候,产生停止条件,即先拉带SDA,为后续SDA上升沿做准备,释放SCL,最后释放SDA;形成一个完整的数据帧;
时序2:当前地址读:当前地址读 对于指定设备(Slave Address),在当前地址指针指示的地址下,读取从机数据(Data));
首先产生起始条件,之后发送一个地址字节(设备内部地址(7)+读写标志位(1)),之后读出当前指针指示的地址下的数据;
时序3:指定地址读 对于指定设备(Slave Address),在指定地址(Reg Address)下,读取从机数据(Data)
首先首先产生起始条件,然后发送一个地址字节(七位地址,一位写标志位,选择从设备),发送一位应答位,之后发送设备内部寄存器地址,然后一位应答位,之后重新起始位,再次发送地址字节(七位地址,一位读标志位,选择从设备),在指定地址下,连续依次向后读出;
二、I2C外设;
2.1I2C外设介绍:
I2C外设是STM32内部集成的硬件电路,可以自动执行时钟生成和数据时序的收发,减轻CPU的负担;
硬件自动实现时序,软件只需要写入控制寄存器CR(产生起始条件等),数据寄存器DR(写入读取数据),读取状态寄存器SR(通过标志位判断当前状态);
支持多主机模式;分为固定多主机和可变多主机;
固定多主机即为主机个数固定,从机个数固定,主机掌控数据总线,从机只能通过主机允许才可以短暂的掌控数据总线,当多个主机同时控制总线使用权时,总线进行仲裁,胜利的一方获得总线使用权;
可变多主机,I2C总线上挂在多个设备,没有固定的主机和从机,任何一个设备都可以在总线空闲的时候作为主机,然后指定其他设备进行通信,当通信完成后,主机又变成从机,当多个设备同时申请时,总线进行仲裁,胜利的一方获得总线使用权;
支持7位/10位地址模式;
A.7位地址,起始条件后,第一个时序是必须是寻址+读写位,主机想要通信的从机的七位地址+一位读写位;
B.十位地址则为起始条件后,第一、二个时序是必须是寻址+读写位,是主机想要通信的从机的十位地址+一位读写位,此时俩个时序为15位+读写位共16位,15位由5位的十位地址标志位帧头11110+十位地址组成;
*并且同一个厂商生成的同一种芯片的I2C外挂地址是相同的,如果要在一条I2C总线上挂载俩个相同地址的芯片,可以通过配置芯片的可变地址,即地址的最低位,来配置不同的地址,在一条I2C总线上,不能有相同的地址;
支持不同的通信速度,标准速度(高达100khz),快速(400KHZ);
作为同步时序,只需要不超过最大值即可;
支持DMA;
在多字节操作时候,可以提高效率;
兼容SMbus(系统管理总线)协议;包括CRC码的生成和校验、SMBus(系统管理总线—System Management Bus)和PMBus(电源管理总线—Power Management Bus)主要用于电源管理系统中;。
2.2 I2C外设的结构图;
分析:I2C外设引脚都是通过复用GPIO实现的,具体参考映射表;
数据接收与发送:
数据控制:通过数据控制,控制数据的接收发送,
接收一个数据:当接收一个数据时候,数据一位一位的从SDA输入到移位寄存器中,高位先行
,一位一位的放入数据寄存器中,当一个字节数据接收完毕后,移位寄存器的值会被移入RDR
数据寄存器中,并置标志位RXNE为1,接收寄存器非空,此时可以读取寄存器,获取寄存器中的值;
发送一个数据:把要发送的数据写入数据寄存器TDR中,当移位寄存器为空时,数据寄存器的值会被立刻移入移位寄存器中,并置标志位TXE为1,发送寄存器空,此时新的数据可以存放在数据寄存器中;
比较器,自身地址寄存器和双地址寄存器作用是,当STM32作为从机的时候,即可变多主机模式下,STM32也是可以作为从机与其他主机通信,此时STM32的从机地址通过自身的地址寄存器来配置,当主机通信时,通过比较器判断是否相同,选择是否响应通信;并且支持同时响应俩个从机地址;
帧错误校验计算:I2C自带数据校验;
时钟控制:通过配置时钟控制寄存器,控制时钟控制电路,控制SCL输出的时钟频率;
控制逻辑电路:
中断:当内部某些标志位置1时,可以开启中断执行一些事件;
DMA:可以开启DMA通道转运数据;
通过配置控制寄存器CR1和CR2,实现控制;
通过读取状态寄存器SR1和SR2读取状态,例如TXE,RXNE位;
SMBALERT:
总功能图:
2.3 I2C外设的实现过程;
配置过程:
1.RCC开始GPIO和SPI时钟;
2.初始化GPIO,配置为开漏输出和上拉输入模式;
3.初始化I2C,配置I2C‘
4.使能CMDI2C;
2.4 时序图
主机发送:
过程分析:
起始条件S+寻址+读写标志+数据1+数据2+....+数据N+终止条件p(数据后包括A响应);
首先:初始化后,总线处于空闲状态,STM32默认为从模式,产生起始条件,写入控制寄存器,STM32又从模式转换为主模式,发送EV5事件,即是否产生标志位,产生标志位后即起始条件产生完成,在数据寄存器中写入一个字节的从机地址,数据寄存器转到移位寄存器中,再把这个字节发送到I2C总线上,并硬件自动判断是否应答,可以产生中断标志位,寻址完成后,发送EV6事件,表示地址发送结束,EV6结束,发生EV8_1事件,TXE移位寄存器空,数据寄存器空,此时可以写入数据,写入数据可以因为移位寄存器也为空,此时数据寄存器立马转移数据到移位寄存器,并产生事件EV8,数据寄存器空,移位寄存器非空,TXE=1,数据1时序产生,写入DR清除该事件,接收应答为结束后,然后移位寄存器空,数据寄存器立马转移数据到移位寄存器,并产生事件EV8,一直重复上述过程,直达没有新的数据发送,此时当前移位寄存器完成时,数据寄存器空,移位寄存器也为空,此时事件为EV8_2,标志位TXE1,BTF字节发送结束;
主机接收:
过程:
首先写入控制寄存器DR,S位,产生起始条件S,然后进入EV5事件,表示起始条件已发送,之后寻址,应答,产生EV6事件,代表寻址已完成,数据1代表数据正通过移位寄存器进行输入,EV6_1事件,只适用于接收一个字节接收,接收后,硬件自动发送应答位,当时序结束后,表示移入的一个字节已转移到数据寄存器了,产生EV7事件,即收到了数据,当把数据读走后,该位清除,从重复进行,当不需要接收时候,需要在最后一个时序单元发送时,提前把应答位控制寄存器ACK置0,并设置终止条件请求,即EV7_1事件,完成后给出非应答,产生终止事件P;
五、API实现;
5.1软件模拟I2C实现对MPU的控制;
5.1.1程序规划:
首先明确想实现的功能:通过封装GPIO通信引脚,模拟I2C时序,实现读写MPU;根据功能将程序主要分为三部分:通信层(底层),驱动层(上层),应用层(main)
5.1.1.1建立I2C通信层模块(底层):
1.主要对通信引脚的封装,初始化(GPIO初始化,引脚电平变化封装);
2.以及I2C的三个时序组成部分:起始,终止,交换字节;
5.1.1.2硬件驱动层(上层)
基于I2C通信层模块建立MPU6050模块,在这个模块里调用底层的拼图,组成完整的时序(写使能,擦除,页编程,读数据等)
5.1.1.3应用层
mian函数里调用驱动层函数,实现功能;
5.1.2模块封装
首先建立模块,MYI2C,MPU6050模块对应.c,.h文件,并且包含在文件中,完成基础配置(参考STM32_程序建立)
首先编写第一个模块,I2C底层通信:主要实现功能,初始化GPIO,配置GPIO引脚为开漏输出模式,封装通信引脚,配置时序单元(拼图);
功能:RCC开启GPIOB时钟,初始化GPIOB,配置PB10,11为开漏输出模式,模拟I2C输出,空闲状态下SDA和SCL为高电平(外接电阻上拉至高电平);
参数:无:
返回值:无:
封装通信引脚:
功能:将PB10引脚封装成通信引脚SCL,通过改变PB10的电平,实现模拟I2C输出;
说明:在SMT32主频高,变化快,要求在SCL电平变化时,立刻读走数据,I2C对读取速率有要求,太快无法读取,所以加入延时函数;
参数:高低电平0/1;
返回值:无
功能:将PB11引脚封装成通信引脚SDA,通过改变PB11的电平,实现模拟I2C输出;
参数:高低电平0/1;
返回值:
功能:将PB11引脚封装成通信引脚SDA,通过读取PB11的电平,实现模拟接收从机输入;
参数:无;
返回值:接收到的值;
时序单元:起始条件,终止条件,发送应答位,接收应答位,发送一个字节的数据,接收一个字节的数据;
功能:产生起始条件(空闲条件下,SCL和SDA均为高电平,在SCL高电平时候,SDA由高电平转变为低电平,之后在拉低SCL),标志着时序的开始;
说明:*先将释放SDA,在释放SCL,确保在重复起始条件时,不出错;如果先置SCL高电平,在置SDA高电平,会判断为终止条件;
参数:无
返回值:无
终止条件时序
功能:标志着数据帧的结束/间隔;
说明:(发送数据或者接受数据的最后一位是SCL低电平的时候放在SDA上,高电平时从SDA上读出,之后发送完毕,SCL变为低电平,但是SDA不确定,在此之前需要将SDA先置低电平,能够产生上升沿,之后在SCL高电平时候,SDA由低电平转变为高电平),标志着时序的开始;
参数:无;
返回值:无;
发送一个字节时序
功能:实现主机发送一个字节;
说明:在SCL低电平的时,主机把字节的一位放在SDA上,在SCL高电平时候,从机读取SDA上的数据,起始条件后,SDA为低电平,所以直接放入数据,之后拉高SCL,从机从SDA上读取数据,之后拉低SCL主机放入下一位数据;
参数:要发送的字节;
返回值:无;
接收一个字节的时序:
功能:接收一个字节的时序;
说明:先将释放SDA相当于切换为输入模式,通过低电平写,高电平读,实现读写分离,进来之后SCL是低电平,主机释放SDA,从机把数据放在SDA上,SCL切换为高电平,主机从SDA上读取数据,之后拉低SCL,从机放入下一位数据;
参数:无;
返回值:接收到的数据;
发送应答位
功能:主机发送应答位;
说明:SCL低电平时,主机写入SDA,SCL高电平时,从机接收SDA上的数据,开始SCL低电平,主机放入数据SDA上,随后拉低SCL,从机读取SDA,之后在拉低SCL,写入下一个数据;
参数:发送的应答位;
返回值:无;
接收应答位
功能:从机发送应答位
说明:首先释放SDA,SCL低电平时,从机写入SDA,SCL高电平时,主机接收SDA上的数据,开始SCL低电平,从机放入数据SDA上,随后拉低SCL,主机读取SDA,之后在拉低SCL,写入下一个数据;
参数:无;
返回值:接收的值;
在.H文件中声明:
第一个模块底层通信层封装完成;
下面封装第二个模块硬件驱动层(上层),将底层的时序单元,拼接成一个完整的时序,实现功能;
指定地址写:
功能:对于指定设备(Slave Address),在指定地址(Reg Address)下,写入指定数据(Data);
说明:首先是产生起始条件,触发起始条件后,主机发送的第一个字节是寻址(发送从设地址,选择通信的目标),第二个字节是从设置的寄存器地址,第三个字节是要发送的数据,每次发送后,接收从机的应答位,最后终止条件,时序接收;
参数:1.从设备的寄存器地址;
2.发送的数据;
返回值:无;
指定地址读:
功能:对于指定设备(Slave Address),在指定地址(Reg Address)下,读取从机数据(Data)(Data)
说明:在通过指针对指定地址进行读写操作的,所以先通过在指定地址写,将指针指向我们需要的地址,所以先重复在指定地址写的,首先是产生起始条件,触发起始条件后,主机发送的第一个字节是寻址(发送从设地址,选择通信的目标),第二个字节是从设置的寄存器地址,之后重复起始条件,寻址时,将在指定地址写,改为在指定地址读,通过|,修改最后一位为读;然后直接读取数据,再把发送应答位为1,表示非应答,从机将不会在发送数据;
如果要进阶连续读取多个数据,则将重复读取数据,发送应答位写0,直到最后一位不再需要读取,发送应答位写1;
参数:1.从设备的寄存器地址;
返回值:读到的数据;
如果要进阶连续读取多个数据,则将重复读取数据,发送应答位写0,直到最后一位不再需要读取,发送应答位写1;
读取寄存器不同的位置,获取的内容,参考手册;
要想写入寄存器,首先要解除芯片的睡眠模式,通过写入电源管理寄存器1;
初始化MPU6050
功能:初始化
说明:在初始化之后,要写入一些寄存器,对MP6050硬件电路进行初始化配置;初始化完成后,MPU内部就会进行连续不断的数据转换,输出的数据保存在数据寄存器中;
参数:无;
功能:无;
(使用宏定义修改,这样不用频繁的查看手册,而且直接写入数字,可读性不高)
获取数据寄存器的值:
功能:获取数据寄存器的值,获取XYZ对应的加速度值和陀螺仪值;
说明:定义俩个变量,先读取陀螺仪X轴的高八位,在读取陀螺仪x轴的低八位,再把他们|在一起,的、得到16位数据后,在用指针传递进来的地址,把读到的数据,通过指针返回回去;
参数:无;
功能:返回6个16位的值,分别代表XYZ的加速度值和陀螺仪值;
*因为函数正常只能返回一个返回值,这里需要六个返回值,多返回值的方法:1在函数外定义六个全局变量,子函数读到的数据直接写道全局变量里,六个全局变量在主函数中共享,相当于返回六个值;
2.用指针,进行变量的地址传递,来实现多返回值;
3.用结构体对多个变量进行打包;
使用第二种方法:定义六个指针变量,之后在主函数中定义变量;通过指针,把主函数变量的地址传递到子函数来,子函数通过传递过来的地址,操作主函数的变量,这样子函数结束后,主函数里的变量的值就是子函数想要返回的值;
为什么读取的值是16位——>因为是通过ADC采集电压值,所以是16位(详细可见MPU6050;)
因为接收值是16的,所以八位数据会进行自动强制类型转换,所以左移八位不会出错
因为这些寄存器是连续的,我们可以通过连续读取多个字节,一次性读取14个字节加速度,陀螺仪XYZ数据+两位温度;
在.H文件中声明
测试显示:
根据在MPU6050介绍的模型:1943/32768=x/16g;x大约为1g,测得Z轴加速度值为1g
加速度计模型,我们选择最大量程16g,测得数据是1945,1945/32768
陀螺仪:测得数据/32768=x/16(满量程);
5.2硬件SPI实现对MPU的控制;
将软件改成硬件实现,只需要更改底层通信层代码的操作,驱动层不需要修改,因为他们是调用底层通信函数来实现功能的,这就是代码隔离封装的好处;
主要实现步骤:1.RCC开启GPIO和I2C的时钟;
2.初始化GPIO,将引脚配置成开漏输出;
3.初始化I2C外设;
4.生成时序单元;
5.使能12C;
首先查看库函数:
通过结构体初始化12C;
生成时序:起始条件:查看手册通过配置CR1寄存器的START位;
产生终止条件:
产生应答位:
发送一个字节:
接收一个字节:
发送7位地址:
如果不是写入操作,就把Address最低为置0,否则就置1;(可以用代替函数代替)
查看标志位状态监控:
分为三种:1基本状态监控,同时判断一个或者多个标志位,确定那几个EVEN发生;
2高级状态监控;(把SR1和SR2两个状态寄存器拼接为16的值输出)
3.基于标志位的监控状态;判断某一个标志位;
读取标志位,清除标志位,读取中断标志位,清除中断标志位;
1.RCC开始GPIO和I2C时钟;
2.初始化GPIO,配置输出模式为,AF_OD复用开漏输出,选择引脚PB11和PB10;
3.初始化I2C,配置IC2的应答位,时钟频率,时钟占空比,响应地址位数,I2C作为从设备时的响应地址;
4.使能I2C
因为I2C是低电平,产生下降沿的时候,是强下拉,所以下降沿变化很快,但是输出高电平,是释放,外部上拉电阻产生弱上拉,所以上升沿有一个缓冲,随着时钟频率越来越大,缓冲影响越大,大于100Khz时,我们通过改变占空比,使低电平时间逐渐增多,原因是因为,低电平改变数据,高电平读取数据,数据变化需要一定的时间来翻转波形,所以在快速模式下要给低电平更多的时间,要不低电平来不及数据变化,高电平读取也无效,所以在小于100kHz时,占空比是1:1,大于100kHz时,低电平占空比越来越大;
这就是为什么频率过高的时候,I2C的传输速度会收到限制的原因;
5.时序单元
起始条件:
功能:产生一个起始条件;
参数:无;
返回值:无;
//软件配置我们通过Delay,进行阻塞式的流程,函数运行完后,对于的波形也发送完成,但是硬件生成时,是直接把寄存器对于位进行修改,波形是否完成需要进行标志位判断,根据时序图,进行判断;
参数是指定要检查哪个事件,返回值是SUCCESS表示最后一次事件等于我们指定的事件,ERROR表示不等于;
停止条件:
发送一个字节:
接收一个字节:
不需要应答位,因为在我们发送一个字节和接收一个字节后,硬件会自动产生应答位;
六、实际应用;
相关文章:

STM32——I2C
通信协议见(STM32——SPI) 一、I2C协议 1.1 I2C协议介绍; I2C是(Inter IC Bus)是由Philips公司开发的一种通用数据总线; 有多根通信线; 一根SDA(串行通信线)…...

笔记本从零安装ubuntu server系统+环境配置
文章目录 前言相关链接ubuntu Server 安装教程屏幕自动息屏关上盖子不休眠MobaXterm外网SSH内网穿透IPV6远程 为什么我要笔记本装Linux为什么要换ubuntu Server版能否连接wifi之后Linux 配置清单总结 前言 之前装了个ubuntu desktop 版,发现没有命令行,…...

SQL 快速参考手册
SQL 语句语法AND / ORSELECT column_name(s) FROM table_name WHERE condition AND|OR conditionALTER TABLEALTER TABLE table_name ADD column_name datatype 或者: ALTER TABLE table_name DROP COLUMN column_name AS (alias)SELECT column_name AS column_alia…...

Linux/Windows系统无法git clone解决办法
一、Windows 1. 查找github和githubusercontent的IP地址 IP Tracer & Tracker - IP Address Lookup Made EasyIP Lookup Made Easy Using The Best IP Tracker – Trace An IP, Map The Location & Get Accurate Results When Using The Best IP Finderhttps://www.i…...

【算法与数据结构】198、213、337LeetCode打家劫舍I, II, III
文章目录 一、198、打家劫舍二、213、打家劫舍 II三、337、打家劫舍III三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、198、打家劫舍 思路分析:打家劫舍是动态规划的的经典题目。本题的难点在于递归公式…...

React、React Router、JSX 简单入门快速上手
React、React Router、JSX 简单入门快速上手 介绍特点 JSX使用js表达式渲染列表样式控制注意事项 入门脚手架创建react项目安装目录介绍入口文件解析 组件解析介绍函数式组件类组件 事件绑定注意点定义使用事件对象事件处理函数接收额外参数 组件状态状态的定义使用 组件通信父…...

从 0 开始搭建 React 框架
webpack 配置 不再赘述,可参考前三个文章(wenpack5 基本使用 1 - 3) 使用 react 安装 react、react-dom、babel/preset-react yarn add react react-dom babel/preset-react<!DOCTYPE html> <html lang"en"> <h…...

网站地址怎么改成HTTPS?
现在,所有类型的网站都需要通过 HTTPS 协议进行安全连接,而实现这一目标的唯一方法是使用 SSL 证书。如果您不将 HTTP 转换为 HTTPS,浏览器和应用程序会将您网站的连接标记为不安全。 但用户询问如何将我的网站从 HTTP 更改为 HTTPS。在此页…...

Blender教程(基础)-面的细分与删除、挤出选区-07
一、Blender之面的细分 新建一个立方体,在编辑模式下、选中一个面。 在选中的面上单击右键弹出细分选项,选择细分。 在选中细分后、会默认细分1次。修改细分次数在左下角 二、Blender之面的删除 选择中需要操作的面,在英文状态下按X键弹…...

QT自制软键盘 最完美、最简单、支持中文输入(二)
目录 一、前言 二、本自制虚拟键盘特点 三、中文输入原理 四、组合键输入 五、键盘事件模拟 六、界面 七、代码 7.1 frmKeyBoard 头文件代码 7.2 frmKeyBoard 源文件代码 八、使用示例 九、效果 十、结语 一、前言 由于系统自带虚拟键盘不一定好用,也不一…...

SpringCloud_学习笔记_1
SpringCloud01 1.认识微服务 随着互联网行业的发展,对服务的要求也越来越高,服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢? 1.0.学习目标 了解微服务架构的优缺点 1.1.单体架构 单体架构ÿ…...

容器算法迭代器初识
#include<iostream> using namespace std; #include<vector> //vetor容器存放内置数据类型 void test01() {//创建了一个vector容器,数组 vector<int> v;//向容器中插入数据v.push_back (10);//尾插 v.push_back (20);v.push_back (30);v.push_ba…...

瑞_力扣LeetCode_二叉搜索树相关题
文章目录 说明题目 450. 删除二叉搜索树中的节点题解递归实现 题目 701. 二叉搜索树中的插入操作题解递归实现 题目 700. 二叉搜索树中的搜索题解递归实现 题目 98. 验证二叉搜索树题解中序遍历非递归实现中序遍历递归实现上下限递归 题目 938. 二叉搜索树的范围和题解中序遍历…...

python爬虫爬取网站
流程: 1.指定url(获取网页的内容) 爬虫会向指定的URL发送HTTP请求,获取网页的HTML代码,然后解析HTML代码,提取出需要的信息,如文本、图片、链接等。爬虫请求URL的过程中,还可以设置请求头、请求参数、请求…...

c# Get方式调用WebAPI,WebService等接口
/// <summary> /// 利用WebRequest/WebResponse进行WebService调用的类 /// </summary> public class WebServiceHelper {//<webServices>// <protocols>// <add name"HttpGet"/>// <add name"HttpPost"/>// …...

银行数据仓库体系实践(11)--数据仓库开发管理系统及开发流程
数据仓库管理着整个银行或公司的数据,数据结构复杂,数据量庞大,任何一个数据字段的变化或错误都会引起数据错误,影响数据应用,同时业务的发展也带来系统不断升级,数据需求的不断增加,数据仓库需…...

微信小程序引导用户打开定位授权通用模版
在需要使用位置信息的页面(例如 onLoad 或 onShow 生命周期函数)中调用 wx.getSetting 方法检查用户是否已经授权地理位置权限: Page({onLoad: function() {wx.getSetting({success: res > {if (res.authSetting[scope.userLocation]) {/…...

JVM篇----第十篇
系列文章目录 文章目录 系列文章目录前言一、JAVA 强引用二、JAVA软引用三、JAVA弱引用四、JAVA虚引用五、分代收集算法前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧…...

DevSecOps 参考模型介绍
目录 一、参考模型概述 1.1 概述 二、参考模型分类 2.1 DevOps 组织型模型 2.1.1 DevOps 关键特性 2.1.1.1 模型特性图 2.1.1.2 特性讲解 2.1.1.2.1 自动化 2.1.1.2.2 多边协作 2.1.1.2.3 持续集成 2.1.1.2.4 配置管理 2.1.2 DevOps 生命周期 2.1.2.1 研发过程划分…...

什么是okhttp?
OkHttp简介: OkHttp 是一个开源的、高效的 HTTP 客户端库,由 Square 公司开发和维护。它为 Android 和 Java 应用程序提供了简单、强大、灵活的 HTTP 请求和响应的处理方式。OkHttp 的设计目标是使网络请求变得更加简单、快速、高效,并且支持…...

R语言基础学习-02 (此语言用途小众 用于数学 生物领域 基因分析)
变量 R 语言的有效的变量名称由字母,数字以及点号 . 或下划线 _ 组成。 变量名称以字母或点开头。 变量名是否正确原因var_name2.正确字符开头,并由字母、数字、下划线和点号组成var_name%错误% 是非法字符2var_name错误不能数字开头 .var_name, var.…...

CTF-WEB的入门真题讲解
EzLogin 第一眼看到这个题目我想着用SQL注入 但是我们先看看具体的情况 我们随便输入admin和密码发现他提升密码不正确 我们查看源代码 发现有二个不一样的第一个是base64 意思I hava no sql 第二个可以看出来是16进制转化为weak通过发现是个弱口令 canyouaccess 如果…...

【C项目】顺序表
简介:本系列博客为C项目系列内容,通过代码来具体实现某个经典简单项目 适宜人群:已大体了解C语法同学 作者留言:本博客相关内容如需转载请注明出处,本人学疏才浅,难免存在些许错误,望留言指正 作…...

【Docker】在Windows下使用Docker Desktop创建nginx容器并访问默认网站
欢迎来到《小5讲堂》,大家好,我是全栈小5。 这是《Docker容器》序列文章,每篇文章将以博主理解的角度展开讲解, 特别是针对知识点的概念进行叙说,大部分文章将会对这些概念进行实际例子验证,以此达到加深对…...

详讲api网关之kong的基本概念及安装和使用(二)
consul的服务注册与发现 如果不知道consul的使用,可以点击上方链接,这是我写的关于consul的一篇文档。 upstreamconsul实现负载均衡 我们知道,配置upstream可以实现负载均衡,而consul实现了服务注册与发现,那么接下来…...

取消Vscode在输入符号时自动补全
取消Vscode在输入符号时自动补全 取消Vscode在输入符号时自动补全问题演示解决方法 取消Vscode在输入符号时自动补全 问题演示 在此状态下输入/会直接自动补全, 如下图 笔者想要达到的效果为可以正常输入/而不进行补全, 如下图 解决方法 在设置->文本编辑器->建议, 取消…...

ElementUI Form:Input 输入框
ElementUI安装与使用指南 Input 输入框 点击下载learnelementuispringboot项目源码 效果图 el-input.vue 页面效果图 项目里el-input.vue代码 <script> export default {name: el_input,data() {return {input: ,input1: ,input2: ,input3: ,input4: ,textarea: …...

Vue_Router_守卫
路由守卫:路由进行权限控制。 分为:全局守卫,独享守卫,组件内守卫。 全局守卫 //创建并暴露 路由器 const routernew Vrouter({mode:"hash"//"hash路径出现#但是兼容性强,history没有#兼容性差"…...

GDB调试技巧实战--自动化画出类关系图
1. 前言 上节我们在帖子《Modern C++利用工具快速理解std::tuple的实现原理》根据GDB的ptype命令快速的理解了std::tuple数据结构的实现,但是手动一个个打印,然后手动画出的UML图,这个过程明显可以自动化。 本文旨在写一个GDB python脚本把这个过程自动化。 本脚本也可以用…...

python使用Schedule
目录 一:使用场景: 二:参数 三:实例 "Schedule"在Python中通常指的是时间调度或任务计划。Python中有多个库可以用来处理时间调度和任务计划,其中最流行的是schedule库。 一&#x…...