FPGA开发——IIC实现简单的串口回环

news2024/9/20 14:55:15

一、概述

        在我们进行日常开发时,不管是进行MCU、单片机、还是FPGA,都会使用到IIC通信协议。采用串行总线可以简化系统硬件结构、减小系统体积、提高系统可靠性。常 用的串行总线有单总线(1-Wire Bus)、IICInter-Integrated Circuit)、SPISerial Peripheral Interface)等。 IIC 总线是 Phlips 公司推出的一种同步串行总线,是一种支持多主机多从机 系统、总线仲裁以及高低速器件同步功能的高性能串行总线技术。

        在前面学习串口通信的时候,我们实现了数据回环的设计,现在我们学到了IIC通信协议,我们也来进行一下简单的IIC数据回环的设计,所谓的IIC数据回环设计就是在使用我们设计出的串口的基础之上,编写IIC的主机和从机,按照IIC通信协议的要求,进行一个数据的交互,从而实现IIC的数据回环实现。今天这篇文章的目的就是为了让我们熟悉一下IIC的通信协议。

二、框架构造

1、总体系统框架

        在框图中可以看到,我们实现的思路就是通过串口接收和发送模块实现与PC机的交互,从而实现数据的回环,而IIC的作用就是通过对于接收模块接收到的数据进行处理,最后把数据传递给发送模块。        

2、IIC主机模块

图中我们把SDA分成了三根线,在代码端口定义中我们对于sda_oen,sda_out,sda_in进行了处理,最后只使用了一根线。

 

3、从机模块

因为我们在主机中对于SDA线进行了处理,所以对与从机来说,只需要一根线接收就行,只不过为了方便观察我们写出来了。

 

三、工程实现

1、IIC主机模块的代码编写

        新建一个iic_master.v文件,如下:这里的输入数据是来自串口接收模块接收到的数据

//---------<模块及端口声名>-------------------------------------------
module iic_master( 
    input				clk		,
    input				rst_n	,
    //IIC
    input		[7:0]   din		,
    input               send_en ,
    //iic_slave从机数据
    output		reg    	iic_scl	,
    inout		    	iic_sda	
);								 
//---------<参数定义>------------------------------------------------
parameter  CLK   =50_000_000 ;
parameter  SPEED =100_000;//传输速率
//---------<内部信号定义>--------------------------------------------
parameter      IDLE     =5'b000_01 ,
               START    =5'b000_10 ,
               TRANS    =5'b001_00 ,
               ACK      =5'b010_00 ,
               STOP     =5'b100_00 ;

parameter  CNT_MAX =CLK/SPEED;

reg             iic_sda_out;
reg             iic_sda_en ;
wire            iic_sda_in ;

reg     [9:0]  scl_cnt;//SCL时钟计数器
wire           add_scl_cnt;
wire           end_scl_cnt;

reg		[3:0]	cnt_bit	   ;
wire			add_cnt_bit;
wire			end_cnt_bit;

reg            iic_scl_r;
wire            nedge;   
reg     [4:0]   state_c ;//现态
reg     [4:0]   state_n ;//次态

wire    idle2start  ;
wire    start2trans ;
wire    trans2ack   ;
wire    ack2stop    ;
wire    stop2idle   ;

reg     [7:0] din_r;//输入数据缓存

//IIC_SDA描述
assign iic_sda =iic_sda_en ? iic_sda_out : 1'bz;
assign iic_sda_in =iic_sda;
//第一段:同步时序描述状态转移
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        state_c <=IDLE ;
    end 
    else begin 
        state_c <= state_n;
    end 
end
    
//第二段:组合逻辑判断状态转移条件,描述状态转移规律
always @(*) begin
    case(state_c)
        IDLE  : begin
            if(idle2start)
                state_n = START;
            else
                state_n = state_c; 
        end
        START : begin
            if(start2trans)
                state_n = TRANS;
            else
                state_n = state_c; 
        end
        TRANS : begin
            if(trans2ack)
                state_n = ACK;
            else
                state_n = state_c; 
        end
        ACK   : begin
            if(ack2stop)
                state_n = STOP;
            else
                state_n = state_c; 
        end
        STOP  : begin
            if(stop2idle)
                state_n = IDLE;
            else
                state_n = state_c; 
        end
        default : ;
    endcase
end

assign idle2start  = state_c == IDLE  && send_en;
assign start2trans = state_c == START && end_scl_cnt;
assign trans2ack   = state_c == TRANS && end_cnt_bit;
assign ack2stop    = state_c == ACK   && end_scl_cnt;
assign stop2idle   = state_c == STOP  && end_scl_cnt;

//第三段:描述状态输出(组合逻辑/时序逻辑)
//scl_cnt
always @(posedge clk or negedge rst_n)begin 
   if(!rst_n)begin
        scl_cnt <= 'd0;
    end 
    else if(add_scl_cnt)begin 
        if(end_scl_cnt)begin 
            scl_cnt <= 'd0;
        end
        else begin 
            scl_cnt <= scl_cnt + 1'b1;
        end 
    end
end 

assign add_scl_cnt = state_c!=IDLE ;
assign end_scl_cnt = add_scl_cnt && scl_cnt ==CNT_MAX-1 ;
//IIC_SCL时钟
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)
       iic_scl  <=1'b1;
    else if(state_c !=IDLE && scl_cnt<=CNT_MAX/2-1)
       iic_scl <= 1'b0;
    else
       iic_scl <=1'b1;
end    

//bit计数器
always @(posedge clk or negedge rst_n)begin 
   if(!rst_n)begin
        cnt_bit <= 'd0;
    end 
    else if(add_cnt_bit)begin 
        if(end_cnt_bit)begin 
            cnt_bit <= 'd0;
        end
        else begin 
            cnt_bit <= cnt_bit + 1'b1;
        end 
    end
end 

assign add_cnt_bit =(state_c ==TRANS) && end_scl_cnt ;
assign end_cnt_bit = add_cnt_bit && cnt_bit ==8-1 ;

//din_r
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        din_r <= 'd0;
    end 
    else if(send_en)begin 
        din_r <= din;
    end 
end

 always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        iic_sda_en <= 'd0;
        iic_sda_out <= 'd1;
    end 
    else begin
        case (state_c)
            IDLE  :begin//修改
                iic_sda_en <= 'd0;
                iic_sda_out <= 1'b1;
            end
            START :begin
                iic_sda_en <= 1'b1;
                if((iic_scl==1) && (scl_cnt>=(CNT_MAX/2+CNT_MAX/4)))
                    iic_sda_out <= 1'b0;
                else
                    iic_sda_out <= 1'b1;
            end
            TRANS :begin
                    iic_sda_en <= 1'b1;
                    if((iic_scl==0) && (scl_cnt <=CNT_MAX>>2))
                        iic_sda_out <= din_r[7-cnt_bit];               
            end
            ACK   :begin
                iic_sda_en <= 1'b0;
                iic_sda_out <= 1'bz;
            end
            STOP  :begin
                iic_sda_en <= 1'b1;
                if(scl_cnt<=CNT_MAX>>2)
                    iic_sda_out <= 1'b0;
                else if((iic_scl==1) && (scl_cnt>=(CNT_MAX/2+CNT_MAX/4)))
                    iic_sda_out <= 1'b1;
            end
            default:;
        endcase
    end
 end   
endmodule 


2、从机模块代码的编写

这里和主机模块一样也是新建一个iic_slave.v文件,如下:

    
//---------<模块及端口声名>-------------------------------------------
module iic_slave( 
    input				clk		,
    input				rst_n	,
    //IIC
    input				iic_scl	,
    inout		        iic_sda	,
    //uart_tx
    output	reg	[7:0]	dout	,//串口发送模块输入数据
    output	reg     	dout_vld //串口发送模块输入数据标志位
);								 
//---------<参数定义>------------------------------------------------
parameter  CLK   =50_000_000 ;
parameter  SPEED =100_000;//传输速率
//---------<内部信号定义>--------------------------------------------
parameter      IDLE     =5'b000_01 ,
               START    =5'b000_10 ,
               TRANS    =5'b001_00 ,
               ACK      =5'b010_00 ,
               STOP     =5'b100_00 ;

parameter  CNT_MAX =CLK/SPEED;

reg iic_scl_r1;//同步打拍
reg iic_scl_r2;
reg iic_sda_r1;
reg iic_sda_r2;

wire     sda_nedge;//sda信号检测
wire     sda_pedge;

wire     scl_nedge;//scl信号检测
wire     scl_pedge;

reg         iic_sda_en;//对于sda线进行一个描述(三台门)
reg         iic_sda_out;
wire        iic_sda_in;

reg   [3:0]  cnt_bit;
wire         add_cnt_bit;
wire         end_cnt_bit;

reg     [9:0]  scl_cnt;//SCL时钟计数器
wire           add_scl_cnt;
wire           end_scl_cnt;   

reg     [4:0]   state_c ;//现态
reg     [4:0]   state_n ;//次态

wire    idle2start  ;
wire    start2trans ;
wire    trans2ack   ;
wire    ack2stop    ;
wire    stop2idle   ;

reg     [7:0] dout_r;//输出数据寄存器
//sda信号描述
assign  iic_sda = iic_sda_en ? iic_sda_out :1'bz;
assign  iic_sda_in = iic_sda;
//第一段:同步时序描述状态转移
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        state_c <= IDLE;
    end 
    else begin 
        state_c <= state_n;
    end 
end
    
//第二段:组合逻辑判断状态转移条件,描述状态转移规律
always @(*) begin
    case(state_c)
        IDLE  : begin
            if(idle2start)
                state_n<=START   ;
            else
                state_n<= state_c;     
        end
        START : begin
            if(start2trans)
                state_n<=TRANS   ;
            else
                state_n<= state_c;     
        end
        TRANS : begin
            if(trans2ack)
                state_n<=ACK   ;
            else
                state_n<= state_c;     
        end
        ACK   : begin
            if(ack2stop)
                state_n<=STOP   ;
            else
                state_n<= state_c;     
        end
        STOP  : begin
            if(stop2idle)
                state_n<=IDLE   ;
            else
                state_n<= state_c;     
        end
        default : state_n <=IDLE ;
    endcase
end
assign idle2start  = (state_c == IDLE    ) && (iic_scl_r2 && sda_nedge);
assign start2trans = (state_c == START   ) && (scl_nedge);
assign trans2ack   = (state_c == TRANS   ) && (end_cnt_bit);
assign ack2stop    = (state_c == ACK     ) && (scl_nedge);
assign stop2idle   = (state_c == STOP    ) && (iic_scl_r2 && sda_pedge);

//第三段:描述状态输出(组合逻辑/时序逻辑) 
//对于scl输入信号进行打拍
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        iic_scl_r1 <= 1'b1;
        iic_scl_r2 <= 1'b1;
    end 
    else begin 
        iic_scl_r1 <= iic_scl;
        iic_scl_r2 <= iic_scl_r1;
    end 
end 
assign scl_nedge= ~iic_scl_r1 && iic_scl_r2 ;
assign scl_pedge= iic_scl_r1 && ~iic_scl_r2 ;
//对于sda输入信号进行打拍
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        iic_sda_r1 <= 1'b1;
        iic_sda_r2 <= 1'b1;
    end 
    else begin 
        iic_sda_r1 <= iic_sda;
        iic_sda_r2 <= iic_sda_r1;
    end 
end 
assign sda_nedge= ~iic_sda_r1 && iic_sda_r2 ;
assign sda_pedge= iic_sda_r1 && ~iic_sda_r2 ;

//bit计数器
always @(posedge clk or negedge rst_n)begin 
   if(!rst_n)begin
        cnt_bit <= 'd0;
    end 
    else if(add_cnt_bit)begin 
        if(end_cnt_bit)begin 
            cnt_bit <= 'd0;
        end
        else begin 
            cnt_bit <= cnt_bit + 1'b1;
        end 
    end
end 

assign add_cnt_bit =(state_c ==TRANS) && scl_nedge ;
assign end_cnt_bit = add_cnt_bit && cnt_bit ==8-1 ;

//sda_en、sda_out
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        iic_sda_en <= 'd0;
        iic_sda_out <= 'd1;
    end 
    else if(state_c==ACK)begin
        iic_sda_en <= 1'b1;
        iic_sda_out <= 1'b0;
    end
    else begin
        iic_sda_en  <= 'd0;
        iic_sda_out <= 'd0;
    end
end   

//数据类型转换,串转并
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        dout_r <= 'd0;
    end 
    else if(state_c==TRANS  && iic_scl_r2)begin 
        dout_r[7-cnt_bit] <=iic_sda_r2;
    end 
end 
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        dout <= 'd0;
    end  
    else if(state_c==STOP)begin 
       dout <=dout_r; 
    end 
end

always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        dout_vld <= 'd0;
    end  
    else begin 
       dout_vld <=stop2idle; 
    end 
end
endmodule 

关于串口接收和发送模块的代码在前面的文章中已经写过了,如果不知道怎么写的小伙伴直接去前面文章里面找就行。

3、顶层文件 的编写

通过顶层文件将串口接收模块和IIC主从机模块连接起来,从而实现数据回环。

新建top.v文件,如下:

module top (
    input       clk     ,
    input       rst_n   ,
    input       rx      ,
    output      tx          
);
wire  [7:0] rx_dout;
wire        rx_dout_vld;
wire            busy;
wire           iic_scl;
wire           iic_sda;
wire    [7:0]  tx_din    ;
wire           tx_din_vld;
uart_rx uart_rx_inst(
    /*input            */ .clk	     (clk        ),
    /*input            */ .rst_n     (rst_n	 ),        
    /*input            */ .din_rx    (rx     ),
    /*output  reg[7:0] */ .dout_data (rx_dout  ),
    /*output  reg      */ .dout_flag (rx_dout_vld  )
);

iic_master iic_master_inst( 
    /*input				  */.clk		(clk    ),
    /*input				  */.rst_n	    (rst_n  ),
    /*input       [7:0]   */.din    (rx_dout),
    /*input               */.send_en    (rx_dout_vld),//开始传输的使能信号
    /*output  reg         */.iic_scl    (iic_scl),
    /*inout               */.iic_sda    (iic_sda)
);		

iic_slave u_iic_slave( 
    /*input				  */.clk		    (clk    ),
    /*input				  */.rst_n	        (rst_n  ),
    /*input               */.iic_scl        (iic_scl),
    /*inout               */.iic_sda        (iic_sda),
    /*output   reg  [7:0] */.dout	        (tx_din    ),
    /*output   reg        */.dout_vld       (tx_din_vld)  
);		

uart_tx uart_tx_inst(
    /*input        */ .clk        (clk      ) ,
    /*input        */ .rst_n      (rst_n    ) ,
    /*input   [7:0]*/ .tx_din     (tx_din     ) ,//进入发送模块准备发送的数据
    /*input        */ .tx_din_vld (tx_din_vld && ~busy    ) ,//要发送数据的有效信号
    /*output  reg  */ .tx_dout    (tx       ) ,//串行发送出去的数据
    /*output  reg  */ .busy       (busy   )  //发送一字节完成信号
);
endmodule

4、IIC测试文件的编写

因为串口我们前面已经写了并且测试过,所以这里我们只需要进行IIC的主机和从机进行一个仿真就可以得出结果,只要在这里数据能够正常交互,IIC的数据回环就没啥问题。

新建一个iic_tb.v文件,如下:

`timescale 1ns/1ps
    
module iic_tb();

//激励信号定义 
    reg				tb_clk  	;
    reg				tb_rst_n	;
    reg     [7:0]   data_in     ;
    reg             send_en     ;
    reg             sda_in      ;

//内部信号定义	 
    wire	        iic_scl     ;
    wire            iic_sda     ;
//输出信号定义
    wire    [7:0]   r_data      ;
    wire            r_data_vld  ;

    pullup(iic_sda);

//时钟周期参数定义	
    parameter		CLOCK_CYCLE = 20;   

//模块例化
    iic_master iic_master_inst( 
    /*input				  */.clk	    (tb_clk     ),
    /*input				  */.rst_n	    (tb_rst_n   ),
    /*input       [7:0]   */.din		(data_in    ),
    /*input               */.send_en    (send_en    ),//开始传输的使能信号
    /*output  reg         */.iic_scl    (iic_scl    ),
    /*inout               */.iic_sda    (iic_sda    )
);	

    iic_slave iic_slave_inst( 
    /*input				  */.clk		    (tb_clk     ),
    /*input				  */.rst_n	        (tb_rst_n   ),
    //iic_master()
    /*input               */.iic_scl        (iic_scl    ),
                            .iic_sda        (iic_sda    ),
    //uart_tx()
    /*output   reg        */.dout         (r_data     ),
    /*output   reg        */.dout_vld     (r_data_vld )
);	

//产生时钟
    initial 		tb_clk = 1'b0;
    always #(CLOCK_CYCLE/2) tb_clk = ~tb_clk;

//产生激励
    initial  begin 
        tb_rst_n = 1'b1;
        data_in = 0;
        send_en = 0;
        sda_in = 1'b1;
        #(CLOCK_CYCLE*2);
        tb_rst_n = 1'b0;
        #(CLOCK_CYCLE*20);
        tb_rst_n = 1'b1;

        #3;
        repeat(10)begin
            data_in = {$random}%256;
            send_en = 1'b1;
            #CLOCK_CYCLE;
            send_en = 1'b0;
            wait(iic_master_inst.stop2idle);
            #500;
        end
        

        #2000;
        $stop;


    end

endmodule 



                                            

5、波形仿真

通过观察IIC仿真波形图中的输入和输出数据结果可知,两者是一样的,说明我们设计的IIC主机和从机模块没有问题。

 

6、下板验证

通过串口调试助手我们可以看到数据正常交互。设计完成。

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

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

相关文章

Codeforces Round 926 (Div. 2) C. Sasha and the Casino (博弈论*1400)

这里的意思是想让我们求得是否是能够实现不停地无上限的赚钱。 这里注意避开一个思维误区&#xff0c;如果你想的是前x次一直用1枚硬币然后吃第x1次保底&#xff0c;那么就是错误的。你应该考虑到如果前x次里面出现了胜利呢&#xff1f;这时候你拿着一枚硬币根本赚不回本。 所…

全志H616系统启动和登录

一、系统启动 刷完机烧入镜像&#xff0c;直接用MobaXterm软件串口登陆 约定固定的波特率115200。 默认登录&#xff1a; 用户&#xff1a;orangepi 密码&#xff1a;orangepi 或用户&#xff1a;root 密码&#xff1a;orangepi 在输入密码时…

YOLO 单目测距:原理、方法与代码

一、原理 单目测距的一个常见方法是假设物体的尺寸已知。通过测量物体在图像中的高度&#xff08;或宽度&#xff09;&#xff0c;并结合物体的实际高度&#xff08;或宽度&#xff09;&#xff0c;最简单的一种方式就是利用相似三角形的原理来计算物体的距离。 二、相似三角…

使用深度学习来进行击剑动作识别的裁判工作

在击剑比赛中&#xff0c;当双方几乎同时击中对方时&#xff0c;记分板两边都会亮起。这时裁判需要决定哪一方得分。一般而言&#xff0c;谁更主动或控制了局势就会得分。我尝试训练了一个模型来辅助裁判做这样的判断&#xff01;目前该模型在花剑测试集上的准确率大约为60%&am…

Vue开发者工具安装详细教程

欢迎大家订阅【Vue2Vue3】入门到实践 专栏&#xff0c;开启你的 Vue 学习之旅&#xff01; 文章目录 前言一、下载二、安装三、调试 前言 Vue 是一个框架&#xff0c;也是一个生态&#xff0c;其功能覆盖了大部分前端开发常见的需求。本文详细讲解了 Vue 开发者工具的安装。 …

ES7.17.5 float类型 terms带来的隐患

背景 1.用户在mapping中加一个字段 testid&#xff0c;结果写数据的时候使用 testId&#xff0c;同时也没有strict限制动态mapping&#xff0c;只是使用了默认的 true&#xff0c;即允许动态生成mapping 2.动态生成的字段 testId 被识别成了 float&#xff0c;用户为了方便&a…

【Netty 一】

Netty是什么 Netty 是一个高性能、异步事件驱动的 NIO 框架&#xff0c;基于 JAVA NIO 提供的 API 实现。它提供了对 TCP、 UDP 和文件传输的支持&#xff0c;作为一个异步 NIO 框架&#xff0c; Netty 的所有 IO 操作都是异步非阻塞 的&#xff0c; 通过 Future-Listener 机制…

ssrf漏洞之——漏洞复现

漏洞介绍 SSRF漏洞&#xff1a;SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由恶意访问者构造url&#xff0c;由服务端对此url发起请求的一个安全漏洞。 漏洞原理 SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能&#xff0c;并且没有对目…

Autosar(Davinci) --- 创建一个Implementation Data Types

前言 这里我们讲一下如何创建一个Implementation Data Types&#xff08;IDT) 一、什么是IDT 二、如何创建一个IDT 鼠标右键【Implementation Data Types】,选择【new Type Reference...】 起一个名字【IdtDoorState】&#xff0c;Data Types选择【boolean】&#xff0c;这里…

RFID光触发标签应用于制造业供应链管理的应用与探索

制造业作为国民经济的支柱产业&#xff0c;其供应链管理的复杂性和重要性日益凸显&#xff0c;在全球化竞争的背景下&#xff0c;企业需要更高效、更精准、更智能的供应链解决方案来满足市场需求&#xff0c;提高客户满意度&#xff0c;降低运营成本&#xff0c;RFID光触发标签…

【mysql】mysql的卸载和安装

mysql的卸载 mysql是否安装&#xff1a; 首先我们先来看看mysql是否安装&#xff1a; 快捷键winR输入cmd&#xff0c;进入命令输入框 输入mysql --version 查看mysql的版本 如果出现了mysql的版本就说明你已经安装了 系统用户root -p就是输入密码所以代码如下 mysql -ur…

AI大模型编写多线程并发框架(六十一):从零开始搭建框架

系列文章目录 文章目录 系列文章目录前言一、项目背景二、第一轮对话-让AI大模型理解我们的诉求二、第二轮对话-优化任务处理方法和结果处理方法三、参考文章 前言 在这个充满技术创新的时代&#xff0c;AI大模型正成为开发者们的新宠。它们可以帮助我们完成从简单的问答到复杂…

模拟实现STL中的unordered_map和unordered_set

目录 1.unordered_map和unordered_set简介 2.unordered_map和unordered_set设计图 3.迭代器的设计 4.哈希表的设计 5.my_unordered_map和my_unordered_set代码 1.unordered_map和unordered_set简介 unordered_map和unordered_set的使用非常类似于map和set&#xff0c;两…

【Linux】日志函数

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 文章目录 引言日志内容日志等级日志函数的编写函数原型参数说明功能描述使用场景示例代码 引言 日志在程序设计中扮演着至关重要的角色&#xff0c;它不仅是程序运行情况的记录者&#xff0c;还是问题诊断、性…

【机器学习】智驭未来:机器学习如何重塑现代城市管理新生态

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀目录 &#x1f50d;1. 引言&#xff1a;迈向智能城市的新时代&#x1f4d2;2. 智驭交通&#xff1a;机器学习在智能交通管理中的应用&#x1…

仿Muduo库实现高并发服务器——LoopThreadPool模块

这个模块需要具备那些基础知识。 线程创建相关操作&#xff0c;锁&#xff0c;条件变量。 设置线程数量&#xff1a; _thread_count 是线程池中&#xff0c;记录线程数量的成员。 创建线程池&#xff1a; 上图就是线程池的创建&#xff0c;将线程与EventLoop对象 通过数组下…

关于嘉立创eda中同一个项目下多个原理图是否独立

嘉立创项目底下&#xff0c;如果你新建了多张原理图&#xff0c;如下 我发现&#xff0c;多张原理图是互相连接的&#xff0c;所以命名是不能重复的 多页原理图 | 嘉立创EDA标准版用户指南https://docs.lceda.cn/cn/Schematic/Multi-Sheet/index.html 上面是嘉立创原文介绍 综…

豆瓣评分7.9!世界级讲师耗时5年整理出的Python学习手册!

Python是一门流行的开源编程语言&#xff0c;广泛用于各个领域的独立程序与脚本化应用中。它不仅免费、可移植、功能强大&#xff0c;同时相对简单&#xff0c;而且使用起来充满乐趣。从软件业界的任意一角到来的程序员&#xff0c;都会发现Python着眼于开发者的生产效率以及软…

编程仙尊——深入理解指针(2)

目录 4.const修饰指针 4.1const修饰变量 5.指针运算 5.1指针-整数 5.2指针-指针 5.3指针的关系运算 6.assert断言 4.const修饰指针 4.1const修饰变量 在编程中&#xff0c;为了防止代码在运行过程中变量的内容意外改变&#xff0c;可以使用const函数&#xff0c;对变量…

介绍python的回归模型原理知识

一.回归 1.什么是回归 回归&#xff08;Regression&#xff09;最早是英国生物统计学家高尔顿和他的学生皮尔逊在研究父母和子女的身高遗传特性时提出的。1855年&#xff0c;他们在《遗传的身高向平均数方向的回归》中这样描述“子女的身高趋向于高于父母的身高的平均值&…