中科亿海微Flash擦写读

引言


        在数字存储技术的领域中,闪存(Flash)是一种非易失性存储器,以其高速读写、低功耗和较高的可靠性而备受关注。相比于传统的磁盘存储技术,闪存具有更小的体积、更高的数据密度和更长的寿命,因此在各种应用中得到了广泛的应用。闪存最初应用于便携式设备和嵌入式系统中,如手机、平板电脑和闪存卡等。随着技术的不断进步,闪存逐渐取代了传统的硬盘驱动器,成为许多计算机系统的首选存储介质。

        闪存的工作原理与传统的存储技术有所不同。它采用了一种称为“浮体栅结构”的技术,通过在晶体管中添加控制门、浮动门和栅极等元件,实现了数据的存储和擦除。这种浮体栅结构使得闪存能够在无电源供应的情况下保持数据的稳定性,同时具有较快的读写速度和较低的功耗。

闪存的应用领域包括但不限于:
1. 便携式设备和嵌入式系统:如手机、平板电脑、存储卡和嵌入式系统模块等。
2. 个人电脑和服务器:闪存固态硬盘(SSD)已经成为替代传统硬盘驱动器的首选存储介质。
3. 汽车电子:闪存被用于车载娱乐系统、导航系统和车载通信系统等。
4. 云存储和大数据中心:闪存被用于高速缓存、快速存储和大规模数据处理等。


问题分析

1. 存储密度和容量:


        闪存的存储密度和容量是一个重要的问题。随着技术的不断发展,闪存的存储密度和容量不断增加,但如何保持稳定的性能和可靠性仍然是一个挑战。如何平衡存储密度和容量与数据可靠性和读写速度之间的关系,是一个需要解决的问题。

2. 读写速度和性能:


        闪存的读写速度和性能是另一个重要的问题。闪存的读取速度通常比写入速度更快,而写入速度受到擦除操作的限制。如何提高闪存的读写速度,并解决擦除操作带来的延迟和性能问题,是一个需要解决的挑战。

3. 寿命和耐久性:


        闪存的寿命和耐久性是一个关键问题。闪存存储单元在重复擦写操作后会逐渐损耗,导致寿命减少。如何提高闪存的耐久性,减少擦写操作对存储单元的损耗,是一个需要解决的问题。

4. 错误校正和数据完整性:


        在闪存中,数据的正确性和完整性是至关重要的。由于闪存存储单元的损耗和环境因素的影响,数据可能会发生错误或丢失。如何设计合适的错误校正和纠正机制,以确保数据的正确性和完整性,是一个需要解决的问题。

5. 垃圾回收和空间管理:


        闪存中的垃圾回收和空间管理是一个关键问题。在闪存中,擦除操作是一个相对较慢的过程,而闪存存储单元的擦除前必须是空白的。如何高效地进行垃圾回收和空间管理,以充分利用闪存空间并减少擦除操作次数,是一个需要解决的挑战。


解决方案

1. 存储密度和容量:


        为了提高存储密度和容量,可以采用更高密度的闪存芯片和多级存储技术,如多层堆叠存储器(MLC)和三级堆叠存储器(TLC)。此外,可以采用更高级别的错误校正码(ECC)来增加数据的存储密度。

2. 读写速度和性能:


        为了提高读写速度和性能,可以采用并行读写和多通道设计,以实现并发的数据访问。同时,可以优化闪存控制器的算法和数据缓存机制,以减少读写操作的延迟。

3. 寿命和耐久性:


        为了提高闪存的寿命和耐久性,可以采用动态均衡和可编程的擦写算法,以均衡存储单元的使用和减少擦写操作的次数。此外,可以实施写放大和数据分散技术,以减少对特定存储单元的过度擦写。

4. 错误校正和数据完整性:


        为了确保数据的正确性和完整性,可以采用强大的错误校正和纠正机制,如BCH(Bose-Chaudhuri-Hocquenghem)码和LDPC(低密度奇偶校验)码。这些机制可以检测和纠正数据传输过程中可能出现的错误。

5. 垃圾回收和空间管理:


        为了高效地进行垃圾回收和空间管理,可以采用闪存控制器中的智能算法和策略。这些算法和策略可以根据存储单元的使用情况和数据访问模式,动态地进行垃圾回收和数据迁移,以减少擦除操作的次数并提高空间利用率。

实施步骤

        该程序利用FPGA实现了对Flash存储器的多项功能,包括写入使能、整片擦除、全片写入和全片数据读取。通过使用FPGA作为控制器,程序能够有效地控制Flash存储器的写入操作,实现数据的可靠存储。同时,通过整片擦除和全片写入功能,可以在需要时快速清除和写入整个Flash存储器。而全片数据读取功能使得程序能够高效地读取Flash存储器中的全部数据。这些功能的实现,为Flash存储器的使用提供了更大的灵活性和便利性。

`timescale 1 ps/ 1 ps
//
// Company:
// Engineer:
//
// Create Date: 11-08-2022 16:06:19
// Design Name:
// Module Name: flash_control
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies: 
//
// Revision:
// Additional Comments:
//
//module flash_control(input 			wire			clk				,input			wire			rst_n			,input  [7:0]  					O_data_out  	, input         					O_tx_done   	, input         					O_rx_done   	, input 							Clock_open		,output reg        				I_rx_en     	, output reg        				I_tx_en     	, output reg [7:0]  				I_data_in   	, output reg        				O_spi_cs    	, output reg						strswitch		,output reg						flash_done		,output reg 						response		,output reg 						control_done		/*synthesis noprune*/,output reg 						Register_error	,	//无法写入寄存器output reg 						DATA_error		,	//数据错误output reg [9:0]				record  		,output reg [20:0]				Erase_count		
);//------------------------------------------------------------------------------
//----------- Registers Declarations -------------------------------------------
//------------------------------------------------------------------------------
reg [7:0]	state/* synthesis preserve */;
reg [63:0]	cnt/* synthesis preserve */;
reg [7:0]   DATA/* synthesis preserve */;
reg [7:0]	DATA_out/* synthesis preserve */;
reg [23:0]	addr2/* synthesis preserve */;
reg [23:0]	addr;
reg [2:0]	count/* synthesis preserve */;
reg 		d0,d1;
reg [7:0]	state_reg/* synthesis preserve */;
reg 			a;
reg 			Sector_ER_DONE;wire 			pos_Clock_open;assign pos_Clock_open	=	d0	&	(!d1);//写启动 写禁止
parameter  	Write_Enable					=	8'h06;		//写启动
parameter  	Write_Disable					=	8'h04;		//写禁止
parameter	Read_Data						=	8'h03;		//读数据
parameter	Sector_Erase					=	8'h20;		//扇区擦除
parameter	Chip_Erase						=	8'hc7;		//芯片擦除
parameter	Power_down						=	8'hb9;		//芯片断电
parameter	Quad_Input_Page_Program			=	8'h32;		//页写入
parameter	Block_Erase_64KB				=	8'hd8;		//64K块擦除
parameter   Page_Program					=	8'h02;		//页编程
parameter 	Fast_Read						=	8'h0b;		//快速读取
parameter	Fast_Read_Quad_Output			=	8'h6b;		//读取4页数据
parameter 	Write_Enable_Register			=	8'h50;		//写状态寄存器//写入状态 读取状态
parameter	Read_Status_Register_1		=	8'h05;			//读状态寄存器1
parameter	Read_Status_Register_2		=	8'h35;			//读状态寄存器2
parameter	Read_Status_Register_3		=	8'h15;			//读状态寄存器2parameter	Write_Status_Register_1		=	8'h01;			//写状态寄存器1
parameter	Write_Status_Register_2		=	8'h31;			//写状态寄存器2
parameter	Write_Status_Register_3		=	8'h11;			//写状态寄存器3always @ (posedge clk ) begin state_reg	<=	state;end always @ (posedge clk ) begin if (!rst_n)begin d0	<=	1'b0;d1	<=	1'b0;end else begin d0	<=	Clock_open;d1	<=	d0;end 
end always @ (posedge clk ) begin if (!rst_n)a		<=	1'b0;elsea		<=	1'b1;
end always @ (posedge clk) begin if (!rst_n)begin state					<=	8'd0		;cnt					<=	64'd0		;I_rx_en				<=	1'b0		;I_tx_en				<=	1'b0		;I_data_in			<=	8'd0		;DATA					<=	8'd0		;O_spi_cs				<=	1'b1		;strswitch			<=	1'b1		;	addr2					<=	24'd0		;addr					<=	24'd0		;DATA_out				<=	8'd0		;count					<=	3'd0		;flash_done			<=	1'b0		;response				<=	1'b0		;Register_error		<=	1'b0		;DATA_error			<=	1'b0		;control_done		<=	1'b0		;record				<=	10'd0		;Erase_count			<=	21'd0		;Sector_ER_DONE		<=	1'b0		;end else case (state)0:begin if (cnt	==	5000000-1)//5000000-1begin //5秒addr					<=	24'd0		;Erase_count			<=		21'd0;cnt					<=		64'd0;state					<=		state		+	1'b1;count					<=		3'd0;response				<=		1'b0;Register_error		<=		Register_error;DATA_error			<=		DATA_error;control_done		<=		1'b0;record				<=		record;end else if (a)begin addr					<=	24'd0		;cnt					<=		cnt		+	1'b1;I_rx_en				<=		1'b0;I_tx_en				<=		1'b0;O_spi_cs			<=		1'b1;strswitch			<=		1'b1;control_done		<=		1'b0;record				<=		record;end else begin cnt					<=	64'd0;end end //***********************写启动1:begin DATA					<=		8'hff;Erase_count			<=		Erase_count;state				<=		state		+	1'b1;I_rx_en				<=		1'b0;I_tx_en				<=		1'b1;O_spi_cs			<=		1'b0;I_data_in			<=		Write_Enable;strswitch			<=		1'b1;		addr2				<=		24'd0;count				<=		count	+	1'b1;control_done		<=		1'b0;end 2:begin if (O_tx_done)state				<=		state	+	1'b1;else 	state				<=		state;end //***********************全片擦除3:begin I_tx_en				<=		1'b0;O_spi_cs			<=		1'b1;state				<=		state	+	1'b1;end 4:begin I_tx_en					<=		1'b1;O_spi_cs				<=		1'b0;state					<=		state	+	1'b1;strswitch				<=		1'b1;	I_data_in				<=		Chip_Erase;	record					<=		record	+	1'b1;control_done			<=		1'b0	;end 5:begin if (O_tx_done)begin control_done		<=		1'b0;state				<=		state	+	1'b1;end else 	begin control_done		<=		1'b0;state				<=		state;end end 6:begin O_spi_cs			<=		1'b1;I_tx_en				<=		1'b0;state				<=		state	+	1'b1;DATA_out			<=		8'haa;end //***********************读取状态寄存器7:begin I_tx_en					<=		1'b1;O_spi_cs				<=		1'b0;state					<=		state	+	1'b1;strswitch				<=		1'b1;	I_data_in				<=		Read_Status_Register_1;end 8:begin if (O_tx_done)state				<=		state	+	1'b1;else state				<=		state;end 9:begin //读写切换I_rx_en				<=		1'b1;I_tx_en				<=		1'b0;state				<=		state	+	1'b1;end //***********************读数据10:begin if (O_rx_done)begin DATA				<=		O_data_out;state				<=		state	+	1'b1;end else state				<=		state;end //***********************判断读取数据11:begin 	if (DATA[0]	==	0)			begin I_rx_en				<=		1'b0;I_tx_en				<=		1'b0;state				<=		state	+	1;cnt					<=		64'd0;Register_error		<=		1'b0;end else begin Register_error		<=		1'b1;state				<=		state	-	1;end end 12:begin //全片擦除完成 进行写操作Sector_ER_DONE		<=		1'b0;O_spi_cs				<=		1'b1;state					<=		state	+	1;Erase_count			<=		Erase_count	+1;end //***********************写启动13:begin I_tx_en					<=		1'b1;O_spi_cs				<=		1'b0;state					<=		state	+	1'b1;strswitch				<=		1'b1;	I_data_in				<=		Write_Enable;	end 14:begin if (O_tx_done)state				<=		state	+	1'b1;else 	state				<=		state;end 15:begin O_spi_cs			<=		1'b1;I_tx_en				<=		1'b0;state				<=		state	+	1'b1;end //***********************写状态寄存器16:begin I_tx_en					<=		1'b1;O_spi_cs				<=		1'b0;state					<=		state	+	1'b1;strswitch				<=		1'b1;	I_data_in				<=		Write_Enable_Register;	end 17:begin if (O_tx_done)state				<=		state	+	1'b1;else 	state				<=		state;end 18:begin O_spi_cs			<=		1'b1;I_tx_en				<=		1'b0;state				<=		state	+	1'b1;end //***********************写状态19:begin I_tx_en					<=		1'b1;O_spi_cs				<=		1'b0;state					<=		state	+	1'b1;strswitch				<=		1'b1;	I_data_in				<=		Write_Status_Register_2;	end 20:begin if (O_tx_done)state				<=		state	+	1'b1;else state				<=		state;end 21:begin I_tx_en				<=		1'b0;state				<=		state	+	1'b1;end //***********************写状态数据22:begin I_tx_en					<=		1'b1;O_spi_cs				<=		1'b0;state					<=		state	+	1'b1;strswitch				<=		1'b1;	I_data_in				<=		8'h02;end 23:begin if (O_tx_done)state				<=		state	+	1'b1;else 		state				<=		state;end 24:beginO_spi_cs			<=		1'b1;I_tx_en				<=		1'b0;state				<=		state	+	1'b1;end //***********************读状态25:begin I_tx_en					<=		1'b1;O_spi_cs					<=		1'b0;state						<=		state	+	1'b1;strswitch				<=		1'b1;I_data_in				<=		Read_Status_Register_2;	end 26:begin if (O_tx_done)state				<=		state	+	1'b1;else state				<=		state;end 27:begin 
//					DATA					<=		8'hff;	control_done		<=		1'b0;I_rx_en				<=		1'b1;I_tx_en				<=		1'b0;state				<=		state	+	1'b1;end //***********************读数据28:begin if (O_rx_done)begin DATA				<=		O_data_out;state				<=		state	+	1'b1;end else state				<=		state;end //***********************判断读取数据29:begin 	if (DATA[1:0]	==	2'b10)			begin O_spi_cs			<=		1'b1;I_rx_en				<=		1'b0;I_tx_en				<=		1'b0;state				<=		state	+	1;cnt					<=		64'd0;Register_error		<=		1'b0;end else begin Register_error		<=		1'b1;state				<=		state	+	1;end end 30:begin if (cnt		>=		500000-1)begin cnt					<=		64'd0;state				<=		state	+	1'b1;end cnt					<=		cnt	+	1'b1;end //***********************等待buf时间缓存31:begin if (cnt	>=	500)//5000000-1begin cnt					<=		64'd0;state				<=		state		+	1'b1;I_rx_en				<=		1'b0;I_tx_en				<=		1'b1;O_spi_cs			<=		1'b0;I_data_in			<=		Write_Enable;	strswitch			<=		1'b1;		
//					count				<=		25'd0;end else begin cnt					<=		cnt		+	1'b1;I_rx_en				<=		1'b0;I_tx_en				<=		1'b0;O_spi_cs			<=		1'b1;strswitch			<=		1'b1;end end 32:begin if (O_tx_done)state				<=		state	+	1'b1;else 	state				<=		state;end 33:begin I_tx_en				<=		1'b0;O_spi_cs			<=		1'b1;state				<=		state	+	1'b1;end //***********************页写入34:begin I_tx_en				<=		1'b1;O_spi_cs			<=		1'b0;I_data_in			<=		Quad_Input_Page_Program;	state				<=		state	+	1'b1;end 35:if (O_tx_done)begin I_data_in			<=		addr2[23:16];state				<=		state	+	1'b1;end else state				<=		state;36:begin if (O_tx_done)begin I_data_in			<=		addr2[15:8];state				<=		state	+	1'b1;end else state				<=		state;end 37:begin if (O_tx_done)begin I_data_in			<=		addr2[7:0];state				<=		state	+	1'b1;end else state				<=		state;end 38:begin 								//提前切换if (O_tx_done)begin strswitch			<=	1'b0;		//使用并行state				<=	state	+	1'b1;end else state				<=	state;end 39:begin I_tx_en				<=	1'b0;state				<=	state	+	1'b1;end 40:begin I_tx_en				<=	1'b1;I_data_in			<=	DATA_out;state				<=	state	+	1'b1;cnt					<=	cnt	+	1'b1;end 41:begin if (cnt	>=	257)begin cnt					<=	64'd0;state				<=	state	+	2;end else if (O_tx_done)begin strswitch			<=	1'b0;I_tx_en				<=	1'b0;I_data_in			<=	DATA_out;state				<=	state	+	1'b1;cnt					<=	cnt	+	1'b1;end else begin I_tx_en				<=	1'b1;state				<=	state;end end 42:begin if (O_tx_done)begin strswitch			<=	1'b0;I_tx_en				<=	1'b0;I_data_in			<=	DATA_out;state				<=	state	-	1'b1;cnt					<=	cnt	+	1'b1;end else begin I_tx_en				<=	1'b1;state				<=	state;end end 43:begin if (Sector_ER_DONE)begin state				<=	state	+	1'b1;end else if (addr2	>=		8388608-1)begin state				<=	state	+	1'b1;addr2				<=	24'd0;end else begin I_tx_en			<=	1'b0;O_spi_cs			<=	1'b1;state				<=	8'd31;addr2				<=	addr2	+	128;end end 44:begin strswitch			<=	1'b1 ;state				<=	state	+	1'b1;I_rx_en				<=	1'b0;I_tx_en				<=	1'b0;O_spi_cs			<=	1'b1;end 
//**************************************开时读取
//***********************写启动45:begin if (cnt	==	25000000-1)begin cnt 	<=	32'd0;state	<=	state	+	1'b1;end else begin cnt 	<=	cnt 	+	1'b1;state	<=	state;end end 46:begin state					<=	state		+	1'b1;I_rx_en				<=	1'b0;I_tx_en				<=	1'b1;O_spi_cs				<=	1'b0;I_data_in			<=	Write_Enable;		//启动状态寄存器strswitch			<=	1'b1;		addr2					<=	addr;end 47:begin if (O_tx_done)state					<=	state	+	1'b1;else 	state					<=	state;end 48:begin I_tx_en				<=	1'b0;O_spi_cs				<=	1'b1;state					<=	state	+	1'b1;end  //***********************读状态49:begin I_tx_en					<=	1'b1;O_spi_cs					<=	1'b0;state						<=	state	+	1'b1;strswitch				<=	1'b1;I_data_in				<=	Read_Status_Register_2;	end 50:begin if (O_tx_done)state					<=	state	+	1'b1;else state					<=	state;end 51:begin I_rx_en				<=	1'b1;I_tx_en				<=	1'b0;state					<=	state	+	1'b1;end 52:begin if (O_rx_done)begin DATA					<=	O_data_out;state					<=	state	+	1'b1;end else state					<=	state;end //***********************判读读取数据53:begin 	if (DATA[1:0]	==	2'b10)			begin O_spi_cs				<=	1'b1;I_rx_en				<=	1'b0;I_tx_en				<=	1'b0;state					<=	state	+	2;cnt					<=	64'd0;Register_error		<=	1'b0;end else begin Register_error		<=	1'b1;state					<=	state	+	2;end end 54:begin if (cnt		>=		500000-1)begin cnt					<=	64'd0;state					<=	state	+	1'b1;end cnt					<=	cnt	+	1'b1;end //***************增加缓存时间读取数据55:begin if (cnt	>=	500-1)begin cnt					<=	64'd0;state					<=	state	+	1'b1;end begin strswitch			<=	1'b1;cnt					<=	cnt	+	1'b1;
//					DATA					<=	8'hff;end end //********************四线制读取56:begin cnt						<=	64'd0;I_tx_en					<=	1'b1;O_spi_cs					<=	1'b0;state						<=	state	+	1'b1;I_data_in				<=	Fast_Read_Quad_Output;	end 57:if (O_tx_done)begin I_data_in			<=	addr2[23:16];state					<=	state	+	1'b1;end else state					<=	state;58:begin if (O_tx_done)begin I_data_in			<=	addr2[15:8];state					<=	state	+	1'b1;end else state					<=	state;end 59:begin if (O_tx_done)begin I_data_in			<=	addr2[7:0];state					<=	state	+	1'b1;end else state					<=	state;end 60:begin 								//提前切换if (O_tx_done)begin strswitch			<=	1'b0;		//使用并行state					<=	state	+	1'b1;end else state					<=	state;end //***************读取数据61:begin I_tx_en				<=	1'b0;I_rx_en				<=	1'b1;state					<=	state	+	1'b1;end 62:begin if (cnt	>=		257)begin cnt					<=	64'd0;state					<=	state	+	2;end else if (O_rx_done)begin DATA					<=	O_data_out;state					<=	state	+	1'b1;end else state					<=	state;end 63:begin if (DATA			==	DATA_out)begin cnt					<=	cnt	+	1'b1;state					<=	state	-	1'b1;DATA_error			<=	1'b0;end else begin DATA_error			<=	1'b1;state					<=	state	-	1'b1;end end //换页读取数据判断64:begin if (Sector_ER_DONE)begin state				<=	80;end else if (addr2	>=	8388608-1)begin state				<=	state	+	1'b1;addr2				<=	24'd0;end else begin addr2				<=	addr2	+	128;state				<=	8'd55;end end //  全片擦除10次 , 两个扇区擦除 1w次65:begin  if (Erase_count	==	10 - 1)begin O_spi_cs			<=	1'b1	;state				<=	state	+	1'b1;I_tx_en				<=	1'b0	;I_rx_en				<=	1'b0	;strswitch			<=	1'b1 	;addr					<=	24'd0		;end else begin O_spi_cs			<=	1'b1	;state				<=	8'd1 	;I_tx_en				<=	1'b0	;I_rx_en				<=	1'b0	;strswitch			<=	1'b1 	;end end  
//**********************************************************************启动两个扇区各擦除 1w次//*******************写启动66:begin O_spi_cs		<=	1'b0;I_tx_en		<=	1'b1;state			<=	state	+	1'b1;I_data_in	<=	Write_Enable;	end 67:begin if (O_tx_done)begin I_tx_en	<=	1'b0;state		<=	state	+	1'b1;end else state		<=	state;end //*******************延迟等待 68:begin if (cnt	==	2) begin cnt		<=		23'd0;O_spi_cs	<=		1'b1;state		<=		state	+	1'b1;end else begin cnt		<=		cnt		+	1'b1;state		<=		state;end end //*******************扇区擦除指令 69:begin O_spi_cs		<=	1'b0;I_tx_en		<=	1'b1;state			<=	state	+	1'b1;I_data_in	<=	Sector_Erase;			end 70:begin if (O_tx_done)begin I_data_in<=	addr[23:16];state		<=	state	+	1'b1;end else state		<=	state;end 71:begin if (O_tx_done)begin I_data_in<=	addr[15:8];state		<=	state	+	1'b1;end else state		<=	state;end 72:begin if (O_tx_done)begin I_data_in<=	addr[7:0];state		<=	state	+	1'b1;end else state		<=	state;end 73:begin if (O_tx_done)begin I_tx_en	<=	1'b0;state		<=	state	+	1'b1;end else state		<=	state;end //*******************延迟等待 74:begin if (cnt	==	2) begin cnt		<=		23'd0;O_spi_cs	<=		1'b1;state		<=		state	+	1'b1;end else begin cnt		<=		cnt		+	1'b1;state		<=		state;end end //*******************读取状态寄存器 75:begin O_spi_cs		<=	1'b0;I_tx_en		<=	1'b1;state			<=	state	+	1'b1;I_data_in	<=	Read_Status_Register_1;			end 76:begin if (O_tx_done)begin I_rx_en	<=		1'b1;I_tx_en	<=		1'b0;state		<=		state	+	1'b1;end else state		<=		state;end 	77:begin if (O_rx_done)begin DATA		<=	O_data_out;state		<=	state	+	1'b1;end else state		<=	state;end 78:begin if (DATA[0]	==	0)state		<=	state	+	1'b1;else state		<=	state	-	1'b1;end // 扇区擦除完成,进行写操作   ,  (跳转到13状态进行写数据与读取数据操作)79:begin Sector_ER_DONE	<=	1'b1;state				<=	13;addr2				<=	addr;end 80:begin //20000if (Erase_count	==	20000-10)begin I_rx_en		<=		1'b0;I_tx_en		<=		1'b0;state			<=	state	+	2;O_spi_cs		<=	1'b1;Erase_count	<=	Erase_count;end //10000else if (Erase_count	==	10000-10)begin I_rx_en		<=		1'b0;I_tx_en		<=		1'b0;state			<=	state	+	1;O_spi_cs		<=	1'b1;Erase_count	<=	Erase_count	+	1'b1;end else begin O_spi_cs		<=	1'b1;Erase_count	<=	Erase_count	+	1'b1;state			<=	66;end end //切换扇区    81:begin I_rx_en		<=	1'b0;I_tx_en		<=	1'b0;O_spi_cs		<=	1'b1;addr			<=	addr	+	128;state			<=	66;end //完成82:begin I_rx_en		<=	1'b0;I_tx_en		<=	1'b0;O_spi_cs		<=	1'b1;addr			<=	addr;state			<=	state;end default : ;endcase 
end endmodule 
`timescale 1 ps/ 1 ps
//
// Company:
// Engineer:
//
// Create Date: 11-08-2022 16:06:06
// Design Name:
// Module Name: SPI
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
// 
// Revision: 
// Additional Comments:
//
//module SPI(input               I_clk       , // 鍏ㄥ眬鏃堕挓1MHzinput               I_rst_n     , // 澶嶄綅淇″彿锛屼綆鐢靛钩鏈夋晥input               I_rx_en     , // 璇讳娇鑳戒俊鍙input               I_tx_en     , // 鍙戦€佷娇鑳戒俊鍙input        [7:0]  I_data_in   , // 瑕佸彂閫佺殑鏁版嵁input 				strswitch	, // 涓茶涓庡苟琛屽垏鎹1浣跨敤涓茶		0浣跨敤骞惰output  reg  [7:0]  O_data_out  , // 鎺ユ敹鍒扮殑鏁版嵁output  reg         O_tx_done   /*synthesis preserve*/, // 鍙戦€佷竴涓瓧鑺傚畬姣曟爣蹇椾綅output  reg         O_rx_done   , // 鎺ユ敹涓€涓瓧鑺傚畬姣曟爣蹇椾綅// 鍥涚嚎鏍囧噯SPI淇″彿瀹氫箟output  reg         O_spi_sck   , // SPI鏃堕挓inout		        O_spi_mosi  , // SPI杈撳嚭锛岀敤鏉ョ粰浠庢満鍙戦€佹暟鎹   	IO0inout               I_spi_miso  , // SPI涓茶杈撳叆锛岀敤鏉ユ帴鏀朵粠鏈虹殑鏁版嵁   IO1inout 				WP			, // IO2inout			    HOLD		  // IO3
);//------------------------------------------------------------------------------
//----------- Registers Declarations -------------------------------------------
//------------------------------------------------------------------------------
reg [3:0]   R_tx_state      		; 
reg [3:0]   R_rx_state      		;
reg [4:0]   R_tx_state_c      		;  
reg [3:0]   R_rx_state_c      		;
reg			fag_IO0					;
reg			fag_IO1					;
reg			fag_IO2					;
reg			fag_IO3					;
reg [5:0]	cnt						;//		1鍙戦€佺粰鑺墖鏁版嵁		0鎺ユ敹鑺墖鏁版嵁
assign		O_spi_mosi		=	I_tx_en==0	?	1'hz	:	fag_IO0;
assign		I_spi_miso		=	I_tx_en==0	?	1'hz	:	fag_IO1;
assign		WP				=	I_tx_en==0	?	1'hz	:	fag_IO2;
assign		HOLD			=	I_tx_en==0	?	1'hz	:	fag_IO3;always @(posedge I_clk )
beginif(!I_rst_n)beginR_tx_state  <=  4'd0    ;R_rx_state  <=  4'd0    ;R_tx_state_c<=	5'd0	;R_rx_state_c<=	4'd0	;O_spi_sck   <=  1'b0    ;O_tx_done   <=  1'b0    ;O_rx_done   <=  1'b0    ;O_data_out  <=  8'd0    ;fag_IO0		<=	1'b0	;fag_IO1		<=	1'b0	;fag_IO2		<=	1'b0	;fag_IO3		<=	1'b0	;cnt			<=	6'd0	;end else if(I_tx_en	&&	strswitch) // 鍙戦€佷娇鑳戒俊鍙锋墦寮€鐨勬儏鍐典笅begincase(R_tx_state_c)0:    // 鍙戦€佺7浣if (cnt	>=	25-1)begin cnt				<=	6'd0;R_tx_state_c  	<=  R_tx_state_c	+	1'b1;end else begincnt 			<=	cnt		+	1'b1	;	fag_IO0  		<=  I_data_in[7]        ;fag_IO1			<=	1'hz				;fag_IO2			<=	1'hz				;fag_IO3			<=	1'hz				;O_spi_sck   	<=  1'b0                ;R_tx_state_c  	<=  R_tx_state_c      	;O_tx_done   	<=  1'b0                ;end 1: if (cnt	>=	25-1)begin O_rx_done		<=	1'b0;cnt				<=	6'd0;R_tx_state_c  	<=  R_tx_state_c	+	1'b1;end else beginO_rx_done		<=	1'b0;cnt 			<=	cnt		+	1'b1		;			O_spi_sck   	<=  1'b1                	;R_tx_state_c  	<=  R_tx_state_c    		;O_tx_done  	 	<=  1'b0                	;end2:    // 鍙戦€佺6浣if (cnt	>=	25-1)begin cnt				<=	6'd0;R_tx_state_c  	<=  R_tx_state_c	+	1'b1;endelse begincnt 			<=	cnt		+	1'b1	;fag_IO0  		<=  I_data_in[6]        ;fag_IO1			<=	1'hz				;fag_IO2			<=	1'hz				;fag_IO3			<=	1'hz				;O_spi_sck   	<=  1'b0                ;R_tx_state_c  	<=  R_tx_state_c        ;O_tx_done   	<=  1'b0                ;end3: //鏁村悎濂囨暟鐘舵€if (cnt	>=	25-1)begin O_rx_done		<=	1'b0;cnt				<=	6'd0;R_tx_state_c  	<=  R_tx_state_c	+	1'b1;end else beginO_rx_done		<=	1'b0;cnt 			<=	cnt		+	1'b1		;			O_spi_sck   	<=  1'b1                	;R_tx_state_c  	<=  R_tx_state_c    		;O_tx_done  	 	<=  1'b0                	;end4:    // 鍙戦€佺5浣if (cnt	>=	25-1)begin cnt				<=	6'd0;R_tx_state_c  	<=  R_tx_state_c	+	1'b1;endelse begincnt 			<=	cnt		+	1'b1	;fag_IO0  		<=  I_data_in[5]        ;fag_IO1			<=	1'hz				;fag_IO2			<=	1'hz				;fag_IO3			<=	1'hz				;O_spi_sck   	<=  1'b0                ;R_tx_state_c  	<=  R_tx_state_c        ;O_tx_done   	<=  1'b0                ;end 5: //鏁村悎濂囨暟鐘舵€if (cnt	>=	25-1)begin O_rx_done		<=	1'b0;cnt				<=	6'd0;R_tx_state_c  	<=  R_tx_state_c	+	1'b1;end else beginO_rx_done		<=	1'b0;cnt 			<=	cnt		+	1'b1		;			O_spi_sck   	<=  1'b1                	;R_tx_state_c  	<=  R_tx_state_c    		;O_tx_done  	 	<=  1'b0                	;end6:    // 鍙戦€佺4浣if (cnt	>=	25-1)begin cnt				<=	6'd0;R_tx_state_c  	<=  R_tx_state_c	+	1'b1;endelse begincnt 			<=	cnt		+	1'b1	;fag_IO0  		<=  I_data_in[4]        ;fag_IO1			<=	1'hz				;fag_IO2			<=	1'hz				;fag_IO3			<=	1'hz				;O_spi_sck   	<=  1'b0                ;R_tx_state_c  	<=  R_tx_state_c    	;O_tx_done   	<=  1'b0                ;end 7: //鏁村悎濂囨暟鐘舵€if (cnt	>=	25-1)begin O_rx_done		<=	1'b0;cnt				<=	6'd0;R_tx_state_c  	<=  R_tx_state_c	+	1'b1;end else beginO_rx_done		<=	1'b0;cnt 			<=	cnt		+	1'b1		;			O_spi_sck   	<=  1'b1                	;R_tx_state_c  	<=  R_tx_state_c    		;O_tx_done  	 	<=  1'b0                	;end8:    // 鍙戦€佺3浣if (cnt	>=	25-1)begin cnt				<=	6'd0;R_tx_state_c  	<=  R_tx_state_c	+	1'b1;endelse begincnt 			<=	cnt		+	1'b1	;fag_IO0  		<=  I_data_in[3]        ;fag_IO1			<=	1'hz				;fag_IO2			<=	1'hz				;fag_IO3			<=	1'hz				;O_spi_sck   	<=  1'b0                ;R_tx_state_c  	<=  R_tx_state_c        ;O_tx_done   	<=  1'b0                ;end    9: //鏁村悎濂囨暟鐘舵€if (cnt	>=	25-1)begin O_rx_done		<=	1'b0;cnt				<=	6'd0;R_tx_state_c  	<=  R_tx_state_c	+	1'b1;end else beginO_rx_done		<=	1'b0;cnt 			<=	cnt		+	1'b1		;			O_spi_sck   	<=  1'b1                	;R_tx_state_c  	<=  R_tx_state_c    		;O_tx_done  	 	<=  1'b0                	;end 10:    // 鍙戦€佺2浣if (cnt	>=	25-1)begin cnt				<=	6'd0;R_tx_state_c  	<=  R_tx_state_c	+	1'b1;endelse begincnt 			<=	cnt		+	1'b1	;fag_IO0  		<=  I_data_in[2]        ;fag_IO1			<=	1'hz				;fag_IO2			<=	1'hz				;fag_IO3			<=	1'hz				;O_spi_sck   	<=  1'b0                ;R_tx_state_c  	<=  R_tx_state_c        ;O_tx_done   	<=  1'b0                ;end 11: //鏁村悎濂囨暟鐘舵€if (cnt	>=	25-1)begin O_rx_done		<=	1'b0;cnt				<=	6'd0;R_tx_state_c  	<=  R_tx_state_c	+	1'b1;end else beginO_rx_done		<=	1'b0;cnt 			<=	cnt		+	1'b1		;			O_spi_sck   	<=  1'b1                	;R_tx_state_c  	<=  R_tx_state_c    		;O_tx_done  	 	<=  1'b0                	;end12:    // 鍙戦€佺1浣if (cnt	>=	25-1)begin cnt				<=	6'd0;R_tx_state_c  	<=  R_tx_state_c	+	1'b1;endelse begincnt 			<=	cnt		+	1'b1	;fag_IO0  		<=  I_data_in[1]        ;fag_IO1			<=	1'hz				;fag_IO2			<=	1'hz				;fag_IO3			<=	1'hz				;O_spi_sck   	<=  1'b0                ;R_tx_state_c  	<=  R_tx_state_c      	;O_tx_done  	 	<=  1'b0                ;end 13: //鏁村悎濂囨暟鐘舵€if (cnt	>=	25-1)begin O_rx_done		<=	1'b0;cnt				<=	6'd0;R_tx_state_c  	<=  R_tx_state_c	+	1'b1;end else beginO_rx_done		<=	1'b0;cnt 			<=	cnt		+	1'b1		;			O_spi_sck   	<=  1'b1                	;R_tx_state_c  	<=  R_tx_state_c    		;O_tx_done  	 	<=  1'b0                	;end14:    // 鍙戦€佺0浣if (cnt	>=	25-1)begin O_tx_done   	<=  1'b0                ;cnt				<=	6'd0;R_tx_state_c  	<=  R_tx_state_c	+	1'b1;endelse beginO_tx_done   	<=  1'b0                ;cnt 			<=	cnt		+	1'b1	;fag_IO0  		<=  I_data_in[0]        ;fag_IO1			<=	1'hz				;fag_IO2			<=	1'hz				;fag_IO3			<=	1'hz				;O_spi_sck   	<=  1'b0                ;R_tx_state_c  	<=  R_tx_state_c        ;end15 : //鏁村悎濂囨暟鐘舵€if (cnt	>=	25-1)begin O_tx_done   	<=  1'b0                ;O_rx_done		<=	1'b0;cnt				<=	6'd0;R_tx_state_c  	<=  R_tx_state_c	+	1'b1;end else beginO_rx_done		<=	1'b0;cnt 			<=	cnt		+	1'b1		;			O_spi_sck   	<=  1'b1                	;R_tx_state_c  	<=  R_tx_state_c    		;O_tx_done  	 	<=  1'b0                	;end16:begin if (cnt	>=	25-1)begin O_rx_done		<=	1'b0;cnt				<=	6'd0				;O_tx_done   	<=  1'b1                ;R_tx_state_c	<=	0					;end else begin O_spi_sck   	<=  1'b0                	;O_rx_done		<=	1'b0;O_tx_done   	<=  1'b0                ;cnt 			<=	cnt		+	1'b1	;end end default:               ;   endcase endelse if(I_rx_en	&&	strswitch) // 鎺ユ敹浣胯兘淇″彿鎵撳紑鐨勬儏鍐典笅begincase(R_rx_state_c)4'd0, 4'd2 , 4'd4 , 4'd6  , 4'd8, 4'd10, 4'd12, 4'd14 : //鏁村悎鍋舵暟鐘舵€if (cnt	==	25-1)begin O_tx_done   	<=  1'b0                ;cnt				<=	6'd0;R_rx_state_c  	<=  R_rx_state_c	+	1'b1;end else beginO_tx_done   	<=  1'b0                ;cnt				<=	cnt 	+	1'b1	;O_spi_sck		<=	1'b0				;R_rx_state_c	<=	R_rx_state_c		;O_rx_done		<=	1'b0				;end4'd1:    // 鎺ユ敹绗浣if (cnt	==	25-1)begin cnt				<=	6'd0;R_rx_state_c  	<=  R_rx_state_c	+	1'b1;end else begin                       cnt				<=	cnt 	+	1'b1	;O_spi_sck       <=  1'b1                ;R_rx_state_c	<=	R_rx_state_c		;O_rx_done       <=  1'b0                ;O_data_out[7]   <=  I_spi_miso          ;   end4'd3:    // 鎺ユ敹绗浣if (cnt	==	25-1)begin cnt				<=	6'd0;R_rx_state_c  	<=  R_rx_state_c	+	1'b1;end else begincnt				<=	cnt 	+	1'b1	;O_spi_sck       <=  1'b1                ;R_rx_state_c	<=	R_rx_state_c	    ;O_rx_done       <=  1'b0                ;O_data_out[6]   <=  I_spi_miso          ; end4'd5:    // 鎺ユ敹绗浣if (cnt	==	25-1)begin cnt				<=	6'd0;R_rx_state_c  	<=  R_rx_state_c	+	1'b1;end else begincnt				<=	cnt 	+	1'b1	;O_spi_sck       <=  1'b1                ;R_rx_state_c	<=	R_rx_state_c	    ;O_rx_done       <=  1'b0                ;O_data_out[5]   <=  I_spi_miso          ; end 4'd7:    // 鎺ユ敹绗浣if (cnt	==	25-1)begin cnt				<=	6'd0;R_rx_state_c  	<=  R_rx_state_c	+	1'b1;end else begincnt				<=	cnt 	+	1'b1	;O_spi_sck       <=  1'b1                ;R_rx_state_c	<=	R_rx_state_c  	    ;O_rx_done       <=  1'b0                ;O_data_out[4]   <=  I_spi_miso          ; end 4'd9:    // 鎺ユ敹绗浣if (cnt	==	25-1)begin cnt				<=	6'd0;R_rx_state_c  	<=  R_rx_state_c	+	1'b1;end else begincnt				<=	cnt 	+	1'b1	;O_spi_sck       <=  1'b1                ;R_rx_state_c	<=	R_rx_state_c	    ;O_rx_done       <=  1'b0                ;O_data_out[3]   <=  I_spi_miso          ; end                            4'd11:    // 鎺ユ敹绗浣if (cnt	==	25-1)begin cnt				<=	6'd0;R_rx_state_c  	<=  R_rx_state_c	+	1'b1;end else begincnt				<=	cnt 	+	1'b1	;O_spi_sck       <=  1'b1                ;R_rx_state_c	<=	R_rx_state_c	    ;O_rx_done       <=  1'b0                ;O_data_out[2]   <=  I_spi_miso          ; end 4'd13:    // 鎺ユ敹绗浣if (cnt	==	25-1)begin cnt				<=	6'd0;R_rx_state_c  	<=  R_rx_state_c	+	1'b1;end else begincnt				<=	cnt 	+	1'b1	;O_spi_sck       <=  1'b1                ;R_rx_state_c	<=	R_rx_state_c	    ;O_rx_done       <=  1'b0                ;O_data_out[1]   <=  I_spi_miso          ; end 4'd15:    // 鎺ユ敹绗浣if (cnt	==	25-1)begin O_rx_done       <=  1'b1                ;cnt				<=	6'd0;R_rx_state_c  	<=  0;end else begincnt				<=	cnt 	+	1'b1	;O_spi_sck       <=  1'b1                ;R_rx_state_c	<=	R_rx_state_c	    ;O_data_out[0]   <=  I_spi_miso          ; enddefault:R_rx_state_c  <=  4'd0                    ;   endcase end    else if(I_tx_en	&&	strswitch==0) // 鍙戦€佷娇鑳戒俊鍙锋墦寮€鐨勬儏鍐典笅begincase(R_tx_state)4'd0:    // 鍙戦€佺0浣if (cnt	==	25-1)begin O_rx_done       <=  1'b0                ;cnt				<=	6'd0				;R_tx_state  	<=  R_tx_state	+	1'b1;end else begin O_rx_done       <=  1'b0                ;cnt				<=	cnt 	+	1'b1	;fag_IO0			<=   I_data_in[4]       ;fag_IO1			<=	 I_data_in[5]		;fag_IO2			<=	 I_data_in[6]		;fag_IO3			<=	 I_data_in[7]		;O_spi_sck   	<=  1'b0                ;R_tx_state  	<=  R_tx_state          ;O_tx_done   	<=  1'b0                ;end 4'd1:if (cnt	==	25-1)begin O_rx_done       <=  1'b0               ;cnt				<=	6'd0				;R_tx_state  	<=  R_tx_state	+	1'b1;end else begin O_rx_done       <=  1'b0                ;cnt				<=	cnt 	+	1'b1	;O_spi_sck   	<=  1'b1                ;R_tx_state  	<=  R_tx_state	   		;O_tx_done   	<=  1'b0                ;end4'd2:    // 鍙戦€佺1浣if (cnt	==	25-1)begin O_rx_done       <=  1'b0                ;cnt				<=	6'd0				;R_tx_state  	<=  R_tx_state	+	1'b1;end else begin O_rx_done       <=  1'b0                ;cnt				<=	cnt 	+	1'b1	;fag_IO0			<=  I_data_in[0]        ;fag_IO1			<=	I_data_in[1]		;fag_IO2			<=	I_data_in[2]		;fag_IO3			<=	I_data_in[3]		;O_spi_sck   	<=  1'b0                ;R_tx_state  	<=  R_tx_state 	   		;O_tx_done   	<=  1'b0                ;end4'd3:if (cnt	==	25-1)begin O_rx_done       <=  1'b0                ;cnt				<=	6'd0				;R_tx_state  	<=  R_tx_state	+	1'b1;end else begin O_rx_done       <=  1'b0                ;cnt				<=	cnt 	+	1'b1	;O_spi_sck   	<=  1'b1                ;R_tx_state  	<=  R_tx_state 		    ;O_tx_done   	<=  1'b0                ;end4'd4:if (cnt	==	25-1)begin O_rx_done       <=  1'b0                ;cnt				<=	6'd0				;O_tx_done   	<=  1'b1                ;R_tx_state  	<=  4'd0     	        ;end else begin O_rx_done       <=  1'b0                ;cnt				<=	cnt 	+	1'b1	;O_spi_sck   	<=  1'b0                ;R_tx_state  	<=  R_tx_state 		    ;end default: ;   endcase endelse if(I_rx_en	&&	strswitch==0) // 鎺ユ敹浣胯兘淇″彿鎵撳紑鐨勬儏鍐典笅begincase(R_rx_state)4'd0:if (cnt	==	25-1)begin O_tx_done   	<=  1'b0                ;O_rx_done       <=  1'b0                ;cnt				<=	6'd0				;R_rx_state  	<=  R_rx_state	+	1'b1;end else begin O_tx_done   	<=  1'b0                ;cnt				<=	cnt 	+	1'b1	;O_spi_sck		<=	1'b0				;R_rx_state		<=	R_rx_state	 		;O_rx_done		<=	1'b0				;end 4'd1:    // 鎺ユ敹绗浣if (cnt	==	25-1)begin O_rx_done       <=  1'b0                ;cnt				<=	6'd0				;R_rx_state  	<=  R_rx_state	+	1'b1;end else begin 	cnt				<=	cnt 	+	1'b1	;O_spi_sck       <=  1'b1                ;R_rx_state      <=  R_rx_state 		    ;O_rx_done       <=  1'b0                ;O_data_out[4]   <=  O_spi_mosi			;   O_data_out[5]   <=  	I_spi_miso				;O_data_out[6]   <=  	WP		;O_data_out[7]   <=  HOLD				;	end4'd2:if (cnt	==	25-1)begin O_rx_done       <=  1'b0                ;cnt				<=	6'd0				;R_rx_state  	<=  R_rx_state	+	1'b1;end else begin cnt				<=	cnt 	+	1'b1	;O_spi_sck		<=	1'b0				;R_rx_state		<=	R_rx_state			;O_rx_done		<=	1'b0				;end 4'd3:    // 鎺ユ敹绗浣if (cnt	==	25-1)begin O_rx_done       <=  1'b0                ;cnt				<=	6'd0				;R_rx_state  	<=  R_rx_state	+	1'b1;end else begin cnt				<=	cnt 	+	1'b1	;O_spi_sck       <=  1'b1                ;R_rx_state      <=  R_rx_state          ;O_rx_done       <=  1'b0                ;O_data_out[0]   <=  O_spi_mosi			;   O_data_out[1]   <=  I_spi_miso			;O_data_out[2]   <=  WP					;O_data_out[3]   <=  HOLD				;	end4'd4:if (cnt	==	25-1)begin O_rx_done       <=  1'b1                ;cnt				<=	6'd0				;R_rx_state		<=	4'd0     	        ;end else begin cnt				<=	cnt 	+	1'b1	;O_spi_sck		<=	1'b0				;R_rx_state		<=	R_rx_state			;end default: ;   endcase end    elsebeginR_tx_state  <=  4'd0    ;R_rx_state  <=  4'd0    ;R_tx_state_c<=	5'd0	;R_rx_state_c<=	4'd0	;O_tx_done   <=  1'b0    ;O_rx_done   <=  1'b0    ;O_spi_sck   <=  1'b0    ;O_data_out  <=  8'd0    ;cnt 		<=	6'd0	;end      
endendmodule


结论

        综上所述,通过利用FPGA实现的该程序,成功实现了Flash存储器的写入使能、整片擦除、全片写入和全片数据读取功能。这些功能的实现为Flash存储器的使用带来了更大的便利性和灵活性,使得数据的存储和访问更加可靠和高效。通过该程序,用户能够有效地控制Flash存储器的操作,并实现对整个存储器的快速擦除和写入,以及高效的数据读取。这些功能的结合为各种应用场景提供了更多的选择和解决方案。

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

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

相关文章

算法练习Day23 (Leetcode/Python-回溯算法)

46. Permutations Given an array nums of distinct integers, return all the possible permutations. You can return the answer in any order. Example 1: Input: nums [1,2,3] Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]思路&#xff1a;此题可用回溯…

SELinux策略语法以及示例策略

首发公号&#xff1a;Rand_cs 本文来讲述 SELinux 策略常用的语法&#xff0c;然后解读一下 SELinux 这个项目中给出的示例策略 安全上下文 首先来看一下安全上下文的格式&#xff1a; user : role : type : level每一个主体和客体都有一个安全上下文&#xff0c;通常也称安…

oracle学习(6)

其他数据库对象 视图&#xff1a; 常见数据库对象——视图&#xff1a;从表中抽出的逻辑上相关的数据集合。 所以&#xff1a;1. 视图基于表。2. 视图是逻辑概念。3. 视图本身没有数据。 创建视图 创建语法与创建表类似&#xff0c;只需要将table → view即可: SQL> …

Selenium教程04:鼠标+键盘网页的模拟操作

在webdriver 中&#xff0c;鼠标操作都封装在ActionChains类中&#xff0c;使用的时候需要导入这个包。 from selenium.webdriver import ActionChainsActionChains方法列表如下&#xff1a; click(on_elementNone) ——单击鼠标左键click_and_hold(on_elementNone) ——点击…

将PPT4页并排成1页

将PPT4页并排成1页打印 解决方法: 方法一 在打印时选择&#xff1a; 打开 PPT&#xff0c;点击文件选项点击打印点击整页幻灯片点击4张水平放置的幻灯平页面就会显示4张PPT显示在一张纸上 方法二 另存为PDF&#xff1a; 打开电脑上的目标PPT文件&#xff0c;点击文件点击…

Android 提取(备份)apk(安装包)

Android 提取(备份)apk(安装包) 一、通过安卓代码的方式 主要分三步&#xff1a; 根据应用找到包名根据包名获得apk提取apk 提取apk代码 private static final String BACKUP_PATH "/sdcard/backup1/"; private static final String APK ".apk";pri…

11.2 Screen调试实战(二,运行时阶段)

三,运行时阶段 运行时出现的问题是比较难查的。 其中一些问题可能是: 应用程序发送了错误的请求应用程序未发送请求驱动问题OpenGL函数调用异常我们可以使用一些调试工具或通过slog2info打印的日志排查问题。 3.1 请求 我们可以通过持久化保存/dev/screen/requests 文件的…

可拖拽流程图组件开发

效果 说在前面 流程图在技术领域是一种常见的可视化工具&#xff0c;用于展示系统、应用或业务流程的各个步骤以及它们之间的关系。它们可以帮助开发人员和项目团队更好地理解和规划复杂的流程&#xff0c;从而提高工作效率和准确性。但是&#xff0c;传统的静态流程图有时无法…

《深入理解C++11:C++11新特性解析与应用》笔记七

第七章 为改变思考方式而改变 7.1 指针空值--nullptr 7.1.1 指针空值&#xff1a;从0到NULL&#xff0c;再到nullptr 传统C头文件里NULL是一个宏定义&#xff1a; 在函数重载同时出现int和char *参数版本的函数时&#xff0c;使用NULL作为参数调用函数会调用int参数版本&…

12-数据结构-排序

排序算法 一.比较类排序 1.交换排序 (1).冒泡 #include <stdio.h>void PrintContext(char sort[], int size) {for(int i0;i<size;i){printf("%d ", sort[i]);}printf("\n"); }//冒泡排序 //Reverse 0:正向排序 //Reverse 1:反向排序 void Order…

【数据库原理】(2)数据库管理系统(DBMS)介绍

数据库管理系统&#xff08;Database Management System, DBMS&#xff09;是一种特殊的软件&#xff0c;它充当用户和电脑操作系统之间的中间层。它的主要任务是帮助用户轻松地创建、使用和维护数据库&#xff0c;同时确保数据的安全、完整性&#xff0c;以及支持多用户同时访…

elasticsearch系列九:异地容灾-CCR跨集群复制

概述 起初只在部分业务中采用es存储数据&#xff0c;在主中心搭建了个集群&#xff0c;随着es在我们系统中的地位越来越重要&#xff0c;数据也越来越多&#xff0c;针对它的安全性问题也越发重要&#xff0c;那如何对es做异地容灾呢&#xff1f; 今天咱们就一起看下官方提供的…

【电商项目实战】商品详情显示与Redis存储购物车信息

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《电商项目实战》。&#x1f3af;&#x1f3af; &am…

合伙企业有哪些分类

合伙企业分为&#xff1a;普通合伙企业和有限合伙企业。其中&#xff0c;普通合伙企业又包含特殊的普通合伙企业。 1、普通合伙企业由2人以上普通合伙人(没有上限规定)组成。 普通合伙企业中&#xff0c;合伙人对合伙企业债务承担无限连带责任。 特殊的普通合伙企业中&#xf…

软件测试/测试开发丨Python 封装 学习笔记

封装的概念 封装&#xff08;Encapsulation&#xff09; 隐藏&#xff1a;属性和实现细节&#xff0c;不允许外部直接访问暴露&#xff1a;公开方法&#xff0c;实现对内部信息的操作和访问 封装的作用 限制安全的访问和操作&#xff0c;提高数据安全性可进行数据检查&#x…

『番外篇九』SwiftUI 实战:打造一款“五脏俱全”的网络图片显示 App(上)

概览 俗话说得好:“读书破万卷,下笔如有神”。不过如果把这句话放到编程的学习上可就不那么贴切了。 要想熟练掌握一门编程语言,光看书是绝对不够的。我们还需尽可能的多撸码、早撸码,撸到无路可退、海枯石烂才有可能一窥门径。 在本篇和续篇博文中,我们将和小伙伴们一起…

7.优化前后端交互的秘诀

注释规约 【强制】类、类属性、类方法的注释必须使用 Javadoc 规范&#xff0c;使用/*内容/格式&#xff0c;不得使用 // xxx 方式。 说明&#xff1a;在 IDE 编辑窗口中&#xff0c;Javadoc 方式会提示相关注释&#xff0c;生成 Javadoc 可以正确输出相应注释&#xff1b;在 I…

c++_09_继承

1 继承 C的继承是弱继承 继承的语法&#xff1a; class 子类 : 继承方式1 基类1, 继承方式2 基类2, ... { ... }; 继承方式&#xff1a; 共有继承 public 保护继承 protected 私有继承 private 2 继承的基本属性&#xff08;3种继承方式均有&#xff09; 继承所…

Javaweb之JDBC的详细解析

2. JDBC介绍(了解) 2.1 介绍 通过Mybatis的快速入门&#xff0c;我们明白了&#xff0c;通过Mybatis可以很方便的进行数据库的访问操作。但是大家要明白&#xff0c;其实java语言操作数据库呢&#xff0c;只能通过一种方式&#xff1a;使用sun公司提供的 JDBC 规范。 Mybatis…

从 MySQL 的事务 到 锁机制 再到 MVCC

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、事务 1.1 含义 1.2 ACID 二、锁机制 2.1 锁分类 2.2 隔离级别 三、MVCC 3.1 介绍 3.2 隔离级别 3.3 原理 四、总结 前…