FPGA实现简易的自动售货机模型

news2024/11/18 14:27:12

文章目录

  • 前言
  • 一、系统设计
    • 1、模块框图
    • 2、状态机框图
    • 3、RTL视图
  • 二、源码
    • 1.蜂鸣器驱动模块
    • 2.按键消抖模块
    • 3、PWM模块
    • 4、sale_goods模块(状态机部分)
    • 5、数码管驱动模块
    • 6、Sales(顶层模块)
  • 三、效果
  • 四、总结
  • 五、参考资料


前言

环境:
1、Quartus18.1
2、vscode
3、板子型号:EP4CE6F17C8N
要求:
自动售货机功能:
1.两个按键用于投币,1个1元,1个5角
2.一个按键用于商品选择,农夫山泉2块,干脆面1块5
3.找零
设计:
我们选择使用四个按键,分别用于投币一元、五角、商品选择、结算四个功能。用六位数码管进行展示,高两位表示投币金额,中间两位表示所选商品类型('10’表示干脆面、'01’表示矿泉水),低两位表示找零数目。交易成功蜂鸣器响起5s。


一、系统设计

1、模块框图

在这里插入图片描述

2、状态机框图

在这里插入图片描述

3、RTL视图

在这里插入图片描述

二、源码

1.蜂鸣器驱动模块

module beep_ctrl(
    input wire clk,
    input wire rst_n,
    input wire pwm,

    output wire beep
);
reg beep_r;
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        beep_r<=1'b1;
    end
    else if(pwm)begin
        beep_r<=1'b0;
    end
    else begin
        beep_r<=1'b1;
    end
end
assign beep=beep_r;
endmodule

2.按键消抖模块

module key_debounce (
    input   wire    clk     ,
    input   wire    rst_n   ,
    input   wire    [3:0] key,
      
    output  wire    [3:0] key_out
);

    localparam      MAX20       = 20'd100_0000; 
    reg [19:0]      cnt_20ms;
    reg             start   ;//稳定信号 开始
    reg [3:0]       key_r0  ;//按键信号寄存器0
    reg [3:0]       key_r1  ;//按键信号寄存器1
    wire            nedge   ;//下降沿
    reg [3:0]       key_r   ;//开启流水

//倒计时计数器20ms
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
        cnt_20ms <= 20'd0;
    end
    else if(nedge)begin
        cnt_20ms <= MAX20;
    end
    else if(start) begin
        if(cnt_20ms == 1'd1)begin
            cnt_20ms <= 20'd0;  
        end
        else begin
            cnt_20ms <= cnt_20ms - 1'd1;
        end
    end
    else begin
        cnt_20ms <= cnt_20ms;
    end
end

//下降沿检测
always @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            key_r0 <= 4'b1111;//非阻塞赋值,同时赋值
            key_r1 <= 4'b1111;
        end
        else begin
            key_r0 <= key; //打一拍,同步时钟域
            key_r1 <= key_r0; //打一拍,检测按键下降沿
        end
    end

assign nedge = (~key_r0[0] && key_r1[0]) || (~key_r0[1] && key_r1[1]) || (~key_r0[2] && key_r1[2]) || (~key_r0[3] && key_r1[3]);//检测到下降沿

//约束start信号
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
        start <= 1'b0;
    end
    else if(nedge)begin
        start <= 1'b1;
    end
    else if(cnt_20ms == 1'b1)begin
        start <= 1'b0;
    end
    else begin
        start <= start;
    end
end

//约束flag信号
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
       key_r <= 4'b0000;
    end
    else if(cnt_20ms == 1'b1)begin
       key_r <= ~key_r0;
    end
    else begin
        key_r <= 4'b0000;//修改
    end
end

assign key_out =key_r;
endmodule

3、PWM模块

module pwm (
    input wire clk,
    input wire rst_n,
    input wire flag_beep,

    output wire pwm
);
parameter  CNT_300MS= 24'd15_000_000;
parameter  NUM_NOTE =6'd34;
parameter  DO = 16'd47749,
           RE = 16'd42549,
           MI = 16'd37899,
           FA = 16'd37549,
           SO = 16'd31849,
           LA = 16'd28399,
           XI = 16'd25399;
reg [23:0]  cnt_300ms;
wire add_cnt_300ms;
wire end_cnt_300ms;

reg [5:0]   cnt_note;  
wire add_cnt_note;
wire end_cnt_note;

reg [15:0] cnt_freq;
wire add_cnt_freq;
wire end_cnt_freq;

reg [15:0] freq_data;
wire [15:0] duty_data;//占空比
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
        cnt_300ms<=24'd0;
    end
    else if(add_cnt_300ms)begin
        if(end_cnt_300ms)begin
            cnt_300ms<=24'd0;
        end
        else begin
            cnt_300ms<=cnt_300ms+1'd1;
        end
    end
    else begin
        cnt_300ms<=cnt_300ms;
    end
end
assign add_cnt_300ms=1'd1;
assign end_cnt_300ms=add_cnt_300ms&&(cnt_300ms==CNT_300MS-1'd1);
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt_note<=6'd0;
    end
    else if(add_cnt_note)begin
        if(end_cnt_note)begin
            cnt_note<=6'd0;
        end
        else begin
            cnt_note<=cnt_note+1'd1;
        end
    end
    else begin
        cnt_note<=cnt_note;
    end
end
assign add_cnt_note=end_cnt_300ms;
assign end_cnt_note=add_cnt_note&&cnt_note==NUM_NOTE-1'd1;
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt_freq<=16'd0;
    end
    else if(add_cnt_freq)begin
        if(end_cnt_freq)begin
            cnt_freq<=16'd0;
        end
        else begin
            cnt_freq<=cnt_freq+1'd1;
        end
    end
    else begin
        cnt_freq<=cnt_freq;
    end
end
assign add_cnt_freq=1'b1;
assign end_cnt_freq=add_cnt_freq&&cnt_freq==freq_data;

//音符查找表
always @(*)begin
    case (cnt_note)
        6'd0:   freq_data=DO;
        6'd1:   freq_data=RE;
        6'd2:   freq_data=MI;
        6'd3:   freq_data=DO;
        6'd4:   freq_data=DO;
        6'd5:   freq_data=RE;
        6'd6:   freq_data=MI;
        6'd7:   freq_data=DO;
        6'd8:   freq_data=MI;
        6'd9:   freq_data=FA;
        6'd10:  freq_data=SO;
        6'd11:  freq_data=MI;
        6'd12:  freq_data=FA;
        6'd13:  freq_data=SO;
        6'd14:  freq_data=SO;
        6'd15:  freq_data=LA;
        6'd16:  freq_data=SO;
        6'd17:  freq_data=FA;
        6'd18:  freq_data=MI;
        6'd19:  freq_data=DO;
        6'd20:  freq_data=SO;
        6'd21:  freq_data=LA;
        6'd22:  freq_data=SO;
        6'd23:  freq_data=FA;
        6'd24:  freq_data=MI;
        6'd25:  freq_data=DO;
        6'd26:  freq_data=RE;
        6'd27:  freq_data=SO;
        6'd28:   freq_data=DO;
        6'd29:   freq_data=DO;
        6'd30:   freq_data=RE;
        6'd31:   freq_data=SO;
        6'd32:   freq_data=DO;
        6'd33:   freq_data=DO;
        default: freq_data=DO;
    endcase
end
assign duty_data=freq_data>>1;
assign pwm = (cnt_freq>duty_data&&flag_beep==1)?1'b1:1'b0;
endmodule

4、sale_goods模块(状态机部分)

module sale_goods (
    input  wire             clk      ,
    input  wire             rst_n    ,
    input  wire  [3:0]      key_in   ,

    output wire  [11:0]     dout,
    output wire             beep  
);
//状态空间
parameter IDLE       = 3'd0,
          Half       = 3'd1,
          ONE        = 3'd2,
          ONE_Half   = 3'd3,
          TWO        = 3'd4;

parameter IDLE1       = 3'd0,
          shui       =  3'd1, 
          mian       =  3'd2;
parameter MAX1S = 26'd50_000_000;
parameter MAX_5 =3'd5;
reg [25:0] cnt_1s;
reg [2:0] cstate;//现态
reg [2:0] nstate;//次态
reg [2:0] cstate1;//现态
reg [2:0] nstate1;//次态
reg [4:0] pay_r;
reg [3:0] choose_r;
reg [2:0] pay_back;
reg beep_r;
reg beep_r1;
reg [2: 0]  cnt_5s;
//1s计数器
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt_1s <= 26'd0;
    end 
    else if(cnt_1s == MAX1S - 1'd1)begin
        cnt_1s <= 26'd0;
    end   
    else begin
        cnt_1s <= cnt_1s + 1'd1;
    end   
end 
//五秒计数器
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt_5s <= 3'd0;
    end 
    else if(cnt_5s == MAX_5 - 1'd1 && cnt_1s == MAX1S - 1'd1)begin
        cnt_5s <= 3'd0;
    end
    else if(cnt_1s == MAX1S - 1'd1&&beep_r==1)begin
        cnt_5s <= cnt_5s + 1'd1;
    end 
    else begin
        cnt_5s <= cnt_5s;
    end 
end 

//第一段
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cstate<=IDLE;
    end
    else begin
        cstate<=nstate;
    end
end
//第二段
always @(*)begin
    case(cstate)                                  //key[0]0.5元,key[1]1  ,key[2]选择 ,key[3]下单
        IDLE:   begin
                    if(key_in[0])begin
                        nstate = Half;
                    end
                    else if(key_in[1])begin
                        nstate=ONE;
                    end
                    else begin
                        nstate=cstate;
                    end
                end
        Half:    begin
                    if(key_in[0])begin
                        nstate = ONE;
                    end
                    else if(key_in[1])begin
                        nstate=ONE_Half;
                    end
                    else begin
                        nstate=cstate;
                    end
                end
        ONE:     begin
                    if(key_in[0])begin
                        nstate = ONE_Half;
                    end
                    else if(key_in[1])begin
                        nstate=TWO;
                    end
                    else begin
                        nstate=cstate;
                    end
                end
        ONE_Half:     begin
                    if(key_in[0])begin
                        nstate = TWO;
                    end
                    else if(key_in[3])begin
                        nstate =IDLE;
                    end
                    else begin
                        nstate=cstate;
                    end
                end
        TWO:    begin
                    if(key_in[3])begin
                        nstate = IDLE;
                    end
                    else begin
                        nstate=cstate;
                    end
                end
        default:   nstate = IDLE;
    endcase
end
//第三段
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        pay_r<=5'd0;
    end
    else begin
        case(cstate)
            IDLE:         pay_r <=5'd0;
            Half    :     pay_r <=5'd5;
            ONE     :     pay_r <=5'd10;
            ONE_Half:     pay_r <=5'd15;
            TWO     :     pay_r <=5'd20;
            default:      pay_r <=5'd0;
        endcase
    end
end

/*商品选择状态机*/
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cstate1<=IDLE1;
    end
    else begin
        cstate1<=nstate1;
    end
end

//第二段
always @(*)begin
    case(cstate1)                                  //00未选择,10mian,01shui
        IDLE1:   begin
                    if(key_in[2])begin
                        nstate1 = shui;
                    end
                    else begin
                        nstate1=cstate1;
                    end
                end
        shui:     begin
                    if(key_in[2])begin
                        nstate1 = mian;
                    end
                    else begin
                        nstate1=cstate1;
                    end
                end
        mian:     begin
                    if(key_in[2])begin
                        nstate1 = IDLE1;
                    end
                    else begin
                        nstate1=cstate1;
                    end
                end
        default:   nstate1 = IDLE1;
    endcase
end
//第三段
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        choose_r<=4'd0;
    end
    else begin
        case(cstate1)
           IDLE1:         choose_r <=4'd0;
           shui     :     choose_r <=4'd1;
           mian     :     choose_r <=4'd10;
           default:       choose_r <=4'd0;
        endcase
    end
end

//找零
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        pay_back <=3'd0;
        beep_r1<=0;
    end
    else if(key_in[3]&&cstate1==shui)begin
        if(pay_r>=20)begin
            pay_back<=pay_r-4'd20;
            beep_r1<=1;
        end
        else
            pay_back<=4'd33;
    end
    else if(key_in[3]&&cstate1==mian)begin
        if(pay_r>=15)begin
            pay_back<=pay_r-4'd15;
            beep_r1<=1;
        end
        else
            pay_back<=4'd33;
    end
    else begin
        beep_r1<=0;
    end
end
//五秒关蜂鸣器
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        beep_r<=1'b0;
    end
    else if(cnt_5s == MAX_5 - 1'd1 && cnt_1s == MAX1S - 1'd1)begin
        beep_r<=1'b0;
    end
    else if(beep_r1)begin
        beep_r<=1'b1;
    end
    else begin
        beep_r<=beep_r;
    end
end
assign dout={pay_r,choose_r,pay_back};
assign beep=beep_r;
endmodule

5、数码管驱动模块

module seg_driver(  //数码管驱动
    input               clk     ,
    input               rst_n   ,
    input       [14:0]  din     ,

    output reg  [5:0]   sel     , //片选
    output reg  [7:0]   dig       //段选     
);
parameter TIME_SCAN = 50_000;
    // parameter TIME_SCAN = 50_000 ; // 1MS 让片选一直扫描的移动

    parameter   ZER = 7'b100_0000,  // 0亮 1灭
                ONE = 7'b111_1001,
                TWO = 7'b010_0100,
                THR = 7'b011_0000,
                FOR = 7'b001_1001,
                FIV = 7'b001_0010,
                SIX = 7'b000_0010,
                SEV = 7'b111_1000,
                EIG = 7'b000_0000,
                NIN = 7'b001_0000;

    reg    [15:0]   cnt_scan    ; //扫描计数器
    wire            add_cnt_scan;
    wire            end_cnt_scan;

    reg    [3:0]    data        ; //寄存器 缓存数据
    reg             dot         ; //小数点

    wire   [3:0]    sec_l       ;  //秒低位
    wire   [3:0]    sec_h       ;  //秒 高位
    wire   [3:0]    min_l       ;  // 分地位
    wire   [3:0]    min_h       ;  //分高位
    wire   [3:0]    hou_l       ; 
    wire   [3:0]    hou_h       ;

    assign  sec_l = din[2:0]   % 10 ;  // 59 % 10 = 9 
    assign  sec_h = din[2:0]   / 10 ;  // 59 / 10 = 5 
    assign  min_l = din[6:3]  % 10 ;
    assign  min_h = din[6:3]  / 10 ;
    assign  hou_l = din[11:7] % 10 ;
    assign  hou_h = din[11:7] / 10 ;

    always @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            cnt_scan <= 16'b0;
        end
        else if(add_cnt_scan)begin
            if(end_cnt_scan)begin
                cnt_scan <= 16'b0;
            end
            else begin
                cnt_scan <= cnt_scan + 1'b1;
            end
        end
        else begin
            cnt_scan <= cnt_scan ;
        end
    end

    assign add_cnt_scan = 1'b1;
    assign end_cnt_scan = add_cnt_scan && cnt_scan == TIME_SCAN - 1;

    always @(posedge clk or negedge rst_n)begin   // 片选
        if(!rst_n)begin
            sel <= 6'b011_111;
        end
        else if(end_cnt_scan)begin
            sel <= {sel[0],sel[5:1]};//循环向右移动  
        end
        else begin
            sel <= sel;
        end
    end 

    always @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            data <= 3'b0;
            dot  <= 1'b1;
        end
        else begin
            case(sel)
                6'b011_111 : begin data <= sec_l; dot <= 1'b1; end
                6'b101_111 : begin data <= sec_h; dot <= 1'b0; end
                6'b110_111 : begin data <= min_l; dot <= 1'b1; end
                6'b111_011 : begin data <= min_h; dot <= 1'b1; end
                6'b111_101 : begin data <= hou_l; dot <= 1'b1; end
                6'b111_110 : begin data <= hou_h; dot <= 1'b0; end
                default : begin data <= 3'b0; dot <= 1'b1;end
            endcase
        end
    end
    
    always @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            dig <= 8'b0;
        end
        else begin
            case(data)
                0 : dig <= {dot,ZER};
                1 : dig <= {dot,ONE};
                2 : dig <= {dot,TWO};
                3 : dig <= {dot,THR};
                4 : dig <= {dot,FOR};
                5 : dig <= {dot,FIV};
                6 : dig <= {dot,SIX};
                7 : dig <= {dot,SEV};
                8 : dig <= {dot,EIG};
                9 : dig <= {dot,NIN};
                default : dig <= 8'b0;
            endcase
        end
    end
endmodule

6、Sales(顶层模块)

module Sales(
    input clk,
    input rst_n,
    input [3:0] key_in,

    output [5:0] sel,
    output [7:0] seg,
    output wire  beep
);
wire [3:0] key_in1;
wire [11:0] dout;
wire beep1;
wire pwm1;
key_debounce key_debounce_inst(
    .clk       (clk)     ,
    .rst_n     (rst_n)     ,
    .key       (key_in)     ,

    .key_out   (key_in1)
);
sale_goods sale_goods_inst(
    .clk      (clk),
    .rst_n    (rst_n),
    .key_in   (key_in1),

    .dout     (dout),
    .beep     (beep1)
);
seg_driver seg_driver_inst(  //数码管驱动
    .clk   (clk)  ,
    .rst_n (rst_n)  ,
    .din   (dout)  ,

    .sel   (sel)  , //片选
    .dig   (seg)    //段选     
);
pwm pwm_inst(
    .clk         (clk)    ,
    .rst_n       (rst_n)    ,
    .flag_beep   (beep1)    ,
    .pwm         (pwm1) 
);
beep_ctrl beep_ctrl_inst(
    .clk        (clk)    ,
    .rst_n      (rst_n)    ,
    .pwm        (pwm1)    ,

    .beep       (beep)
);
endmodule

三、效果

FPGA模拟自动售货机


四、总结

此次的售货机模型只是一个简单的模拟,将之前所学习的各个小的模块进行一个综合的运用,使得对一些基本操作:数码管驱动、按键消抖、蜂鸣器、状态机等更加熟练,理解上也更加深刻。

五、参考资料

https://blog.csdn.net/weixin_43828944/article/details/124231997?spm=1001.2014.3001.5502

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

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

相关文章

华为OD机试 JavaScript 实现【简单密码】【牛客练习题 HJ21】,附详细解题思路

一、题目描述 现在有一种密码变换算法。 九键手机键盘上的数字与字母的对应&#xff1a; 1--1&#xff0c; abc--2, def--3, ghi--4, jkl--5, mno--6, pqrs--7, tuv--8 wxyz--9, 0--0&#xff0c;把密码中出现的小写字母都变成九键键盘对应的数字&#xff0c;如&#xff1a;a …

Python实现面向对象版学员管理系统

如有错误&#xff0c;敬请谅解&#xff01; 此文章仅为本人学习笔记&#xff0c;仅供参考&#xff0c;如有冒犯&#xff0c;请联系作者删除&#xff01;&#xff01; 1.1需求分析 1.1.1使用面向对象编程思想完成学员管理系统的开发&#xff0c;具体如下&#xff1a; 系统要求…

城镇供水产销差问题分析与对策

城镇自来水与其它商品的经营活动一样存在着产销差&#xff0c;产销差的高低&#xff0c;直接影响着供水企业的经济效益。供水企业的经营活动中不单考虑企业的经济效益&#xff0c;还要考虑社会效益。产销差是客观存在的&#xff0c;造成产销差的原因是多样的&#xff0c;复杂的…

初探图神经网络——GNN

title: 图神经网络(GNN) date: tags: 随笔知识点 categories:[学习笔记] 初探图神经网络(GNN) 文章来源&#xff1a;https://distill.pub/2021/gnn-intro/ 前言&#xff1a;说一下为什么要写这篇文章&#xff0c;因为自己最近一直听说“图神经网络”&#xff0c;但是一直不了…

【LeetCode】24.两两交换链表中的节点

24.两两交换链表中的节点&#xff08;中等&#xff09; 方法一&#xff1a;递归 思路 代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), n…

聊一聊mysql的MVC

技术主题 在mysql世纪使用中&#xff0c;经常涉及到MVCC的概念&#xff08;Multi-Vsersion Concurrency Control&#xff09;&#xff0c;即多版本并发控制&#xff0c;一种并发控制方法&#xff0c;根本目的是主为了提升数据库的并发性能。 mvcc为什么产生 数据库最原生的锁…

解开索引迷局:聚簇索引与非聚簇索引的差异大揭秘!

大家好&#xff0c;我是小米&#xff01;今天我们来聊一聊数据库中的索引&#xff0c;具体地说就是聚簇索引和非聚簇索引。这两者在数据库中扮演着重要的角色&#xff0c;对于我们理解数据库的存储和查询机制非常有帮助。下面就让我来给大家详细解释一下它们的区别吧&#xff0…

为不同的调制方案设计一个单载波系统(映射器-信道-去映射器)(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

RPC介绍

RPC介绍 1 介绍1.1 概述1.2 RPC的分裂发展 2 历史发展1969年11月&#xff0c;ARPAnet 开始建立。1974年&#xff1a;Jon Postel 和 Jim White发表了RFC6741975年&#xff1a;RFC684 作为RFC 674 的注释发表&#xff0c;对RFC 674 的争议进行回复。1976年&#xff1a;RFC 707 发…

C++学习之旅 -类和对象(重点)

文章目录 封装封装的意义案例1案例2 访问权限C中class和struct的区别成员属性私有化构造函数和析构函数构造函数析构函数构造函数的分类以及调用构造&调用 拷贝构造函数调用时机深拷贝&浅拷贝初始化列表类对象作为类成员静态成员C对象模型&this指针成员变量和成员函…

Mybatis Generator源码修改

文章目录 报java.net.MalformedURLException错误解决问题原因&#xff1a;编译的时候没有把下面的dtd文件打进去解决方法 XML文件判空优化-增加空字符串修改InsertSelectiveElementGenerator修改UpdateByPrimaryKeySelectiveElementGenerator XML文件判空优化-最佳解决方案 报j…

一文详解!接口测试 API 自动化测试框架

目录 前言 框架定位 框架架构图 框架介绍 技术栈 Case 展示 执行展示 框架优势&#xff1a; 前言 接口测试 API 自动化测试框架可以提高测试效率和自动化程度&#xff0c;通常包括 HTTP 客户端、测试数据管理、测试报告生成、测试用例管理和调度等功能。下面是一个常用…

【论文】attention is all you need

重点在第三节 attention is all you need摘要1. 绪论2. 背景3. 模型架构3.1 编码器和解码器堆叠 3.2 注意力3.2.1 缩放点积注意力&#xff08;Scaled Dot-Product Attention&#xff09;3.2.2 多头注意力机制3.2.3 模型中注意力的应用 3.3 职位感知前馈网络&#xff08;Positio…

单链表OJ题:LeetCode--142.环形链表Ⅱ(判断第一次入环的节点)

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家解读一下LeetCode中第142道单链表OJ题&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; 数据结构与算法专栏&#xff1a;数据结构与算法 个 人…

【网页设计】第 1 课 - 了解网页设计

欢迎来到博主 Apeiron 的博客&#xff0c;祝您旅程愉快 &#xff01; 时止则止&#xff0c;时行则行。动静不失其时&#xff0c;其道光明。 目录 1、缘起 2、了解网页设计 2.1、网页设计 2.2、网站结构 2.3、网站分类 2.4、页面鉴赏 3、总结 1、缘起 前段时间学习完了前…

OpenCV 图像与视频的基础操作

文章目录 引言创建和显示窗口如何通过 OpenCV 加载图片问题加载图片存在的问题如何通过 openCV 保存图片&#xff08;保存图片&#xff09;如何通过 OpenCV 保存图片如何利用 OpenCV 从摄像头采集视频&#xff08;读取视频文件&#xff09;如何从多媒体文件中读取视频帧&#x…

52、基于51单片机脉搏心率报警LCD 1602显示系统设计(程序+原理图+PCB图+Proteus仿真+参考论文+开题报告+任务书+外文文献+元器件清单等)

摘 要 脉搏心率测量仪在我们的日常生活中已经得到了非常广泛的应用,通过观测脉搏信号&#xff0c;可以对人体的健康进行检查&#xff0c;通常被用于保健中心和医院。为了提高脉搏测量仪的简便性和精确度&#xff0c;本课题设计了一种基于51单片机的脉搏测量仪。系统以51单片机…

C++设计模式 - 创建型模式之工厂模式

文章目录 C设计模式 - 创建型模式之工厂模式接口和针对接口编程 1. 简单工厂模式适用场合UML代码示例 2. 工厂方法模式适用场合UML代码示例 3. 抽象工厂模式适用场合UML代码示例 总结 C设计模式 - 创建型模式之工厂模式 工厂模式属于创建型模式&#xff0c;大致可以分为三类&a…

【Linux】信号量(基于环形队列的生产消费模型)

文章目录 POSIX信号量一、什么是信号量二、信号量接口1.初始化信号量2.销毁信号量3.申请信号量&#xff08;等待信号量&#xff09;4.释放信号量&#xff08;发布信号量&#xff09; 基于环形队列的生产消费模型一、结构介绍二、理论讲解三、代码实现 总结 POSIX信号量 POSIX信…

C语言之操作符详解

本章重点 1. 各种操作符的介绍 2. 表达式求值 给大家提到一些操作符&#xff0c;下面我们来给大家详细介绍 首先看算术操作符&#xff0c;其他几个都没什么可讲的我们来重点看一下/&#xff08;除法&#xff09; 整数除法&#xff08;除号的两端都是整数&#xff09; 浮点…