【FPGA零基础学习之旅#11】数码管动态扫描
🎉欢迎来到FPGA专栏~数码管动态扫描
- ☆* o(≧▽≦)o *☆嗨~我是小夏与酒🍹
- ✨博客主页:小夏与酒的博客
- 🎈该系列文章专栏:FPGA学习之旅
- 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏
- 📜 欢迎大家关注! ❤️

🎉 目录-数码管动态扫描
- 一、效果演示
- 二、电路结构
- 三、代码详解
- 四、AV4开发板演示
- 五、Spirit_V2开发板演示

一、效果演示
🥝Spirit_V2开发板按键控制数码管:

🥝AV4开发板数码管动态扫描:


二、电路结构

上图电路结构的子模块介绍:
| 名称 | 功能描述 |
|---|---|
| divider | 分频产生1KHz的扫描时钟 |
| shift6 | 6位循环移位寄存器 |
| MUX6 | 数据输入选择 |
| MUX2 | 使能选择 |
| LUT | 数据译码器 |
由于各子模块的代码量不会特别大,因此将在一个文件中编写。
三、代码详解
先上代码:
smg_HEX.v:
module smg_HEX(input Clk, //50Minput Rst_n, //复位input En, //数码管显示使能input [23:0] disp_data, //6 × 4 = 24(6个数码管,数据格式为hex,总共输入24位)output reg [7:0] seg, //数码管段选output [5:0] sel //数码管位选(数码管选择)
);reg [5:0]sel_r;//--------<分频器>--------reg [14:0]divider_cnt;//25000-1reg clk_1K;reg [3:0]data_tmp;//待显示数据缓存//1KHz分频计数器always@(posedge Clk or negedge Rst_n)beginif(!Rst_n)divider_cnt <= 15'd0;else if(!En)divider_cnt <= 15'd0;else if(divider_cnt == 24999)divider_cnt <= 15'd0;elsedivider_cnt <= divider_cnt + 1'b1;end//1KHz扫描时钟always@(posedge Clk or negedge Rst_n)beginif(!Rst_n)clk_1K <= 1'b0;else if(divider_cnt == 24999)clk_1K <= ~clk_1K;elseclk_1K <= clk_1K;end//--------<6位循环移位寄存器>-------- always@(posedge clk_1K or negedge Rst_n)beginif(!Rst_n)sel_r <= 6'b000_001;else if(sel_r == 6'b100_000)sel_r <= 6'b000_001;elsesel_r <= sel_r << 1;end //--------<6选1多路器>-------- always@(*)begincase(sel_r)6'b00_0001:data_tmp = disp_data[3:0];6'b00_0010:data_tmp = disp_data[7:4];6'b00_0100:data_tmp = disp_data[11:8];6'b00_1000:data_tmp = disp_data[15:12];6'b01_0000:data_tmp = disp_data[19:16];6'b10_0000:data_tmp = disp_data[23:20];default:data_tmp = 4'b0000;endcaseend//--------<LUT>-------- always@(*)begincase(data_tmp)4'h0:seg = 8'hc0;4'h1:seg = 8'hf9;4'h2:seg = 8'ha4;4'h3:seg = 8'hb0;4'h4:seg = 8'h99;4'h5:seg = 8'h92;4'h6:seg = 8'h82;4'h7:seg = 8'hf8;4'h8:seg = 8'h80;4'h9:seg = 8'h90;4'ha:seg = 8'h88;4'hb:seg = 8'h83;4'hc:seg = 8'hc6;4'hd:seg = 8'ha1;4'he:seg = 8'h86;4'hf:seg = 8'h8e;endcaseend//--------<2选1多路器>-------- assign sel = (En)?(~sel_r):6'b111_111;endmodule
需要注意端口列表:
module smg_HEX(input Clk, //50Minput Rst_n, //复位input En, //数码管显示使能input [23:0] disp_data, //6 × 4 = 24(6个数码管,数据格式为hex,总共输入24位)output reg [7:0] seg, //数码管段选output [5:0] sel //数码管位选(数码管选择)
);
En使能信号只有在高电平时,数码管显示。加入使能信号端口是为了低功耗设计的实现。
接下来做仿真测试:
smg_HEX_tb.v:
`timescale 1ns/1ns
`define clock_period 20module smg_HEX_tb;reg Clk; //50Mreg Rst_n;reg En; //数码管显示使能reg [23:0] disp_data;wire [7:0] seg; //数码管段选wire [5:0] sel; //数码管位选(数码管选择)smg_HEX Usmg_HEX(.Clk(Clk), //50M.Rst_n(Rst_n),.En(En), //数码管显示使能.disp_data(disp_data),.seg(seg), //数码管段选.sel(sel) //数码管位选(数码管选择));initial Clk = 1;always#(`clock_period / 2) Clk =~Clk;initial beginRst_n = 1'b0;En = 1;disp_data = 24'h123456;#(`clock_period*20);Rst_n = 1'b1;#(`clock_period*20);#20000000;disp_data = 24'h89abcd;#20000000;$stop;endendmodule
仿真结果:

RTL:

四、AV4开发板演示
上述代码为数码管动态扫描的驱动代码,使用时需要添加上层模块。
AV4开发板开箱视频:【FPGA-AV4】火热售卖中!欢迎大家抢购!小月电子~(含购买链接)。
在AV4开发板上的实现,主要使用到了ISSP调试工具,ISSP的ip核创建:
🥝创建一个新的ip核:

🥝选择ISSP,选择好Verilog HDL和路径:

🥝该项目只需要用到source端口:

🥝下一步:

🥝完成:

issp.v:
// megafunction wizard: %In-System Sources and Probes%VBB%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: altsource_probe // ============================================================
// File Name: issp.v
// Megafunction Name(s):
// altsource_probe
//
// Simulation Library Files(s):
// altera_mf
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 13.0.0 Build 156 04/24/2013 SJ Full Version
// ************************************************************//Copyright (C) 1991-2013 Altera Corporation
//Your use of Altera Corporation's design tools, logic functions
//and other software and tools, and its AMPP partner logic
//functions, and any output files from any of the foregoing
//(including device programming or simulation files), and any
//associated documentation or information are expressly subject
//to the terms and conditions of the Altera Program License
//Subscription Agreement, Altera MegaCore Function License
//Agreement, or other applicable license agreement, including,
//without limitation, that your use is for the sole purpose of
//programming logic devices manufactured by Altera and sold by
//Altera or its authorized distributors. Please refer to the
//applicable agreement for further details.module issp (probe,source);input probe;output [23:0] source;endmodule// ============================================================
// CNX file retrieval info
// ============================================================
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
// Retrieval info: CONSTANT: ENABLE_METASTABILITY STRING "NO"
// Retrieval info: CONSTANT: INSTANCE_ID STRING "NONE"
// Retrieval info: CONSTANT: PROBE_WIDTH NUMERIC "0"
// Retrieval info: CONSTANT: SLD_AUTO_INSTANCE_INDEX STRING "YES"
// Retrieval info: CONSTANT: SLD_INSTANCE_INDEX NUMERIC "0"
// Retrieval info: CONSTANT: SOURCE_INITIAL_VALUE STRING " 0"
// Retrieval info: CONSTANT: SOURCE_WIDTH NUMERIC "24"
// Retrieval info: USED_PORT: probe 0 0 0 0 INPUT NODEFVAL "probe"
// Retrieval info: USED_PORT: source 0 0 24 0 OUTPUT NODEFVAL "source[23..0]"
// Retrieval info: CONNECT: @probe 0 0 0 0 probe 0 0 0 0
// Retrieval info: CONNECT: source 0 0 24 0 @source 0 0 24 0
// Retrieval info: GEN_FILE: TYPE_NORMAL issp.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL issp.inc TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL issp.cmp TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL issp.bsf TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL issp_inst.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL issp_bb.v TRUE
// Retrieval info: LIB_FILE: altera_mf
将该ip核添加到项目文件中,并在顶层文件中例化模块:
module smg_ISSP(input Clk, //50Minput Rst_n, //复位output [7:0] seg, //数码管段选output [5:0] sel //数码管位选(数码管选择)
);wire [23:0]disp_data;smg_HEX Usmg_HEX(.Clk(Clk), //50M.Rst_n(Rst_n), //复位.En(1'b1), //数码管显示使能.disp_data(disp_data), //6 × 4 = 24(6个数码管,数据格式为hex,总共输入24位).seg(seg), //数码管段选.sel(sel) //数码管位选(数码管选择));issp Uissp(.probe(),.source(disp_data));endmodule
将上述程序配置好之后,数码管显示如下:

当程序配置好之后,使用ISSP调试工具,打开步骤:
🍋在Tools中打开:

🍋未发现设备,先点击ok:

🍋在Hardware中选择对应的设备:

🍋将数据显示格式调整为hex格式:

🍋将数据改为123456:

🍋测试结果:

🍋将数据改为ABCDEF:

🍋测试结果:

五、Spirit_V2开发板演示
Spirit_V2开发板介绍:【FPGA-Spirit_V2】小精灵V2开发板初使用。
接下来在Spirit_V2开发板上实验,通过按键控制数码管亮灭,实现简单的低功耗设计:

先上RTL视图,便于理解编程思路:

按键信号经过按键消抖模块之后,有效信号进入数码管数据和使能模块,最后信号进入数码管驱动模块。
按键消抖模块的详细讲解:【FPGA零基础学习之旅#10】按键消抖模块设计与验证(一段式状态机实现)。
接下来为各模块的代码:
KeyFilter.v:
//
//模块:按键消抖模块
//key_state:输出消抖之后按键的状态
//key_flag:按键消抖结束时产生一个时钟周期的高电平脉冲
//
module KeyFilter(input Clk,input Rst_n,input key_in,output reg key_flag,output reg key_state
);//按键的四个状态localparamIDLE = 4'b0001,FILTER1 = 4'b0010,DOWN = 4'b0100,FILTER2 = 4'b1000;//状态寄存器reg [3:0] curr_st;//边沿检测输出上升沿或下降沿wire pedge;wire nedge;//计数寄存器reg [19:0]cnt;//使能计数寄存器reg en_cnt;//计数满标志信号reg cnt_full;//计数满寄存器//------<边沿检测电路的实现>------//边沿检测电路寄存器reg key_tmp0;reg key_tmp1;//边沿检测always@(posedge Clk or negedge Rst_n)beginif(!Rst_n)beginkey_tmp0 <= 1'b0;key_tmp1 <= 1'b0;endelse beginkey_tmp0 <= key_in;key_tmp1 <= key_tmp0;end endassign nedge = (!key_tmp0) & (key_tmp1);assign pedge = (key_tmp0) & (!key_tmp1);//------<状态机主程序>------ //状态机主程序always@(posedge Clk or negedge Rst_n)beginif(!Rst_n)begincurr_st <= IDLE;en_cnt <= 1'b0;key_flag <= 1'b0;key_state <= 1'b1;endelse begincase(curr_st)IDLE:beginkey_flag <= 1'b0;if(nedge)begincurr_st <= FILTER1;en_cnt <= 1'b1;endelsecurr_st <= IDLE;endFILTER1:beginif(cnt_full)beginkey_flag <= 1'b1;key_state <= 1'b0;curr_st <= DOWN;en_cnt <= 1'b0;end else if(pedge)begincurr_st <= IDLE;en_cnt <= 1'b0;endelsecurr_st <= FILTER1;endDOWN:beginkey_flag <= 1'b0;if(pedge)begincurr_st <= FILTER2;en_cnt <= 1'b1;endelsecurr_st <= DOWN;endFILTER2:beginif(cnt_full)beginkey_flag <= 1'b1;key_state <= 1'b1;curr_st <= IDLE;en_cnt <= 1'b0;end else if(nedge)begincurr_st <= DOWN;en_cnt <= 1'b0;endelsecurr_st <= FILTER2;enddefault:begincurr_st <= IDLE;en_cnt <= 1'b0;key_flag <= 1'b0;key_state <= 1'b1;endendcaseendend//------<20ms计数器>------ //20ms计数器//Clk 50_000_000Hz//一个时钟周期为20ns//需要计数20_000_000 / 20 = 1_000_000次always@(posedge Clk or negedge Rst_n)beginif(!Rst_n)cnt <= 20'd0;else if(en_cnt)cnt <= cnt + 1'b1;elsecnt <= 20'd0;endalways@(posedge Clk or negedge Rst_n)beginif(!Rst_n)cnt_full <= 1'b0;else if(cnt == 999_999)cnt_full <= 1'b1;elsecnt_full <= 1'b0;endendmodule
DataAndEn.v:
module DataAndEn(input Clk,input Rst_n,input key_flag,input key_state,output reg [23:0] disp_data,output reg En
);always@(posedge Clk or negedge Rst_n)beginif(!Rst_n)En <= 1'b0;else if(key_state == 1'b0)En <= 1'b1;else En <= 1'b0;endalways@(posedge Clk or negedge Rst_n)beginif(!Rst_n)disp_data <= 24'h0;else if(!key_state)disp_data <= 24'h89abcd;else;endendmodule
数码管驱动模块的代码保持不变,接下来为顶层模块:
smg_top.v:
module smg_top(input Clk, input Rst_n, input key_in, output [7:0] seg, output [5:0] sel
);wire key_flag;wire key_state;wire En;wire [23:0] disp_data;KeyFilter UKeyFilter(.Clk(Clk),.Rst_n(Rst_n),.key_in(key_in),.key_flag(key_flag),.key_state(key_state));DataAndEn UDataAndEn(.Clk(Clk),.Rst_n(Rst_n),.key_flag(key_flag),.key_state(key_state),.disp_data(disp_data),.En(En));smg_HEX Usmg_HEX(.Clk(Clk), .Rst_n(Rst_n), .En(En), .disp_data(disp_data),.seg(seg), .sel(sel) );endmodule

🧸结尾
- ❤️ 感谢您的支持和鼓励! 😊🙏
- 📜您可能感兴趣的内容:
- 【FPGA】串口通信讲解-状态机判断数据值
- 【Python】串口通信-与FPGA、蓝牙模块实现串口通信(Python+FPGA)
- 【Arduino TinyGo】【最新】使用Go语言编写Arduino-环境搭建和点亮LED灯
- 【全网首发开源教程】【Labview机器人仿真与控制】Labview与Solidworks多路支配关系-四足爬行机器人仿真与控制
相关文章:
【FPGA零基础学习之旅#11】数码管动态扫描
🎉欢迎来到FPGA专栏~数码管动态扫描 ☆* o(≧▽≦)o *☆嗨~我是小夏与酒🍹 ✨博客主页:小夏与酒的博客 🎈该系列文章专栏:FPGA学习之旅 文章作者技术和水平有限,如果文中出现错误,希望大家能指正…...
JavaExcel:自动生成数据表并插入数据
故事背景 出于好奇,当下扫描excel读取数据进数据库 or 导出数据库数据组成excel的功能层出不穷,代码也是前篇一律,poi或者easy excel两种SDK的二次利用带来了各种封装方法。 那么为何不能直接扫描excel后根据列的属性名与行数据的属性建立S…...
哪吒汽车“三头六臂”之「浩智电驱」
撰文 / 翟悦 编审 / 吴晰 8月21日,在哪吒汽车科技日上,哪吒汽车发布“浩智战略2025”以及浩智技术品牌2.0。根据公开信息,主编梳理了以下几点:◎浩智滑板底盘支持400V/800V双平台◎浩智电驱包括180kW 400V电驱系统和250kW 800…...
补码的反码加1为什么是原码?
搞了半个小时,终于弄懂了。 168421原码10011反码01100补码01101 学到这里了,我们肯定知道,原码补码 0,在这里也就是 19 13 32,溢出来的一位正好舍去了; 所以说,对啊,只要保证…...
光刻机是怎么做出来的
文章目录 一、光刻机的基本原理二、光刻机的制造过程三、光刻机的制造要求四、光刻机的发展趋势 光刻机是半导体工艺制造中非常重要的设备之一,它是用来制作微细结构的关键工具之一。相信大家都知道,半导体工艺中最小的制造单位是晶体管,而制…...
CocosCreator3.8研究笔记(二)windows环境 VS Code 编辑器的配置
一、设置文件显示和搜索过滤步骤 为了提高搜索效率以及文件列表中隐藏不需要显示的文件, VS Code 需要设置排除目录用于过滤。 比如 cocoscreator 中,编辑器运行时会自动生成一些目录:build、temp、library, 所以应该在搜索中排除…...
Rust--流程控制
循环/判断 ref: 流程控制 - Rust语言圣经(Rust Course) 判断 if condition true {// A... } else {// B... }if 语句块是表达式,所以可以为变量赋值,当然要注意的是保证返回的类型相同: fn main() {let condition true;let number if c…...
mate60的麒麟9000s和麒麟9000是一款CPU吗
答案:不是 论证: 1.在核心方便9000是1个高频A77,3个低频A77,4个A55组成的。9000S是2个高频A34核心,6个定制A78AE核心和4个A510核心并搭载超线程技术(详见新华网新华网地址) 2.GPU截然不同&am…...
查漏补缺 - JS三 WebAPI
目录 BOMhistory DOM操作DOM1,dom.children 和 dom.childNodes 区别2,dom.remove()3,其他常用 API DOM 属性1,标准属性2,自定义属性 DOM 内容DOM样式DOM事件 JavaScript 包括 EcmaScript 和 WebAPI EcmaScript 包括 语…...
如何熟练使用vector?
🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻推荐专栏1: 🍔🍟🌯C语言初阶 🐻推荐专栏2: 🍔🍟🌯C语言进阶 🔑个人信条: 🌵知行合一 …...
gitlab-rake gitlab:backup:create 执行报错 Errno::ENOSPC: No space left on device
gitlab仓库备份执行 gitlab-rake gitlab:backup:create报错如下: 问题分析:存储备份的空间满 解决方法: 方法1:清理存放路径,删除不需要文件,释放空间。 方法2:创建一个根目录的挂载点&#x…...
【Nginx】负载均衡当其中一台服务器宕机之后
搭建一个简单的负载均衡,然后关闭其中一台再来访问,会发现我们的浏览器卡住一直转圈圈,过了很久才会显示结果。由此我们可以得出结论Nginx负载的时候如果其中一台服务挂掉了,它会把请求转发到另一个可以提供服务的机器,…...
每日一题 2511. 最多可以摧毁的敌人城堡数目
难度:简单 翻译:寻找距离最远的 1 和 -1 的组合,要求它们之间只有0 class Solution:def captureForts(self, forts: List[int]) -> int:res, t 0, -1for i, fort in enumerate(forts):if fort -1 or fort 1:if t > 0 and fort ! f…...
NLP(六十七)BERT模型训练后动态量化(PTDQ)
本文将会介绍BERT模型训练后动态量化(Post Training Dynamic Quantization,PTDQ)。 量化 在深度学习中,量化(Quantization)指的是使用更少的bit来存储原本以浮点数存储的tensor,以及使用更少的…...
机器学习和数据挖掘04-PowerTransformer与 MinMaxScaler
概念 PowerTransformer(幂变换器) PowerTransformer 是用于对数据进行幂变换(也称为Box-Cox变换)的预处理工具。幂变换可以使数据更接近正态分布,这有助于某些机器学习算法的性能提升。它支持两种常用的幂变换&#x…...
1.15 自实现GetProcAddress
在正常情况下,要想使用GetProcAddress函数,需要首先调用LoadLibraryA函数获取到kernel32.dll动态链接库的内存地址,接着在调用GetProcAddress函数时传入模块基址以及模块中函数名即可动态获取到特定函数的内存地址,但在有时这个函…...
总结ADX指标交易的好处
股神巴菲特从一个穷小子变成世界富豪,而闻名世界。anzo capital昂首资本以为这辈子再也不会和巴菲特产生任何交集,直到我看了巴菲特的发家史,才发现原来我们都使用过ADX指标盈利过,下面anzo capital昂首资本就总结一下使用ADX指…...
ConsoleApplication815项目(直接加载+VEH Hook Load)
上线图 ConsoleApplication815.cpp #include <iostream> #include<Windows.h> #include "detours.h" #include "detver.h" #pragma comment(lib,"detours.lib")#pragma warning(disable:4996)LPVOID Beacon_address; SIZE_T Beacon…...
事务(SQL)
事务概述 事务是一组操作的集合,他是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向西永提交或撤销操作请求。这组操作,要么全部执行成功,要么全部执行失败。 事务操作 查看/设置事务提交方式 -- 查看/设置事务…...
原型,原型链,继承(圣杯模式)
经典模式和圣杯模式区别 经典模式和圣杯模式都是用于解决构造函数继承和原型继承的问题,但它们在实现继承的方式上有所不同。 经典模式是通过将子类的原型对象设置为父类的实例来实现继承,然后将子类的构造函数设置为子类本身。这样子类既可以继承父类…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...
pycharm 设置环境出错
pycharm 设置环境出错 pycharm 新建项目,设置虚拟环境,出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...
【WebSocket】SpringBoot项目中使用WebSocket
1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖,添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...

