verilog练习:i2c slave 模块设计

news2025/2/12 14:28:14

文章目录

  • 前言
  • 1.结构
  • 2.代码
    • 2.1 iic_slave.v
    • 2.2 sync.v
    • 2.3 wr_fsm.v
      • 2.3.1 状态机状态解释
    • 2.4 ram.v
  • 3. 波形展示
  • 4. 建议
  • 5. 资料总结


前言

首先就不啰嗦iic协议了,网上有不少资料都是叙述此协议的。

下面将是我本次设计的一些局部设计汇总,如果对读者有借鉴意义那最好,如果没有的话也无所谓,互相交流而已。(这是我早期的版本,注释比较少,代码编写比较混乱,读者自便)

希望读者发现问题可在下方留言,我会及时回答或者修改。


1.结构

顶层结构图在这里插入图片描述
master结构图
在这里插入图片描述
slave结构图
在这里插入图片描述

2.代码

2.1 iic_slave.v

`timescale 1ns/1ps

module iic_slave (
    input rstn,
    input clk,
    input scl,
    inout sda,
    input [7:0] q,  // RAM data to slave
    output wen,
    output [7:0] d, // Slave data to RAM
    output [7:0] a  // Slave address to RAM
);

// Internal signals
wire sync_scl_1;
wire sync_sda_1;
wire sda_posedge;
wire sda_negedge;
wire scl_posedge;
wire scl_negedge;
wire sda_out;
wire sda_oen;

// Three-state gate for SDA
assign sda = (sda_oen) ? sda_out : 1'bz;

// Instantiate sync module
sync sync (
    .clk(clk),
    .rstn(rstn),
    .scl(scl),
    .sda(sda),
    .sync_scl_1(sync_scl_1),
    .sync_sda_1(sync_sda_1),
    .sda_posedge(sda_posedge),
    .sda_negedge(sda_negedge),
    .scl_posedge(scl_posedge),
    .scl_negedge(scl_negedge)
);

// Instantiate RAM module
ram ram (
    .clk(clk),
    .rstn(rstn),
    .d(d),
    .a(a),
    .q(q),
    .wen(wen)
);

// Instantiate write FSM module
wr_fsm wr_fsm (
    .clk(clk),
    .rstn(rstn),
    .sync_scl_1(sync_scl_1),
    .sync_sda_1(sync_sda_1),
    .scl_posedge(scl_posedge),
    .scl_negedge(scl_negedge),
    .sda_posedge(sda_posedge),
    .sda_negedge(sda_negedge),
    .d(d),
    .a(a),
    .q(q),
    .wen(wen),
    .sda_out(sda_out),
    .sda_oen(sda_oen)
);

endmodule

2.2 sync.v

`timescale 1ns/1ps
module sync (
    rstn,
    clk,
    scl,
    sda,
    sync_scl_1,
    sync_sda_1,
    sda_posedge,
    sda_negedge,
    scl_posedge,
    scl_negedge
);

    input rstn;
    input clk;
    input scl;
    input sda;

    output sync_scl_1;
    output sync_sda_1;
    output sda_posedge;
    output sda_negedge;
    output scl_posedge;
    output scl_negedge;

    reg sync_scl_1;
    reg sync_sda_1;
    reg sync_scl_0;
    reg sync_sda_0;

    always @(posedge clk or negedge rstn) begin
        if (!rstn) begin
            sync_scl_1 <= 1'b0;
            sync_sda_1 <= 1'b0;
            sync_scl_0 <= 1'b0;
            sync_sda_0 <= 1'b0;
        end else begin
            sync_scl_0 <= scl;
            sync_sda_0 <= sda;
            sync_scl_1 <= sync_scl_0;
            sync_sda_1 <= sync_sda_0;
        end
    end

    assign sda_posedge = (sync_sda_0) & (~sync_sda_1);
    assign sda_negedge = (~sync_sda_0) & (sync_sda_1);
    assign scl_posedge = (sync_scl_0) & (~sync_scl_1);
    assign scl_negedge = (~sync_scl_0) & (sync_scl_1);

endmodule

2.3 wr_fsm.v

`timescale 1ns/1ps
module wr_fsm (
    rstn,
    clk,
    sync_scl_1,
    sync_sda_1,
    scl_posedge,
    scl_negedge,
    sda_posedge,
    sda_negedge,
    q,
    d,
    a,
    wen,
    sda_out,
    sda_oen
);

    input rstn, clk;
    input sync_scl_1;
    input sync_sda_1;
    input scl_posedge;
    input scl_negedge;
    input sda_posedge;
    input sda_negedge;
    input [7:0] q;
    output [7:0] d;
    output [7:0] a;
    output wen;
    output sda_out;
    output sda_oen;

    reg wen; // write and read flags reg
    reg [7:0] scl_cnt; // clk delay counter
    reg [3:0] bit_cnt; // valid transfer byte
    reg [7:0] a; // a = save word addr, shift data to ram
    reg sda_out; // data out reg
    reg sda_oen; // three state gate flag bit
    reg [7:0] save_ctrl; // store ctrl word
    reg [7:0] save_q_data; // store data of q
    wire [7:0] q;

    parameter slave_addr = 7'b1101101; // parameter slave addr
    parameter scl_cnt_max = 60-1;

    reg [3:0] state; // state transform
    parameter idle       = 4'd0,
              w_start   = 4'd1,
              w_ctrl    = 4'd2,
              ack1      = 4'd3,
              w_addr    = 4'd4,
              ack2      = 4'd5,
              w_data    = 4'd6,
              ack3      = 4'd7,
              r_start   = 4'd8,
              r_ctrl    = 4'd9,
              ack4      = 4'd10,
              r_data    = 4'd11,
              ack5      = 4'd12,
              stop      = 4'd13;

    always @(posedge clk or negedge rstn)
    begin
        if (!rstn) begin
            state <= idle;
            sda_oen <= 1'b0;
            sda_out <= 1'b1;
            scl_cnt <= 8'b0;
            bit_cnt <= 4'b0;
            sda_out <= 1'b0;
        end else begin
            case (state)
                idle: begin
                    // Initialize state and signals
                    state <= w_start;
                    sda_oen <= 1'b0;
                    sda_out <= 1'b1;
                    scl_cnt <= 8'b0;
                    bit_cnt <= 4'b0;
                    sda_out <= 1'b0;
                end

                w_start: begin
                    // Wait for start condition
                    if (sync_scl_1 && sda_negedge)
                        begin
                            state <= w_ctrl;
                            bit_cnt <= 4'd8;
                        end
                    else
                        state <= w_start;
                end

                w_ctrl: begin
                    // Control word transfer
                    if (scl_negedge)
                        begin
                            save_ctrl <= {save_ctrl[6:0], sync_sda_1};
                            bit_cnt <= bit_cnt - 1;
                            if (bit_cnt == 4'd0)
                                begin
                                    state <= ack1;
                                    bit_cnt <= 4'd8;
                                end
                            else
                                state <= w_ctrl;
                        end
                    else
                        state <= w_ctrl;
                end

                ack1: begin
                    // Acknowledge control word
                    if (save_ctrl[7:1] == slave_addr)
                        begin
                            scl_cnt <= scl_cnt + 8'b1;
                            if (scl_cnt == scl_cnt_max >> 2)
                                begin
                                    sda_out <= 0;
                                    sda_oen <= 1;
                                    state <= ack1;
                                end
                            else if (scl_cnt == (scl_cnt_max >> 2) + scl_cnt_max)
                                begin
                                    state <= w_addr;
                                    sda_oen <= 0;
                                    scl_cnt <= 8'b0;
                                    bit_cnt <= 4'd7;
                                end
                            else
                                state <= ack1;
                        end
                    else
                        state <= stop;
                end

                w_addr: begin
                    // Write address
                    if (scl_negedge)
                        begin
                            bit_cnt <= bit_cnt - 4'b1;
                            wen <= save_ctrl[0]; // write operation
                            a <= {a[6:0], sync_sda_1};
                            if (bit_cnt == 4'd0)
                                begin
                                    bit_cnt <= 4'd7;
                                    state <= ack2;
                                end
                            else
                                state <= w_addr;
                        end
                    else
                        state <= w_addr;
                end

                ack2: begin
                    // Acknowledge address
                    scl_cnt <= scl_cnt + 8'b1;
                    if (scl_cnt == scl_cnt_max >> 2)
                        begin
                            sda_out <= 1'b0;
                            sda_oen <= 1'b1;
                            state <= ack2;
                        end
                    else if (scl_cnt == (scl_cnt_max >> 2) + scl_cnt_max)
                        begin
                            sda_oen <= 1'b0;
                            scl_cnt <= 8'b0;
                            if (wen == 0) // decide write or read
                                state <= w_data;
                            else
                                state <= r_start;
                        end
                    else
                        state <= ack2;
                end

                w_data: begin
                    // Write data
                    if (scl_negedge)
                        begin
                            d <= {d[6:0], sync_sda_1};
                            bit_cnt <= bit_cnt - 4'b1;
                            if (bit_cnt == 4'd0)
                                begin
                                    bit_cnt <= 4'd7;
                                    state <= ack3;
                                end
                            else
                                state <= w_data;
                        end
                    else
                        state <= w_data;
                end

                ack3: begin
                    // Acknowledge data
                    scl_cnt <= scl_cnt + 8'b1;
                    if (scl_cnt == scl_cnt_max >> 2)
                        begin
                            sda_out <= 0;
                            sda_oen <= 1'b1;
                            state <= ack3;
                        end
                    else if (scl_cnt == (scl_cnt_max >> 2) + scl_cnt_max)
                        begin
                            sda_oen <= 1'b0;
                            scl_cnt <= 8'b0;
                            state <= stop;
                        end
                    else
                        state <= ack3;
                end

                r_start: begin
                    // Read start condition
                    if (sync_scl_1 && sda_negedge)
                        begin
                            sda_oen <= 1'b0;
                            bit_cnt <= 4'd8;
                            state <= r_ctrl;
                        end
                    else
                        state <= r_start;
                end

                r_ctrl: begin
                    // Read control word
                    if (scl_negedge)
                        begin
                            bit_cnt <= bit_cnt - 4'b1;
                            save_ctrl <= {save_ctrl[6:0], sync_sda_1};
                            if (bit_cnt == 4'd0)
                                begin
                                    wen <= save_ctrl[0];
                                    bit_cnt <= 4'd7;
                                    state <= ack4;
                                end
                            else
                                state <= r_ctrl;
                        end
                    else
                        state <= r_ctrl;
                end

                ack4: begin
                    // Acknowledge control word
                    if (save_ctrl[7:1] == slave_addr)
                        begin
                            scl_cnt <= scl_cnt + 8'b1;
                            if (scl_cnt == scl_cnt_max >> 2)
                                begin
                                    sda_out <= 0;
                                    sda_oen <= 1;
                                    state <= ack4;
                                end
                            else if (scl_cnt == (scl_cnt_max >> 2) + scl_cnt_max)
                                begin
                                    sda_oen <= 1'b0;
                                    scl_cnt <= 8'b0;
                                    if (wen)
                                        begin
                                            state <= r_data;
                                            sda_oen <= 1'b1;
                                            sda_out <= sync_sda_1;
                                        end
                                    else
                                        state <= w_data;
                                end
                            else
                                state <= ack4;
                        end
                    else
                        state <= stop;
                end

                r_data: begin
                    // Read data
                    if (scl_negedge)
                        begin
                            save_q_data <= q[7:0];
                            bit_cnt <= bit_cnt - 4'b1;
                            sda_out <= save_q_data[7];
                            if (bit_cnt == 4'd0)
                                begin
                                    state <= ack5;
                                    bit_cnt <= 4'd7;
                                    sda_oen <= 0;
                                end
                            else
                                begin
                                    state <= r_data;
                                    sda_oen <= 1;
                                    save_q_data <= {save_q_data[6:0], 1'b0};
                                end
                        end
                    else
                        state <= r_data;
                end

                ack5: begin
                    // Acknowledge data
                    if (scl_posedge)
                        begin
                            if (sync_sda_1 == 1)
                                state <= stop;
                            else
                                state <= idle;
                        end
                    else
                        state <= ack5;
                end

                stop: begin
                    // Stop condition
                    if (sync_scl_1 && sda_posedge)
                        begin
                            state <= idle;
                            sda_oen <= 1'b0;
                            sda_out <= 1'b1;
                        end
                    else
                        state <= stop;
                end

                default: state <= idle;
            endcase
        end
    end
endmodule


2.3.1 状态机状态解释

以下是代码中每个状态的作用解释:

reg [3:0] state; // state transform
parameter idle       = 4'd0,
          w_start   = 4'd1,
          w_ctrl    = 4'd2,
          ack1      = 4'd3,
          w_addr    = 4'd4,
          ack2      = 4'd5,
          w_data    = 4'd6,
          ack3      = 4'd7,
          r_start   = 4'd8,
          r_ctrl    = 4'd9,
          ack4      = 4'd10,
          r_data    = 4'd11,
          ack5      = 4'd12,
          stop      = 4'd13;

状态作用解释

  1. idle (4’d0):
  • 作用: 初始状态,等待复位信号或起始条件。
  • 描述: 在这个状态下,所有信号被初始化,状态机等待复位信号 rstn 或起始条件(sync_scl_1 和 sda_negedge)。
  1. w_start (4’d1):
  • 作用: 等待起始条件。
  • 描述: 在这个状态下,状态机检测起始条件(sync_scl_1 和 sda_negedge)。如果检测到起始条件,状态机进入 w_ctrl 状态。
  1. w_ctrl (4’d2):
  • 作用: 接收控制字。
  • 描述: 在这个状态下,状态机接收控制字(save_ctrl),并将其存储在寄存器中。控制字的接收通过 scl_negedge 信号完成。当接收到完整的控制字后,状态机进入 ack1 状态。
  1. ack1 (4’d3):
  • 作用: 发送 ACK 信号。
  • 描述: 在这个状态下,状态机发送 ACK 信号(sda_out 和 sda_oen)。如果接收到的控制字匹配从设备地址(slave_addr),状态机进入 w_addr 状态。否则,状态机进入 stop 状态。
  1. w_addr (4’d4):
  • 作用: 接收地址。
  • 描述: 在这个状态下,状态机接收地址数据(a),并将其存储在寄存器中。地址的接收通过 scl_negedge 信号完成。当接收到完整的地址后,状态机进入 ack2 状态。
  1. ack2 (4’d5):
  • 作用: 发送 ACK 信号。
  • 描述: 在这个状态下,状态机发送 ACK 信号(sda_out 和 sda_oen)。根据控制字中的写入标志(wen),状态机决定进入 w_data 状态(写入数据)或 r_start 状态(读取数据)。
  1. w_data (4’d6):
  • 作用: 写入数据。
  • 描述: 在这个状态下,状态机接收数据(d),并将其存储在寄存器中。数据的接收通过 scl_negedge 信号完成。当接收到完整的数据后,状态机进入 ack3 状态。
  1. ack3 (4’d7):
  • 作用: 发送 ACK 信号。
  • 描述: 在这个状态下,状态机发送 ACK 信号(sda_out 和 sda_oen)。然后状态机进入 stop 状态。
  1. r_start (4’d8):
  • 作用: 等待读取起始条件。
  • 描述: 在这个状态下,状态机检测读取起始条件(sync_scl_1 和 sda_negedge)。如果检测到起始条件,状态机进入 r_ctrl 状态。
  1. r_ctrl (4’d9):
  • 作用: 接收控制字。
  • 描述: 在这个状态下,状态机接收控制字(save_ctrl),并将其存储在寄存器中。控制字的接收通过 scl_negedge 信号完成。当接收到完整的控制字后,状态机进入 ack4 状态。
  1. ack4 (4’d10):
  • 作用: 发送 ACK 信号。
  • 描述: 在这个状态下,状态机发送 ACK 信号(sda_out 和 sda_oen)。如果接收到的控制字匹配从设备地址(slave_addr),状态机进入 r_data 状态。否则,状态机进入 stop 状态。
  1. r_data (4’d11):
  • 作用: 读取数据。
  • 描述: 在这个状态下,状态机读取数据(q),并将其存储在寄存器中。数据的读取通过 scl_negedge 信号完成。当读取完数据后,状态机进入 ack5 状态。
    13。 ack5 (4’d12):
  • 作用: 发送 ACK 信号。
  • 描述: 在这个状态下,状态机发送 ACK 信号(sda_out 和 sda_oen)。然后状态机进入 idle 状态。
  1. stop (4’d13):
  • 作用: 停止状态。
  • 描述: 在这个状态下,状态机等待停止条件(sync_scl_1 和 sda_posedge)。如果检测到停止条件,状态机进入 idle 状态。

每个状态的作用如下:

  • idle: 初始状态,等待复位或起始条件。
  • w_start: 等待起始条件。
  • w_ctrl: 接收控制字。
  • ack1: 发送 ACK 信号,确认控制字接收。
  • w_addr: 接收地址。
  • ack2: 发送 ACK 信号,确认地址接收。
  • w_data: 写入数据。
  • ack3: 发送 ACK 信号,确认数据写入。
  • r_start: 等待读取起始条件。
  • r_ctrl: 接收控制字。
  • ack4: 发送 ACK 信号,确认控制字接收。
  • r_data: 读取数据。
  • ack5: 发送 ACK 信号,确认数据读取。
  • stop: 停止状态,等待停止条件。

这些状态共同构成了一个完整的 I2C 从设备写入和读取的有限状态机,确保数据的正确传输和接收。

2.4 ram.v

`timescale 1ns/1ps
module ram (
    clk,
    rstn,
    d,
    a,
    q,
    wen
);

    // Input ports
    input clk, rstn;
    input [7:0] a;  // Address input
    input [7:0] d;  // Data input
    input wen;      // Write enable

    // Output ports
    output [7:0] q; // Data output

    // Internal registers
    reg [7:0] ram [255:0]; // RAM array
    integer i;             // Loop counter
    reg [7:0] q;           // Output data register

    // Always block for RAM operations
    always @(posedge clk or negedge rstn)
    begin
        if (!rstn) begin
            // Initialize RAM on reset
            for (i = 0; i <= 255; i = i + 1)
                ram[i] <= 8'b0;
        end else begin
            if (!wen) begin
                // Write operation: wen = 0
                ram[a] <= d;
            end else begin
                // Read operation: wen = 1
                q <= ram[a];
            end
        end
    end

endmodule


3. 波形展示

在这里插入图片描述

4. 建议

必看
此设计还存在一些问题,后续有时间我会完善的。

在同步的时候我建议还是使用两个寄存器缓冲,而不是使用一个,使用多个更加的稳妥一些,我这个就是使用了较少的寄存器缓冲,所以波形中有问题。(我把这段字打个红色背景)。(是因为在边沿检测的时候无法确认信号是否同步还是异步所以在设计的时候还是使用双寄存器进行消除亚稳态)

5. 资料总结

练习时的一些思路。

https://blog.csdn.net/weixin_46163885/article/details/107170689

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

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

相关文章

项目6:基于大数据校园一卡通数据分析和可视化

1、项目简介 本项目是基于大数据的清华校园卡数据分析系统&#xff0c;通过Hadoop&#xff0c;spark等技术处理校园卡交易、卡号和商户信息数据。系统实现消费类别、男女消费差异、学院消费排行和年级对比等分析&#xff0c;并通过Web后端和可视化前端展示结果。项目运行便捷&…

Datawhale 组队学习 Ollama教程 task1

一、Ollama 简介 比喻&#xff1a;Ollama 就像是一个“魔法箱子”&#xff0c;里面装满了各种大型语言模型&#xff08;LLM&#xff09;。你不需要懂复杂的魔法咒语&#xff08;配置&#xff09;&#xff0c;只需要轻轻一按&#xff08;一条命令&#xff09;&#xff0c;就能让…

大模型基本原理(二)——ChatGPT的工作原理

如何得到一个ChatGPT&#xff1f; 1、无监督预训练&#xff1a;通过大量的文本数据集进行无监督训练&#xff0c;得到一个基座模型&#xff08;只会续写文本&#xff09; 2、监督微调&#xff1a;通过一些人类撰写的高质量对话数据对基座模型进行监督微调&#xff0c;得到一个…

成为高能量体质:从身体神庙到精神圣殿的修炼之路

清晨五点&#xff0c;当城市还在沉睡&#xff0c;瑜伽垫上的汗水已经折射出第一缕阳光。这不是苦行僧的自虐&#xff0c;而是高能量体质者的日常仪式。在这个能量稀缺的时代&#xff0c;如何把自己修炼成一座小型核电站&#xff1f;答案就藏在身体的每个细胞里。 一、能量管理…

51c自动驾驶~合集50

我自己的原文哦~ https://blog.51cto.com/whaosoft/13280022 #VLA 主流方案全解析 旨在让智能体在物理世界中通过感知、决策和行动来实现目标&#xff0c;而视觉 - 语言 - 动作&#xff08;VLA&#xff09;模型作为其中的关键技术&#xff0c;近年来备受关注。VLA 模型能够…

论文阅读:MGMAE : Motion Guided Masking for Video Masked Autoencoding

MGMAE:Motion Guided Masking for Video Masked Autoencoding Abstract 掩蔽自编码&#xff08;Masked Autoencoding&#xff09;在自监督视频表示学习中展现了出色的表现。时间冗余导致了VideoMAE中高掩蔽比率和定制的掩蔽策略。本文旨在通过引入运动引导掩蔽策略&#xff0…

【嵌入式Linux应用开发基础】文件I/O基础编程

目录 一、文件I/O简介 二、文件描述符 2.1. 唯一性 2.2. 抽象性 2.3. 有限性 三、文件操作函数 四、标准文件I/O函数 五、文件执行权限 5.1. 权限类型 5.2. 权限分配对象 5.3. 权限表示方法 5.4. 权限设置命令 5.5. 权限设置的重要性 5.6. 实例说明 六、设备文件…

【JS】实现一个hexo插件并发布

hexo插件生成 在你的 hexo blog 目录&#xff0c;找到 node_modules. 新建一个文件夹。然后执行 npm init npm 会引导你生成 package.json 这是你的包的描述文件。需要注意的是&#xff0c;所有的 hexo 插件必须以 hexo - 开头&#xff0c;否则 hexo 不会加载。 如果hexo g中没…

【Java 面试 八股文】MySQL 篇

MySQL 篇 1. MySQL中&#xff0c;如何定位慢查询&#xff1f;2. 那这个SQL语句执行很慢&#xff0c;如何分析呢&#xff1f;3. 了解过索引吗&#xff1f;&#xff08;什么是索引&#xff09;4. 索引的底层数据结构了解过吗&#xff1f;5. B树和B树的区别是什么呢&#xff1f;6.…

vue中使用高德地图自定义掩膜背景结合threejs

技术架构 vue3高德地图2.0threejs 代码步骤 这里我们就用合肥市为主要的地区&#xff0c;将其他地区扣除&#xff0c;首先使用高德的webapi的DistrictSearch功能&#xff0c;使用该功能之前记得检查一下初始化的时候是否添加到plugins中&#xff0c;然后搜索合肥市的行政数据…

Python----PyQt开发(PyQt高级:图像显示,定时器,进度条)

一、图像显示 1.1、增加图标 1.直接创建setWindowIcon(QIcon(灯泡.jpg)) import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton from PyQt5.QtGui import QIconclass MainWindow(QMainWindow):def __init__(self):super(MainWindow, self).__init_…

Tomcat添加到Windows系统服务中,服务名称带空格

要将Tomcat添加到Windows系统服务中&#xff0c;可以通过Tomcat安装目录中“\bin\service.bat”来完成&#xff0c;如果目录中没有service.bat&#xff0c;则需要使用其它方法。 打到CMD命令行窗口&#xff0c;通过cd命令跳转到Tomcat安装目录的“\bin\”目录&#xff0c;然后执…

2025.2.10 每日学习记录3:技术报告只差相关工作+补实验

0.近期主任务线 1.完成小论文准备 目标是3月份完成实验点1的全部实验和论文。 2.准备教资笔试 打算留个十多天左右&#xff0c;一次性备考笔试的三个科目 1.实习申请技术准备&#xff1a;微调、Agent、RAG 据央视财经&#xff0c;数据显示&#xff0c;截至2024年12月…

微生物学术语和定义 | 微生物学词汇表

​ 微生物学作为一门研究微生物及其与环境、宿主和其他生物相互作用的科学&#xff0c;涵盖了广泛的学科领域和专业术语。然而&#xff0c;由于微生物学的快速发展和跨学科融合&#xff0c;许多术语的定义和使用在不同领域中可能存在差异甚至混淆。 随着新冠疫情的全球蔓延&am…

Java集合List详解(带脑图)

允许重复元素&#xff0c;有序。常见的实现类有 ArrayList、LinkedList、Vector。 ArrayList ArrayList 是在 Java 编程中常用的集合类之一&#xff0c;它提供了便捷的数组操作&#xff0c;并在动态性、灵活性和性能方面取得了平衡。如果需要频繁在中间插入和删除元素&#xf…

分层解耦-ioc引入

内聚: 软件中各个功能模块内部的功能联系。 耦合: 衡量软件中各个层/模块之间的依赖、关联的程度。 软件设计原则: 高内聚低耦合。

如何利用DeepSeek开源模型打造OA系统专属AI助手

利用DeepSeek开源模型打造OA系统专属AI助手&#xff0c;可以显著提升办公效率&#xff0c;增强信息检索和管理能力。 注册与登录DeepSeek平台 访问DeepSeek官网 访问DeepSeek的官方网站DeepSeek。使用电子邮件或手机号码注册账号并登录。 获取API Key 登录DeepSeek平台&am…

uni getLocation 公众号h5获取定位坐标没有返回

先看代码 //获取经纬度getLocation() {console.log("111")uni.getLocation({type: wgs84,success: function (res) {console.log(当前位置的经度&#xff1a; res.longitude);console.log(当前位置的纬度&#xff1a; res.latitude);},fail: function(err) {conso…

C语言基本概念————讨论sqrt()和pow()函数与整数的关系

本文来源&#xff1a;C语言基本概念——讨论sqrt()和pow()函数与整数的关系. C语言基本概念——sqrt和pow函数与整数的关系 1. 使用sqrt()是否可以得到完全平方数的精确的整数平方根1.1 完全平方数的计算结果是否精确&#xff1f;1.2 为什么不会出现误差&#xff08;如 1.99999…

如何本地部署DeepSeek

第一步&#xff1a;安装ollama https://ollama.com/download 打开官网&#xff0c;选择对应版本 第二步&#xff1a;选择合适的模型 https://ollama.com/ 模型名称中的 1.5B、7B、8B 等数字代表模型的参数量&#xff08;Parameters&#xff09;&#xff0c;其中 B 是英文 B…