STM32标准库——(17)硬件SPI读写W25Q64

1.SPI外设简介

时钟频率就是sck波形的频率,一个sck时钟交换一个bit,所以时钟频率一般体现的是传输速度,单位是Hz或者bit/s,那这里的时钟频率是fPCLK除以一个分频系数分频系数可以配置为2或4或8、16、32、64、128、256,所以可以看出来,spi的时钟其实就是由pclk分频得来的,pclk就是外设时钟,APB2的pclk就是72MHz,APB1的pclk是36MHz,比如我们的spi1是APB2的外设,pclk等于72MHz,那它的spi时钟频率最大就是只进行二分频=36MHz,像我们之前I2C的频率最大就只有400KHz,所以这里spi的最大频率比I2C快了90倍,然后这里频率有些注意事项,一是这个频率数值并不是任意指定的,它只能是pclk执行分频后的数值就只有这八个选项,最低频率是pclk的256分频,二是spi1和spi2 挂载的总线是不一样的,spi1挂载在APB2,pclk是72MHz,spi1挂载在APB1,pclk是36MHz,所以同样的配置,spi1的时钟频率要比spi2的大一倍。

2.SPI框图

  1. 首先左上角核心部分就这个移位寄存器,右边的数据低位,一位一位的从mosi移出去,然后miso的数据一位一位的移入到左边的数据高位,显然移位寄存器应该是一个右移的状态,所以目前图上表示的是低位先行的配置,对应右下角有一个LSBFIRST的控制位,这一位可以控制是低位先行还是高位先行,手册里寄存器描述可以查一下,这里LSBFIRST帧格式,给0先发送msb,msb就是高位的意思,给1先发送lsb ,lsb就是低位的意思,那ppt这里目前的状态LSBFIRST的应该是1,低位先行,如果LSBFIRST给零高位先行的话,这个图还要变动一下,就是移位寄存器变为左移,输出,从左边移出去,输入,从右边移进来,这样才符合逻辑,然后继续看左边这一块,这里画了个方框,里面把mosi和miso做了个交叉,这一块主要是用来进行主从模式引脚变换的,我们这个spi外设可以做主机,也可以做从机,做主机时这个交叉就不用,mosi为mo,主机输出,miso为mi,主机输入,这是主机的情况,如果我们stm32作为从机的话,mosi为si,从机输入,这时他就要走交叉的这一路,输入到移位寄存器,同理miso为so,从机输出,这时输出的数据也走交叉的这一路输出到miso。
  2. 接下来上下两个缓冲区,就还是我们熟悉的设计,这两个缓冲区实际上就是数据寄存器DR,下面发送缓冲区就是发送数据寄存器TDR,上面接收缓冲区就是接收数据寄存器RDR,和串口那里一样,TDR和RDR占用同一个地址统一叫做DR,写入DR时数据从这里写入到TDR,读取DR时,数据从这里从RDR读出,数据寄存器和移位寄存器打配合,可以实现连续的数据流,具体流程就是比如我们需要连续发送一批数据,第一个数据写入到TDR当移位寄存器没有数据移位时TDR的数据会立刻转入移位寄存器开始移位,这个转入时刻,会置状态寄存器的TXE为1表示发送寄存器空当我们检查TXE置1后,紧跟着下一个数据就可以提前写入到TDR里侯着了,一旦上个数据发完,下一个数据就可以立刻跟进,实现不间断的连续传输,然后移位寄存器,这里一旦有数据过来了,它就会自动产生时钟将数据移出去,在移出的过程中,miso的数据也会移入,一旦数据移出完成,数据移入是不是也完成了,这时移入的数据就会整体的从移位计算器转入到接收缓冲区RDR,这个时刻会置状态寄存器器的RXNE为1,表示接收计寄存器器非空当我们检查RXNE置1后,就要尽快把数据从RDR读出来,在下一个数据到来之前,读出RDR就可以实现连续接收,否则如果下一个数据已经收到了,上个数据还没从RDR读出来,那RDR的数据就会被覆盖,就不能实现连续的数据流了。和之前串口、I2C的都差不多的,当然这三者也是有一些区别的,比如这里spi全双工发送和接收同步进行,所以它的数据寄存器发送和接收是分离的,而移位寄存器发送和接收可以共用;然后看一下前面I2C的框图,因为I2C是半双工发送和接收不会同时进行,所以它的数据寄存器和移位寄存器,发送和接收都可以是共用的;串口是全双工,并且发送和接收可以异步进行,所以这就要求它的数据寄存器,发送和接收是分离的,移位寄存器发送和接收也得是分离的。
  3. 接着后面这些通信电路和各种寄存器,都是一些黑盒子电路,如果你要具体研究,可以看一下这些位的寄存器描述,我挑几个重点的讲一下,比如LSBFIRST的刚才说过,决定高位先行还是低位先行spe是spi使能,就是SPI_Cmd函数配置的位BR配置波特率,就是sck时钟频率MSTR(Master),配置主从模式,1是主模式,0是从模式,我们一般用主模式cpul和cpha,这个之前讲过,用来选择spi的四种模式,然后这里sr状态计算器,最后两个txe发送寄存器空,rxne接收寄存器非空,这两个比较重要,我们发送接收数据的时候需要关注这两位,最后CR2寄存器就是一些使能位了,比如中断使能dma使能等。
  4. 最后这里还有一个NSS引脚,ss就是从机选择,低电平有效,所以这里前面加了个n,这个nss和我们想象的从机选择可能不太一样,我们想象的应该是用来指定某个从机对吧,但是根据手册里的描述,我也研究了一下,这里的nss设计,可能更偏向于实现这里说的多主机模型,总的来说啊,这个NSS我们并不会用到,SS引脚我们直接使用一个gpio模拟就行,因为ss引脚很简单,就置一个高低电平就行了,而且从机的情况下,ss还会有多个,这里硬件的nss也完成不了我们想要的功能,那这个nss是如何实现多主机切换的功能呢,假如这里有三个stm32设备,我们需要把这三个设备的nss全都连接在一起,首先这个nss可以配置为输出或者输入,当配置为输出时,可以输出电平告诉别的设备,我现在要变为主机,你们其他设备都给我变从机,不要过来捣乱,当配置为输入时,可以接收别设备的信号当有设备是主机拉低nss后,我就无论如何也变不成主机了,这就是它的作用,然后内部电路的设计,当这里这个ssoe等于1时,nss作为输出引脚,并在当前设备变为主设备时,给nss输出低电平,这个输出的低电平,就是告诉其他设备,我现在是主机了,当主机结束后,ssoe要清0,nss变为输入,这时输入信号就会跑到右边这里,这个数据选择器ssm位决定选择哪一路,当选择上面一路时是硬件nss模式,也就是说这时外部如果输入了低电平,那当前的设备就进入不了主模式了,因为nss低电平肯定是,外部已经有设备进入了主模式,他已经提前告诉我他是主模式了,我就不能再跟大家抢了,当数据选择器选择下面一路时,是软件管理nss输入,nss是1还是2,由这一位SSI来决定,这个就是nss实现多主机的思路,但这个设计是nss作为多从机选择的作用消失了,揪出所有人的小辫子之后,主机发送的数据就只能是广播发送给所有人的,如果想实现指定设备通信,可能还需要再加入寻址机制。

3.SPI基本结构

4.主模式传输

4.1 连续传输

  • 第一行是sck时钟线,这里cpol等于1,cpha等于1,示例使用的是spi模式三,所以sck默认是高电平,然后在第一个下降沿mosi和miso移出数据,之后上升沿引入数据,依次这样来进行,那下面第二行是mosi和miso输出的波形,跟随sck时钟变化,数据位依次出现,这里从前到后依次出现的是b0b1一直到b7 ,所以这里示例演示的是低位先行的模式啊,实际spi高位先行用的多一些,最后第三行是txe发送寄存器空标志位,下面发送缓冲器括号写入SPI_DR,实际上就是这里的TDR然后bsy(busy)是由硬件自动设置和清除的当有数据传输时,busy置1那上面红框这部分演示的就是输出的流程和现象,然后下面红框是输入的流程和现象,第一个是miso/mosi的输入数据,之后是RXNE接收数据寄存器非空标志位最后是接收,缓冲器读出SPI_DR,显然这里就是RDR

  • 首先ss置低电平开始时序,这个没画但是必须得有的,在刚开始时TXE为1,表示TDR空可以写入数据开始传输,然后下面指示的第一步就是软件写入0xf1至SPI_DR,0xf1就是要发送的第一个数据,之后可以看到写入之后TDR变为0xf1 ,同时txe变为0,表示tdr已经有数据了,那此时dr是等候区,移位寄存器才是真正的发送区,移位寄存器刚开始肯定没有数据,所以在等候区TDR里的f1 ,就会立刻转入移位寄存器开始发送转入瞬间置txe标志位为1,表示发送寄存器空,然后移位寄存器有数据了,波形就自动开始生成,当然我感觉这里画的数据波形时机可能有点早,应该是在这个时刻b0的波形才开始产生,在这之前数据还没有转入移位进器,所以感觉b0出现的可能过早了,不过这个也不影响我们理解,大家知道这意思就行好了,这样数据转入移位寄存器之后,数据F1的波形就开始产生了,在移位产生f1波形的同时,等候区tdr是空的,为了移位完成时,下一个数据能不间断的跟随,这里我们就要提早把下一个数据写入到TDR里等着了,所以下面只是第二步的操作,是写入F1之后,软件等待TXE等于1,在这个位置,一旦tdr空了,我们就写入F2至SPI_DR,写入之后可以看到tdr的内容就变成F2了,也就是把下一个数据放到tdr里,后者之后的发送流程也是同理,最后在这里如果我们只想发送三个数据,F3转入移位寄存器之后,TXE等于1,我们就不需要继续写入了,txe之后一直是1,注意在最后一个TXE等于1之后,还需要继续等待一段时间,f3的波形才能完整发送完,等波形全部完整发送之后,busy的标志由硬件清除,这才表示波形发送完成了,那这些就是发送的流程,然后继续看一下下面接收的流程,SPI是全双工,发送的同时还有接收,所以可以看到在第一个字节发送完成后,第一个字节的接收也完成了,接收到的数据1是A1 ,这时移位寄存器的数据整体转入RDR,RDR随后存储的就是A1 ,转入的同时按RXNE标志位也置1,表示收到数据了,我们的操作是下面这里写的,软件等待RXNE等于1,=1表示收到数据了,然后从SPI_DR也是RDR读出数据A1 ,这是第一个接收到的数据,接收之后软件清除RXNE标志位,然后当下一个数据2收到之后,RXNE重新置1,我们监测到RXNE等于1时就继续读出RDR,这是第二个数据A2 ,最后在最后一个字节时序完全产生之后,数据三才能收到,所以数据3,直到这里才能读出来,然后注意,一个字节波形收到后,移位寄存器的数据自动转入RDR,会覆盖原有的数据,所以我们读出rdr要及时,比如A1这个数据收到之后,最迟你也要在这里把它读走,否则下一个数据A2覆盖A1,就不能实现连续数据流的接收了。

4.2 非连续传输

配置还是spi模式三,sck默认高电平,我们想发送数据时如果检测到TXE等于1了,TDR为空,就软件写入0xF1至SPI_DR,这时TDR的值变为F1,TXE变为0,目前移位寄存器也是空,所以这个F1会立刻转入移位寄存器,开始发送,波形产生并且,TXE置回1,表示你可以把下一个数据放在tdr里侯着了,但是现在区别就来了,在连续传输这里一旦,TXE等于1了,我们就会把下个数据写到tdr里侯着这样是为了连续传输数据衔接更紧密,但是刚才说了,这样的话,流程就比较混乱,程序写起来比较复杂,所以在非连续传输这里,TXE等于1了,我们不着急把下一个数据写进去,而是一直等待,等第一个字节时序结束,在这个位置时序结束了,意味着接收第一个字节也完成了,这时接收的RXNE会置一,我们等待RXNE置1后,先把第一个接收到的数据读出来,之后再写入下一个字节数据,也就是这里的软件等待TXE等于1,但是较晚写入0xf2SPI_DR,较晚写入TDR后,数据二开始发送,我们还是不着急写数据三,等到了这里,先把接收的数据二收着,再继续写入数据3,数据3时序结束后,最后再接收数据三置换回来的数据,你看按照这个流程的话,我们的整个步骤就是第一步等待TXE为一,第二步写入发送的数据至TDR,第三步等待RXNE为一,第四步读取RDR接收的数据,之后交换第二个字节,重复这四步,那这样我们就可以把这四部分装到一个函数,调用一次交换一个字节,这样程序逻辑是不是就非常简单了,和之前软件spi的流程基本上是一样的,我们只需要稍作修改,就可以把软件spi改成硬件spi,那非连续算出缺点,就是在这个位置没有及时把下一个数据写入TDR侯着,所以等到第一个字节时序完成后,第二个字节还没有送过来,那这个数据传输就会在这里等着,所以这里时钟和数据的时序,在字节与字节之间会产生间隙,拖慢了整体数据传输的速度这个间隙在sck频率低的时候影响不大,但是在sck频率非常高时隙拖后腿的现象就比较严重了。

5.软/硬件波形对比

6.常用API

6.1 SPI_I2S_SendData

/*** @brief  Transmits a Data through the SPIx/I2Sx peripheral.* @param  SPIx: where x can be*   - 1, 2 or 3 in SPI mode *   - 2 or 3 in I2S mode* @param  Data : Data to be transmitted.* @retval None*/
void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data)
功能:通过外设 SPIx 发送一个数据
参数:SPIx:x 可以是 1 或者 2,来选择 SPI 外设Data: 待发送的数据
返回值:无       

6.2 SPI_I2S_ReceiveData

/*** @brief  Returns the most recent received data by the SPIx/I2Sx peripheral. * @param  SPIx: where x can be*   - 1, 2 or 3 in SPI mode *   - 2 or 3 in I2S mode* @retval The value of the received data.*/
uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx)
功能:返回通过 SPIx 最近接收的数据
参数:SPIx:x 可以是 1 或者 2,来选择 SPI 外设
返回值:接收到的字       

6.3 SPI_I2S_GetFlagStatus

/*** @brief  Checks whether the specified SPI/I2S flag is set or not.* @param  SPIx: where x can be*   - 1, 2 or 3 in SPI mode *   - 2 or 3 in I2S mode* @param  SPI_I2S_FLAG: specifies the SPI/I2S flag to check. *   This parameter can be one of the following values:*     @arg SPI_I2S_FLAG_TXE: Transmit buffer empty flag.*     @arg SPI_I2S_FLAG_RXNE: Receive buffer not empty flag.*     @arg SPI_I2S_FLAG_BSY: Busy flag.*     @arg SPI_I2S_FLAG_OVR: Overrun flag.*     @arg SPI_FLAG_MODF: Mode Fault flag.*     @arg SPI_FLAG_CRCERR: CRC Error flag.*     @arg I2S_FLAG_UDR: Underrun Error flag.*     @arg I2S_FLAG_CHSIDE: Channel Side flag.* @retval The new state of SPI_I2S_FLAG (SET or RESET).*/
FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)
功能:检查指定的 SPI 标志位设置与否
参数:SPIx:x 可以是 1 或者 2,来选择 SPI 外设SPI_I2S_FLAG:待检查的 SPI 标志位
返回值:SPI_FLAG 的新状态(SET 或者 RESET)  

6.4 SPI_I2S_ClearFlag

/*** @brief  Clears the SPIx CRC Error (CRCERR) flag.* @param  SPIx: where x can be*   - 1, 2 or 3 in SPI mode * @param  SPI_I2S_FLAG: specifies the SPI flag to clear. *   This function clears only CRCERR flag.* @note*   - OVR (OverRun error) flag is cleared by software sequence: a read *     operation to SPI_DR register (SPI_I2S_ReceiveData()) followed by a read *     operation to SPI_SR register (SPI_I2S_GetFlagStatus()).*   - UDR (UnderRun error) flag is cleared by a read operation to *     SPI_SR register (SPI_I2S_GetFlagStatus()).*   - MODF (Mode Fault) flag is cleared by software sequence: a read/write *     operation to SPI_SR register (SPI_I2S_GetFlagStatus()) followed by a *     write operation to SPI_CR1 register (SPI_Cmd() to enable the SPI).* @retval None*/
void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)
功能:清除 SPIx 的待处理标志位
参数:SPIx:x 可以是 1 或者 2,来选择 SPI 外设SPI_I2S_FLAG:待清除的 SPI 标志位
返回值:无

7.接线图

 

8.相关代码

8.1 MySPI.c

#include "stm32f10x.h"                  // Device header/*** 函    数:SPI写SS引脚电平,SS仍由软件模拟* 参    数:BitValue 协议层传入的当前需要写入SS的电平,范围0~1* 返 回 值:无* 注意事项:此函数需要用户实现内容,当BitValue为0时,需要置SS为低电平,当BitValue为1时,需要置SS为高电平*/void MySPI_W_SS(uint8_t BitValue)
{GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue);		//根据BitValue,设置SS引脚的电平
}/*** 函    数:SPI初始化* 参    数:无* 返 回 值:无* 注意事项:此函数需要用户实现内容,实现SS、SCK、MOSI和MISO引脚的初始化*/
void MySPI_Init(void)
{/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);	//开启SPI1的时钟/*GPIO初始化*/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);					//将PA4引脚初始化为推挽输出 SS是软件控制的输出信号 配置通用推挽输出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);					//将PA5和PA7引脚初始化为复用推挽输出 MOSI和SCK是外设输出的控制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);					//将PA6引脚初始化为上拉输入 SPI_InitTypeDef SPI_InitStructure;SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;		//波特率分频,选择128分频SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;			//SPI相位,选择第一个时钟边沿采样,极性和相位决定选择SPI模式0 1Edge代表CPHA=0 2Edge代表CPHA=1SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;				//SPI极性,选择低极性 这里46和45配合使用模式0 都需要配置低电平SPI_InitStructure.SPI_CRCPolynomial = 7;				//CRC多项式,暂时用不到,给默认值7SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;		//数据宽度,选择为8位SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;		//先行位,选择高位先行 49和48行常用8位高位先行 在SPI外设简介提到SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;		//方向,选择2线全双工SPI_InitStructure.SPI_Mode = SPI_Mode_Master;			//模式,选择为SPI主模式SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;				//NSS,选择由软件控制SPI_Init(SPI1,&SPI_InitStructure);SPI_Cmd(SPI1,ENABLE);MySPI_W_SS(1);
}/*** 函    数:SPI起始* 参    数:无* 返 回 值:无*/
void MySPI_Start(void)
{MySPI_W_SS(0);				//拉低SS,开始时序
}/*** 函    数:SPI终止* 参    数:无* 返 回 值:无*/
void MySPI_Stop(void)
{MySPI_W_SS(1);				//拉高SS,终止时序
}/*** 函    数:SPI交换传输一个字节,使用SPI模式0* 参    数:ByteSend 要发送的一个字节* 返 回 值:接收的一个字节*/
uint8_t MySPI_SwapByte(uint8_t ByteSend)
{while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) != SET);		//等待发送数据寄存器空SPI_I2S_SendData(SPI1,ByteSend);								//写入数据到发送数据寄存器,开始产生时序while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) != SET);	//等待接收数据寄存器非空return SPI_I2S_ReceiveData(SPI1);								//读取接收到的数据并返回
}

8.2 MySPI.h

#ifndef __MYSPI_H
#define __MYSPI_Hvoid MySPI_Init(void);
void MySPI_Start(void);
void MySPI_Stop(void);
uint8_t MySPI_SwapByte(uint8_t ByteSend);#endif

8.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);		//显示DID/*W25Q64功能函数测试*/W25Q64_SectorErase(0x000000);					//扇区擦除W25Q64_PageProgram(0x000000, ArrayWrite, 4);	//将写入数据的测试数组写入到W25Q64中W25Q64_ReadData(0x000000, ArrayRead, 4);		//读取刚写入的测试数据到读取数据的测试数组中/*显示数据*/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){}
}

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

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

相关文章

C++核心编程之内存分区模型,引用,函数提高

1,类型分区模型 c程序在执行中,将内存大方向划分为4个区域 1,代码区:存放函数体的二进制代码,由操作系统进行管理的 2,全局区:存放全局变量和静态变量以及常量 3,栈区&#xff1…

基于SSM的学科竞赛管理系统。Javaee项目。ssm项目。

演示视频: 基于SSM的学科竞赛管理系统。Javaee项目。ssm项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构,通过Spring SpringMvcMybatisVueLayuiElemen…

MP2494图纸 国产替代型号SC72001宽工作输入电压范围:4.5V 至 80V

MP2494 是一款单片降压开关变换器。它在宽输入范围内可实现 2A 连续输出电流,具有出色的负载和线性调整率。其控制良好的开关沿降低了 EMI 干扰。故障保护功能包括逐周期限流保护和过温关断保护。MP2494 最大限度地减少了现有标准外部元器件的使用。MP2494采用SOIC8…

win系统如何同时安装MySQL5和MySQL8

win系统如何同时安装MySQL5和MySQL8 文章目录 win系统如何同时安装MySQL5和MySQL81、准备好两种版本的数据库2、下载后解压到你指定的目录3、手动配置安装MySQL5和8安装MySQL53.1创建my.ini文件3.2生成data文件夹 安装MySQL83.1创建my.ini文件3.2生成data文件夹 4、配置环境变量…

面试高频率问答题目

索引: 主键索引:表的id (唯一 且 不能为空) 唯一索引:表User 假设有account 字段 ,用户名不重复 (唯一 可以为空) 复合索引:where() 的条件 用户名,密码 …

计算机组成原理----数据的表示和运算

一:进位计数制 1、进制 B:二进制:0-1 逢二进一、借一当二 O:八进制:0-7 逢八进一 D:十进制:0-9 逢十进一 H:十六进制:0-9、A-F 逢十六进一 r进制2 2、…

Cohere

文章目录 关于 cohere公司介绍目标:构建大模型基础设施产品商业模式 API 使用基于 Cohere AI 实现语义搜索 关于 cohere PYPI : https://pypi.org/project/cohere官网 : https://cohere.comgithub : https://github.com/cohere-ai/cohere-python文档:ht…

【2024】vue-router和pinia的配置使用

目录 vue-routerpiniavue-routerpinia进阶用法---动态路由 有同学在项目初始化后没有下载vue-router和pinia,下面开始: vue-router npm install vue-router然后在src目录下创建文件夹router,以及下面的index.ts文件: 写进下面的…

python--产品篇--游戏-坦克

文章目录 准备代码main.pycfg.py 效果 准备 下载 代码 main.py import os import cfg import pygame from modules import *主函数 def main(cfg):# 游戏初始化pygame.init()pygame.mixer.init()screen pygame.display.set_mode((cfg.WIDTH, cfg.HEIGHT))pygame.display.…

CHI协议学习

原始文档:https://developer.arm.com/documentation/102407/0100/?langen CHI 总线拓扑结构 CHI总线拓扑是实现自定义的,可以是RING/MESH/CROSSBAR的类型; RING 一般适用于中等规模芯片MESH 一般适用于大规模芯片CROSSBAR 一般适用于小规模…

工具函数模板题(蓝桥杯 C++ 代码 注解)

目录 一、Vector容器: 二、Queue队列 三、Map映射 四、题目(快递分拣 vector): 代码: 五、题目(CLZ银行问题 queue): 代码: 六、题目(费里的语言 map&…

【Spring底层原理高级进阶】Spring Kafka:实时数据流处理,让业务风起云涌!️

🎉🎉欢迎光临🎉🎉 🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀 🌟特别推荐给大家我的最新专栏《Spring 狂野之旅:从入门到入魔》 🚀 本…