当前位置: 首页 > news >正文

【GD32F303红枫派使用手册】第十九节

19.1 实验内容

通过本实验主要学习以下内容:

  • SPI简介
  • GD32F303 SPI简介
  • SPI NOR FLASH——GD25Q32ESIGR简介
  • 使用GD32F303 SPI接口实现对GD25Q32ESIGR的读写操作

19.2 实验原理

19.2.1 SPI简介

SPI(Serial Peripheral interface),顾名思义是串行外设接口,和UART不同的是,SPI是同步通讯接口,所以带有时钟线,而UART是异步通讯接口,不需要时钟线。

SPI通常使用4根线,分别为SCK、MOSI、MISO、NSS(CS):

  • SCK:串列时脉,由主机发出
  • MOSI:主机输出从机输入信号(数据由主机发出)
  • MISO:主机输入从机输出信号(数据由从机发出)
  • NSS:片选信号,由主机发出,一般是低电位有效

SPI默认为全双工工作,在这种工作模式下,主机通过MOSI线发送数据的同时,也在MISO线上接受数据,简单来说就是主机和从机之间进行数据交换。

SPI是一个可以实现一主多从的通讯接口,从机的片选由主机NSS脚来控制:

每个通讯时刻,只有一个从机NSS被主机选中,选中方式为主机拉低响应的NSS(CS)脚。

SPI的数据线只有一条(虽然有MOSI和MISO,但实际上每个CLK主机都只能发送和接受一个bit),所以称之为单线SPI。从SPI衍生出来的还有4线制SPI(QSPI)和8线制SPI(OSPI)以及其他多线制SPI,这个我们后面具体再聊。

19.2.2 GD32F303 SPI简介

GD32F303的主要特性如下:

◼ 具有全双工和单工模式的主从操作;
◼ 16位宽度,独立的发送和接收缓冲区;
◼ 8位或16位数据帧格式;
◼ 低位在前或高位在前的数据位顺序;
◼ 软件和硬件NSS管理;
◼ 硬件CRC计算、发送和校验;
◼ 发送和接收支持DMA模式;
◼ 支持SPI TI模式;
◼ 支持SPI NSS脉冲模式
◼ 支持SPI四线功能的主机模式(仅在SPI0中)   

以下为GD32F303 SPI的框图:

我们可以看到GD32F303有一个发送缓冲区和一个接受缓冲区这两个缓冲区都对应的是SPI_DATA寄存器,向SPI_DATA寄存器写数据将会把数据存入发送缓冲区,从SPI_DATA读数据,将从接受缓冲区获得数据。GD32F303还有一个移位寄存器,当主机发送缓冲区被写入数据时,数据将立刻转移到移位寄存器,移位寄存器通过 MOSI 信号线将字节传送给从机,从机也将自己的移位寄存器中的内容通过 MISO 信号线返回给主机。这样,两个移位寄存器中的内容就被交换。外设的写操作和读操作是同步完成的。如果只进行写操作,主机只需忽略接收到的字节;反之,若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的传输。

SPI数据bit在CLK的有效边沿被锁存,而有效边沿是可以选择的,分别为:

  • 第一个上升沿
  • 第一个下降沿
  • 第二个下降沿
  • 第二个上升沿

通过SPI_CTL0寄存器中的CKPL位和CKPH位来设置有效锁存沿。其中CKPL 位决定了空闲状态时 SCK 的电平, CKPH 位决定了第一个或第二个时钟跳变沿为有效采样边沿。SPI_CTL0 中的 LF 位可以配置数据顺序, 当 LF=1 时, SPI 先发送 LSB 位,当LF=0时,则先发送 MSB 位。SPI_CTL0 中的 FF16 位配置数据长度, 当 FF16=1 时,数据长度为 16位,否则为 8 位。下图为SPI的时序图:

4线SPI(QSPI)的时序图如下(CKPL=1, CKPH=1, LF=0)  ,我们可以看到QSPI是通过MOSI、MISO、IO2、IO3来进行数据收或发,所以QSPI是工作在半双工模式:

这里再介绍下SPI的NSS(片选)功能。NSS电平由主机来控制,主机将需要操作的从机NSS拉低,从而使该从机在总线上生效。

主机控制NSS的方式有两种——硬件方式和软件方式。主机硬件NSS模式下,NSS脚只能选择特定IO口(具体见datasheet中IO口功能表),当开始进行数据读写时,NSS自动拉低,这种方式的优点是主机NSS由硬件自动控制,缺点是只能控制一个从机;主机NSS软件模式下,NSS可以使用任意IO口,需要控制哪个从机,软件将对于IO拉低即可,这种方式的优点是可以实现一个主机多个从机的通讯,缺点是软件需要介入控制NSS脚。

注意:GD32F303 主机硬件NSS模式下,一旦开始第一次数据读取,NSS被硬件自动拉低后,将不会自行拉高,从机将处于始终被片选的状态下。

从机获取NSS状态的方式也有两种——硬件方式和软件方式。从机硬件NSS模式下,SPI 从NSS引脚获取 NSS 电平, 在软件NSS 模式(SWNSSEN = 1) 下, SPI 根据SWNSS 位得到NSS电平。

SPI除了单线全双工模式外,还有很多其他方式,比如可以实现只用MOSI进行数据收和发的半双工通讯,这样就可以省下MISO用作他处了,具体可以参考GD32F30x系列官方用户手册。

下面介绍下SPI的发送和接受流程:

发送流程
在完成初始化过程之后, SPI 模块使能并保持在空闲状态。在主机模式下, 当软件写一个数据到发送缓冲区时,发送过程开始。在从机模式下,当 SCK 引脚上的 SCK 信号开始翻转, 且NSS 引脚电平为低, 发送过程开始。 所以, 在从机模式下,应用程序必须确保在数据发送开始前, 数据已经写入发送缓冲区中。
当 SPI 开始发送一个数据帧时, 首先将这个数据帧从数据缓冲区加载到移位寄存器中,然后开始发送加载的数据。在数据帧的第一位发送之后, TBE(发送缓冲区空) 位置 1。 TBE 标志位置 1, 说明发送缓冲区为空, 此时如果需要发送更多数据, 软件应该继续写 SPI_DATA 寄存器。在主机模式下, 若想要实现连续发送功能, 那么在当前数据帧发送完成前, 软件应该将下一个数据写入 SPI_DATA 寄存器中。  

接收流程
在最后一个采样时钟边沿之后, 接收到的数据将从移位寄存器存入到接收缓冲区, 且 RBNE(接收缓冲区非空) 位置 1。软件通过读 SPI_DATA 寄存器获得接收的数据, 此操作会自动清除RBNE 标志位。   

19.2.3 SPI FLASH——GD25Q32ESIGR简介

GD25Q32ESIGR是一款容量为32Mbit(即4Mbyte)的SPI接口的NOR FLASH,其支持SPI和QSPI模式,芯片示意图如下:

GD25Q32ESIGR管脚定义如下:

GD25Q32ESIGR内部flash结构如下:

下面介绍GD25Q32ESIGR的一些功能码。

Write Enable (WREN) (06H) :接受到该命令后,GD25Q32ESIGR做好接受数据并进行存储的准备,时序如下:

Read Status Register (RDSR) (05H or 35H or 15H)  :读GD25Q32ESIGR的状态,时序如下:

Read Data Bytes (READ) (03H)  :接受到该命令后,GD25Q32ESIGR将数据准备好供主机读走,时序如下:

Dual Output Fast Read (3BH)  :使GD25Q32ESIGR切换到QSPI模式,时序如下:

Quad Output Fast Read (6BH)  :QSPI读命令,时序如下:

Quad Page Program (32H)   :QSPI写命令,时序如下:

Sector Erase (SE) (20H)  :Sector擦除命令,时序如下:

GD25Q32ESIGR就介绍到这里,读者可以在兆易创新官网下载该NOR FLASH的datasheet以获取更多信息。

19.3 硬件设计

红枫派开发板SPI——NOR FLASH的硬件设计如下:

从图中可以看出,本实验使用的是普通单线SPI,GD25Q32ESIGR的片选由GD32F303ZET6的PG14控制(因PG14不是SPI的NSS管脚,所以本实验用主机NSS软件模式),GD25Q32ESIGR的SO、SI和SCLK分别和GD32F303ZET6的PB4(SPI2_MISO)、PB5(SPI2_MOSI)以及PB3(SPI2_CLK)相连。

19.4 代码解析

19.4.1 SPI初始化函数

在driver_spi.c文件中定义了SPI初始化函数driver_spi_init:

C
void driver_spi_init(typdef_spi_struct *spix)
{spi_parameter_struct spi_init_struct;    rcu_periph_clock_enable(spix->rcu_spi_x);/* spi configure */spi_i2s_deinit(spix->spi_x);driver_gpio_general_init(spix->spi_cs_gpio);    driver_gpio_general_init(spix->spi_sck_gpio);driver_gpio_general_init(spix->spi_mosi_gpio);driver_gpio_general_init(spix->spi_miso_gpio);        if(spix->spi_mode==MODE_DMA){if(spix->spi_rx_dma!=NULL){if(spix->frame_size==SPI_FRAMESIZE_8BIT){driver_dma_com_init(spix->spi_rx_dma,(uint32_t)&SPI_DATA(spix->spi_x),NULL,DMA_Width_8BIT,DMA_PERIPHERAL_TO_MEMORY);}else{driver_dma_com_init(spix->spi_rx_dma,(uint32_t)&SPI_DATA(spix->spi_x),NULL,DMA_Width_16BIT,DMA_PERIPHERAL_TO_MEMORY);}     if(spix->spi_tx_dma!=NULL){if(spix->frame_size==SPI_FRAMESIZE_8BIT){driver_dma_com_init(spix->spi_tx_dma,(uint32_t)&SPI_DATA(spix->spi_x),NULL,DMA_Width_8BIT,DMA_MEMORY_TO_PERIPHERAL);}else{driver_dma_com_init(spix->spi_tx_dma,(uint32_t)&SPI_DATA(spix->spi_x),NULL,DMA_Width_16BIT,DMA_MEMORY_TO_PERIPHERAL);}             }            }}if(spix->spi_cs_gpio!=NULL){driver_gpio_pin_set(spix->spi_cs_gpio);}spi_struct_para_init(&spi_init_struct);spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;spi_init_struct.device_mode = spix->device_mode;spi_init_struct.frame_size = spix->frame_size;spi_init_struct.clock_polarity_phase = spix->clock_polarity_phase;if(spix->device_mode==SPI_MASTER){spi_init_struct.nss = SPI_NSS_SOFT;}else{spi_init_struct.nss = SPI_NSS_HARD;        }spi_init_struct.prescale = spix->prescale;spi_init_struct.endian = spix->endian;spi_init(spix->spi_x, &spi_init_struct);spi_enable(spix->spi_x);
}

19.4.2 SPI轮训接受一个数函数

在driver_spi.c文件中定义了使用轮训方式发送接受一个字节数据函数driver_spi_master_transmit_receive_byte:

C
uint8_t driver_spi_master_transmit_receive_byte(typdef_spi_struct *spix,uint8_t byte)
{SPI_DATA(spix->spi_x);SPI_STAT(spix->spi_x);       driver_spi_flag_wait_timeout(spix,SPI_FLAG_TBE,SET);spi_i2s_data_transmit(spix->spi_x,byte);DRV_ERROR==driver_spi_flag_wait_timeout(spix,SPI_FLAG_RBNE,SET);return spi_i2s_data_receive(spix->spi_x);                
}

上面函数中有带超时功能的等待SPI状态的函数driver_spi_flag_wait_timeout,该函数定义在driver_spi.c:

C
Drv_Err driver_spi_flag_wait_timeout(typdef_spi_struct *spix, uint32_t flag ,FlagStatus wait_state)
{uint32_t timeout = driver_tick;    while(wait_state!=spi_i2s_flag_get(spix->spi_x, flag)){if((timeout+SPI_TIMEOUT_MS) <= driver_tick) {              return DRV_ERROR;} }return DRV_SUCCESS;
}

19.4.3 SPI NOR FLASH 接口bsp层函数

操作NOR FLASH的函数都定义在bsp层文件bsp_spi_nor.c中,这个文件中定义的函数都是针对NOR FLASH特性来实现的,我们选取几个函数进行介绍。

1、NOR FLASH按sector擦除函数bsp_spi_nor_sector_erase,该函数流程是:使能NOR FLASH的写功能->拉低片选->向NOR FLASH发送sector擦除指令SE(0x20)->从低地址到高地址发送需要擦除的地址->拉高片选->等待NOR FALSH内部操作完成(循环去读NOR FLASH状态,直到读出编程状态为0)

C
void bsp_spi_nor_sector_erase(uint32_t sector_addr)
{/* send write enable instruction */bsp_spi_nor_write_enable();/* sector erase *//* select the flash: chip select low */bsp_spi_nor_cs_low();/* send sector erase instruction */driver_spi_master_transmit_receive_byte(&BOARD_SPI,SE);/* send sector_addr high nibble address byte */driver_spi_master_transmit_receive_byte(&BOARD_SPI,(sector_addr & 0xFF0000) >> 16);/* send sector_addr medium nibble address byte */driver_spi_master_transmit_receive_byte(&BOARD_SPI,(sector_addr & 0xFF00) >> 8);/* send sector_addr low nibble address byte */driver_spi_master_transmit_receive_byte(&BOARD_SPI,sector_addr & 0xFF);/* deselect the flash: chip select high */bsp_spi_nor_cs_high();/* wait the end of flash writing */bsp_spi_nor_wait_for_write_end();
}

2、按page写数据函数bsp_spi_nor_page_write,该函数实现在page范围内写数据,该函数流程是:使能NOR FLASH的写功能->拉低片选->向NOR FLASH发送写指令WRITE(0x02)->从低地址到高地址发送要写的地址(每次进行写数据时,只需要给初始地址即可,写完一个数据后NOR FLASH内部会自动把地址+1)->写数据->拉高片选->等待NOR FALSH内部操作完成(循环去读NOR FLASH状态,直到读出编程状态为0)

C
void bsp_spi_nor_page_write(uint8_t* pbuffer, uint32_t write_addr, uint16_t num_byte_to_write)
{/* enable the write access to the flash */bsp_spi_nor_write_enable();/* select the flash: chip select low */bsp_spi_nor_cs_low();/* send "write to memory" instruction */driver_spi_master_transmit_receive_byte(&BOARD_SPI,WRITE);/* send write_addr high nibble address byte to write to */driver_spi_master_transmit_receive_byte(&BOARD_SPI,(write_addr & 0xFF0000) >> 16);/* send write_addr medium nibble address byte to write to */driver_spi_master_transmit_receive_byte(&BOARD_SPI,(write_addr & 0xFF00) >> 8);/* send write_addr low nibble address byte to write to */driver_spi_master_transmit_receive_byte(&BOARD_SPI,write_addr & 0xFF);/* while there is data to be written on the flash */while(num_byte_to_write--){/* send the current byte */driver_spi_master_transmit_receive_byte(&BOARD_SPI,*pbuffer);/* point on the next byte to be written */pbuffer++;}/* deselect the flash: chip select high */bsp_spi_nor_cs_high();/* wait the end of flash writing */bsp_spi_nor_wait_for_write_end();
}

3、按buffer写数据函数bsp_spi_nor_buffer_write,该函数实现任意长度数据写入,使用page写函数搭配算法,可以跨page进行写数据:

C
void bsp_spi_nor_buffer_write(uint8_t* pbuffer, uint32_t write_addr, uint16_t num_byte_to_write)
{uint8_t num_of_page = 0, num_of_single = 0, addr = 0, count = 0, temp = 0;addr          = write_addr % SPI_FLASH_PAGE_SIZE;count         = SPI_FLASH_PAGE_SIZE - addr;num_of_page   = num_byte_to_write / SPI_FLASH_PAGE_SIZE;num_of_single = num_byte_to_write % SPI_FLASH_PAGE_SIZE;/* write_addr is SPI_FLASH_PAGE_SIZE aligned  */if(0 == addr){/* num_byte_to_write < SPI_FLASH_PAGE_SIZE */if(0 == num_of_page)bsp_spi_nor_page_write(pbuffer,write_addr,num_byte_to_write);/* num_byte_to_write > SPI_FLASH_PAGE_SIZE */else{while(num_of_page--){bsp_spi_nor_page_write(pbuffer,write_addr,SPI_FLASH_PAGE_SIZE);write_addr += SPI_FLASH_PAGE_SIZE;pbuffer += SPI_FLASH_PAGE_SIZE;}bsp_spi_nor_page_write(pbuffer,write_addr,num_of_single);}}else{/* write_addr is not SPI_FLASH_PAGE_SIZE aligned  */if(0 == num_of_page){/* (num_byte_to_write + write_addr) > SPI_FLASH_PAGE_SIZE */if(num_of_single > count){temp = num_of_single - count;bsp_spi_nor_page_write(pbuffer,write_addr,count);write_addr += count;pbuffer += count;bsp_spi_nor_page_write(pbuffer,write_addr,temp);}elsebsp_spi_nor_page_write(pbuffer,write_addr,num_byte_to_write);}else{/* num_byte_to_write > SPI_FLASH_PAGE_SIZE */num_byte_to_write -= count;num_of_page = num_byte_to_write / SPI_FLASH_PAGE_SIZE;num_of_single = num_byte_to_write % SPI_FLASH_PAGE_SIZE;bsp_spi_nor_page_write(pbuffer,write_addr, count);write_addr += count;pbuffer += count;while(num_of_page--){bsp_spi_nor_page_write(pbuffer,write_addr,SPI_FLASH_PAGE_SIZE);write_addr += SPI_FLASH_PAGE_SIZE;pbuffer += SPI_FLASH_PAGE_SIZE;}if(0 != num_of_single)bsp_spi_nor_page_write(pbuffer,write_addr,num_of_single);}}
}

4、按buffer读数据函数bsp_spi_nor_buffer_read,该函数实现任意地址读数据,该函数流程是:拉低片选->向NOR FLASH发送读指令READ(0x03)->从低地址到高地址发送要读的地址(每次进行读数据时,只需要给初始地址即可,读完一个数据后NOR FLASH内部会自动把地址+1)->读数据->拉高片选:

C
void bsp_spi_nor_buffer_read(uint8_t* pbuffer, uint32_t read_addr, uint16_t num_byte_to_read)
{/* select the flash: chip slect low */bsp_spi_nor_cs_low();/* send "read from memory " instruction */driver_spi_master_transmit_receive_byte(&BOARD_SPI,READ);/* send read_addr high nibble address byte to read from */driver_spi_master_transmit_receive_byte(&BOARD_SPI,(read_addr & 0xFF0000) >> 16);/* send read_addr medium nibble address byte to read from */driver_spi_master_transmit_receive_byte(&BOARD_SPI,(read_addr& 0xFF00) >> 8);/* send read_addr low nibble address byte to read from */driver_spi_master_transmit_receive_byte(&BOARD_SPI,read_addr & 0xFF);/* while there is data to be read */while(num_byte_to_read--){/* read a byte from the flash */*pbuffer = driver_spi_master_transmit_receive_byte(&BOARD_SPI,DUMMY_BYTE);/* point to the next location where the byte read will be saved */pbuffer++;}/* deselect the flash: chip select high */bsp_spi_nor_cs_high();
}

19.4.4 main函数实现

以下为main函数代码:

C
int main(void)
{//延时、共用驱动部分初始化 driver_init();          //初始化LED组和默认状态bsp_led_group_init();bsp_led_on(&LED0);bsp_led_off(&LED1);     //初始化UART打印bsp_uart_init(&BOARD_UART);//初始化SPI    bsp_spi_init(&BOARD_SPI);  //初始化SPI NOR     bsp_spi_nor_init();  printf("\n\rSPI Flash:GD25Q32E configured...\n\r");//读取flash idflash_id = bsp_spi_nor_read_id();printf("\n\rThe Flash_ID:0x%X\n\r",flash_id);//比对flash id是否一致if(SFLASH_ID == flash_id){printf("\n\r\n\rWrite to tx_buffer:\n\r\n\r");//准备数据for(uint16_t i = 0; i < BUFFER_SIZE; i ++){tx_buffer[i] = i;printf("0x%02X ",tx_buffer[i]);if(15 == i%16)printf("\n\r");}printf("\n\r\n\rRead from rx_buffer:\n\r");        //擦除要写入的sectorbsp_spi_nor_sector_erase(FLASH_WRITE_ADDRESS);//写入数据 bsp_spi_nor_buffer_write(tx_buffer,FLASH_WRITE_ADDRESS,TX_BUFFER_SIZE);//延时等待写完成delay_ms(10);//回读写入数据bsp_spi_nor_buffer_read(rx_buffer,FLASH_READ_ADDRESS,RX_BUFFER_SIZE);        /* printf rx_buffer value */for(uint16_t i = 0; i <= 255; i ++){printf("0x%02X ", rx_buffer[i]);if(15 == i%16)printf("\n\r");}//比较回读和写入数据if(ERROR == memory_compare(tx_buffer,rx_buffer,256)){printf("Err:Data Read and Write aren't Matching.\n\r");/* spi flash read id fail */printf("\n\rSPI Flash: Read ID Fail!\n\r");//写入错误/* turn off all leds */bsp_led_on(&LED0);/* turn off all leds */bsp_led_on(&LED1);           while(1);}else{printf("\n\rSPI-GD25Q16 Test Passed!\n\r");}}else{ //ID读取错误/* spi flash read id fail */printf("\n\rSPI Flash: Read ID Fail!\n\r");/* turn off all leds */bsp_led_on(&LED0);/* turn off all leds */bsp_led_on(&LED1);           while(1);}while(1){/* turn off all leds */bsp_led_toggle(&LED0);/* turn off all leds */bsp_led_toggle(&LED1);        delay_ms(200);}
}

main函数中实现了向特定NOR FLASH地址写数据,并回读出来,并将写入的数据和回读出来的数据进行对比,看是否写入成功。

19.5 实验结果

使用USB-TypeC线,连接电脑和板上USB to UART口后,配置好串口调试助手,即可看到MCU对SPI NOR flash的擦写读过程。

由聚沃科技原创,来源于【红枫派开发板】第十九讲 SPI-SPI NOR FLASH读写实验 - 苏州聚沃电子科技有限公司 (gd32bbs.com) 

相关文章:

【GD32F303红枫派使用手册】第十九节

19.1 实验内容 通过本实验主要学习以下内容&#xff1a; SPI简介 GD32F303 SPI简介 SPI NOR FLASH——GD25Q32ESIGR简介 使用GD32F303 SPI接口实现对GD25Q32ESIGR的读写操作 19.2 实验原理 19.2.1 SPI简介 SPI&#xff08;Serial Peripheral interface&#xff09;&…...

【C语言】扫雷游戏

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…...

逻辑蕴含、函数依赖集的闭包、Armstrong公理、属性集闭包

一、引言 Armstrong公理-从给定的函数依赖集得到关系模式的完整依赖集 二、逻辑蕴含 1、定义 设F是关系模式R上的函数依赖集&#xff0c;X、Y是R的属性子集&#xff0c;对于R的每个满足F的关系实例r&#xff0c;若函数 依赖都成立&#xff0c;则称F逻辑蕴含。 记为&#…...

macOS聚集搜索功能开启与关闭

按下command空格弹出 使用搜索 关闭搜索 sudo mdutil -a -i off 启用搜索 sudo mdutil -a -i on...

大模型“诸神之战”,落地才是赛点

ChatGPT 诞生已经快一年&#xff0c;你还在与它对话吗&#xff1f; 有的人用来写报告、改代码&#xff0c;让它成为得力帮手&#xff1b;有的人却只是“调戏”个两三回&#xff0c;让它创作诗歌或故事&#xff0c;便不再“宠幸”。 根据网站分析工具 SimilarWeb 的数据&#…...

接口重放攻击

如何保证接口安全&#xff0c;做到防篡改防重放&#xff1f;_接口防止串改-CSDN博客 接口安全设计之防篡改和防重放_接口防篡改机制-CSDN博客 基于nonce timestamp 的方案 nonce的意思是仅一次有效的随机字符串&#xff0c;要求每次请求时该参数要保证不同。实际使用用户信息…...

MySQL学习笔记-进阶篇-SQL优化

SQL优化 插入数据 insert优化 1&#xff09;批量插入 insert into tb_user values(1,Tom),(2,Cat),(3,Jerry); 2&#xff09;手动提交事务 mysql 默认是自动提交事务&#xff0c;这样会导致频繁的开启和提交事务&#xff0c;影响性能 start transaction insert into tb_us…...

【机器学习】第2章 线性回归及最大熵模型

一、概念 1.回归就是用一条曲线对数据点进行拟合&#xff0c;该曲线称为最佳拟合曲线&#xff0c;这个拟合过程称为回归。 2.一个自变量 叫 一元线性回归&#xff0c;大于一个自变量 叫 多元线性回归。 &#xff08;1&#xff09;多元回归&#xff1a;两个x&#xff0c;一个…...

科技创新对农业发展的影响

科技创新对农业发展的影响深远且广泛&#xff0c;主要体现在以下几个方面&#xff1a; 一、提高农业生产效率 引入先进的农业机械设备&#xff1a;新型农业机械设备如无人机、机器人等的应用&#xff0c;显著减轻了农民的劳动强度&#xff0c;提高了农作物的种植效率。利用精…...

Linux 常用命令 - rm 【删除文件或目录】

简介 rm 命令源于英文单词 “remove”&#xff0c;它用于删除文件或目录。rm 是 Linux 系统中最基本的命令之一&#xff0c;用于删除指定的文件或目录。默认情况下&#xff0c;rm 不会删除目录&#xff0c;但可以通过递归删除选项来实现。 使用方式 rm [选项]... [文件]...常…...

一血c++

题目描述 每一个竞赛选手都无法拒绝拿一血 "一血"其实就是同学们在榜单上看到的深绿色的标记&#xff0c;代表着某道题目&#xff0c;他是第一个通过的。 叶苡朋老师是一名资深信奥选手&#xff0c;在大学多次获奖&#xff0c;也是一个资深抢一血爱好者&#xff0…...

无问芯穹Qllm-Eval:制作多模型、多参数、多维度的量化方案

前言 近年来&#xff0c;大语言模型&#xff08;Large Models, LLMs&#xff09;受到学术界和工业界的广泛关注&#xff0c;得益于其在各种语言生成任务上的出色表现&#xff0c;大语言模型推动了各种人工智能应用&#xff08;例如ChatGPT、Copilot等&#xff09;的发展。然而…...

2024-05-31T08:36:09.000+00:00 转换 YYYY-MM-DD HH-MM-SS

function formatDate(date) {// 处理ISO 8601字符串if (typeof date string) {date new Date(date);}// 处理时间戳else if (typeof date number) {date new Date(date * 1000); // 假设后端时间戳为秒&#xff0c;需要乘以1000转换为毫秒}// 自定义格式化&#xff0c;例如…...

reason: the Java file contained parse errors

今天用Maven打包项目时发生一个错误&#xff1a; file: D:\workspace\echoo2.0-xxx-xxx-portal\src\main\java\com\echoo\service\impl\DecDataServiceImpl.java; reason: the Java file contained parse errors 打包报错显示这个类解析错误 在IDEA中没有任何错误提示 问题所…...

使用密钥对登录服务器

目录 1、使用密钥文件登录服务器 2、登录成功画面&#xff1a; 3、如若出现以下状况&#xff0c;则说明密钥文件登录失败 1、使用密钥文件登录服务器 首先需要上传pem文件 2、登录成功画面&#xff1a; 3、如若出现以下状况&#xff0c;则说明密钥文件登录失败 解决方法&…...

面试_多线程

线程池 线程池的参数有哪些 线程池七大参数分别是corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler corePoolSize&#xff1a;线程池中常驻核心线程数maximumPoolSize&#xff1a;线程池能够容纳同时执行的最大线程数keepAliveTime&…...

跨境电商必备?揭秘原生IP的作用

一、什么是原生IP&#xff1f; 原生IP&#xff08;Native IP&#xff09;是指由互联网服务提供商&#xff08;ISP&#xff09;或服务器提供商直接分配给用户的IP地址&#xff0c;这种IP地址直接与用户设备或网络相连&#xff0c;也就是指这个IP的注册地址和服务器机房所在的国…...

mysql竖表变横表不含聚合

文章目录 前言一、vertical_table二、转换1.要将其转换为横表形式&#xff0c;例如&#xff1a;2.sql 总结 前言 在MySQL中将竖表转换为横表&#xff08;也称为行转列操作&#xff09;&#xff0c;不涉及聚合函数&#xff0c;通常可以通过使用条件判断和自连接来实现。假设有一…...

application/x-www-form-urlencoded和json的区别

application/x-www-form-urlencoded 和 application/json 是两种不同的数据格式&#xff0c;常用于HTTP请求中传递数据。 它们各自的特点和使用场景如下&#xff1a; 1. application/x-www-form-urlencoded •特点&#xff1a;这是一种传统的表单提交时采用的编码类型&#x…...

oracle数据库日常保养或巡检语句实践整理汇总

目录 1.目的 2.操作工具 3.实践说明 1.检查Oracle实例状态 2.检查Oracle在线日志状态 3.检查Oracle表空间状态 4.检查Oracle所有数据文件状态 5.检查Oracle数据库连接情况 6.检查Oracle表容量占用大小 7.检查Oracle备份 8.检查数据库表空间的使用情况 4.总结 1.目的 …...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...