FPGA开发——按键控制数码管的设计
一、概述
按键控制数码管是一种常见的电子显示技术,它结合了按键输入与数码管显示的功能。在这一设计中,用户通过按下不同的按键来发送指令,这些指令随后被处理并转换为数码管上显示的数字或字符。按键通常作为输入设备,通过电路连接到微控制器(如FPGA、单片机等)的输入引脚,而数码管则作为输出设备,其显示内容由微控制器控制。
按键控制数码管的设计可以包括以下几个步骤:
-
按键输入处理:微控制器不断扫描按键的状态,当检测到按键被按下时,根据按键的编号或功能执行相应的操作。
-
指令转换:将按键的输入转换为数码管能够理解的显示指令。这通常涉及将按键编号或功能映射到特定的数字或字符编码。
-
数码管显示控制:微控制器根据转换后的显示指令,通过控制数码管的驱动电路来点亮或熄灭数码管中的不同段,从而显示出所需的数字或字符。
-
循环扫描与更新:为了保持数码管显示内容的实时性,微控制器需要不断重复上述步骤,形成一个循环扫描和更新的过程。
二、工程实现
1、基本思路构建
在本篇文章中我们以按键控制单个数码管为例讲解通过按键改变数码管显示的值的设计,基本思路如下:
在默认情况下数码管正常显示,当按下按键1时,数码管从正常显示的状态跳转到设置的状态,接着通过按键二队数码管显示的值进行一个改变,最后在按下按键1使得数码管从设置状态有重新回到正常显示状态,如此往复设计。
2、设计文件的编写
新建一个seg0.v文件
module seg0(input clk,input rst_n,input [1:0] key_in,input seg_sel,//位选output reg [7:0] seg_dual//段选
);
localparam ZERO = 8'b1100_0000, //共阳极段码ONE = 8'b1111_1001,TWO = 8'b1010_0100,THREE = 8'b1011_0000,FOUR = 8'b1001_1001,FIVE = 8'b1001_0010,SIX = 8'b1000_0010,SEVEN = 8'b1111_1000,EIGHT = 8'b1000_0000,NINE = 8'b1001_0000,A = 8'b1000_1000,b = 8'b1000_0011,c = 8'b1100_0110,d = 8'b1010_0001,E = 8'b1000_0110,f = 8'b1000_1110;
reg [26:0] cnt;
wire add_cnt;
wire end_cnt;
reg [4:0] flag;
wire add_flag;
wire end_flag;reg seg_flag;//数码管状态切换标志位
always @(posedge clk or negedge rst_n)beginif(!rst_n)cnt<=0;else if(add_cnt)beginif(end_cnt)cnt<=0;elsecnt<=cnt+1'b1;end
end
assign add_cnt=1'b1;
assign end_cnt=add_cnt && (cnt==50_000_000-1);always @(posedge clk or negedge rst_n)beginif(!rst_n)flag<=0;else if(seg_flag==1 && key_in[1])flag<=flag+1'b1;else if(add_flag)beginif(end_flag)flag<=0;elseflag<=flag+1'b1;end
end
assign add_flag=end_cnt;
assign end_flag=add_flag && (flag==16-1);always @(posedge clk or negedge rst_n)beginif(!rst_n)seg_flag<=0;else if(key_in[0])seg_flag<=~seg_flag;else seg_flag<=seg_flag;
endalways @(posedge clk or negedge rst_n)beginif(!rst_n)seg_dual<=8'b1111_1111;else if(seg_flag==0)begincase (flag)4'd0:seg_dual <=ZERO ;4'd1:seg_dual <=ONE ;4'd2:seg_dual <=TWO ;4'd3:seg_dual <=THREE; 4'd4:seg_dual <=FOUR ;4'd5:seg_dual <=FIVE ;4'd6:seg_dual <=SIX ;4'd7:seg_dual <=SEVEN;4'd8:seg_dual <=EIGHT;4'd9:seg_dual <=NINE ;4'd10:seg_dual<=A ;4'd11:seg_dual<=b ;4'd12:seg_dual<=c ;4'd13:seg_dual<=d ;4'd14:seg_dual<=E ;4'd15:seg_dual<=f ;default: ;endcaseend
end
endmodule
新建一个key.v文件
//状态机实现
module key (input clk ,input rst_n ,input [1:0] key_in , //输入原始的按键信号output reg [1:0] key_out //输出处理之后的按键信号
);
//参数定义localparam IDLE = 4'b0001,//空闲JITTLE0 = 4'b0010,//滤除第一次抖动DOWN = 4'b0100,//稳定JITTLE1 = 4'b1000;//滤除第二次抖动parameter TIME_20MS = 1_000_000;//需要计数的值,20ms//内部信号reg [3:0] state_c;//现态reg [3:0] state_n;//次态reg [19:0] cnt_20ms;//计数20mswire add_cnt_20ms;wire end_cnt_20ms;wire [1:0] nedge ;//下降沿信号wire [1:0] pedge ;//上升沿信号reg [1:0] key_in_r1 ;//打两拍 同步打拍reg [1:0] key_in_r2 ;//状态转移 同步时序逻辑描述状态转移always @(posedge clk or negedge rst_n) beginif(!rst_n)state_c <= IDLE;elsestate_c <= state_n;end//状态转移条件 组合逻辑always @(*) begincase (state_c)//一定是case 现态IDLE:beginif(nedge)state_n = JITTLE0;elsestate_n = state_c;endJITTLE0:beginif(end_cnt_20ms)state_n = DOWN;elsestate_n = state_c; endDOWN:beginif(pedge)state_n = JITTLE1;elsestate_n = state_c;endJITTLE1 :beginif(end_cnt_20ms)state_n = IDLE;elsestate_n = state_c; end default: state_n = IDLE;endcaseend//20ms计数器
always @(posedge clk or negedge rst_n) beginif(!rst_n)cnt_20ms <= 0;else if(add_cnt_20ms)beginif(end_cnt_20ms)cnt_20ms <= 0;elsecnt_20ms <= cnt_20ms + 1;end
endassign add_cnt_20ms = (state_c == JITTLE0) || (state_c == JITTLE1);
assign end_cnt_20ms = add_cnt_20ms && cnt_20ms == TIME_20MS - 1;//下降沿 上升沿
//同步 打拍
always @(posedge clk or negedge rst_n)begin if(!rst_n)beginkey_in_r1 <= 2'b11;key_in_r2 <= 2'b11;end else begin key_in_r1 <= key_in; //同步按键输入信号key_in_r2 <= key_in_r1; //打拍end
end//r1当前状态,r2上一个状态
assign nedge = ~key_in_r1 && key_in_r2;
assign pedge = key_in_r1 && ~key_in_r2;//key_outalways @(posedge clk or negedge rst_n) beginif(!rst_n)key_out <= 0;else if(end_cnt_20ms &&(state_c== JITTLE1))key_out <= ~key_in_r2;//有效脉冲 20nselse key_out <= 0;endendmodule
3、新建一个顶层文件top.v,用于将数码管和按键连接起来。
module top(input clk,input rst_n,input [1:0] key_in,output seg_sel,output [7:0] seg_dual);
wire [1:0] key_flag;
key key_inst(/*input */ .clk (clk ),/*input */ .rst_n (rst_n ),/*input */ .key_in (key_in ), //输入原始的按键信号/*output */ .key_out (key_flag ) //输出处理之后的按键信号
);seg0 seg_inst(/*input */ .clk (clk ),/*input */ .rst_n (rst_n ),.key_in (key_flag), ///*input */ .seg_sel (seg_sel ),//位选/*output*/ .seg_dual (seg_dual )//段选
);endmodule
4、测试文件的编写
其实这里我不推荐进行波形图仿真的,因为仿真需要编写的条件非常多,相比之下使用在线调试工具进行实时调试更好。这里我也给一个测试文件,需要的小伙伴可以加以完善。
//定义时间尺度
`timescale 1ns/1ns
module top_tb ;//输入信号定义
reg clk;
reg rst_n;
reg [1:0] key_in;
wire [7:0] seg_dual;
wire seg_sel;
defparam top_inst.cnt_inst.TIME_1s=500;
//模块例化
top top_inst(/*input */.clk (clk ),/*input */.rst_n (rst_n ),/*input */.key_in (key_in ),/*output*/.seg_sel (seg_sel ),/*output*/.seg_dual (seg_dual));
//激励信号产生
parameter CLK_CLY = 20;
//时钟
initial clk=1;
always #(CLK_CLY/2)clk=~clk;//复位
initial beginrst_n= 1'b0;#(CLK_CLY*3);#5;//复位结束避开时钟上升沿rst_n= 1'b1;
end//激励
//激励
integer i;
initial repeat(5)beginkey_in[1] = 1;//模拟按键未按下i ={$random}%6;//给i赋值0-5#(CLK_CLY*500);//等待复位时间结束#3;key_in[1] = 0;//前按键抖动开始#(CLK_CLY*1);//一个5-10ms的抖动时间repeat ((i+5)*50)beginkey_in[1] = $random;#(CLK_CLY*1);end key_in[1] = 0;//按键稳定#(CLK_CLY*100*500);//后抖动开始key_in[1] = 1;#(CLK_CLY*1);repeat ((i+5)*50)beginkey_in[1] = $random;#(CLK_CLY*1);end key_in[1] = 1;//按键稳定#(CLK_CLY*10*5000);key_in[2] = 1;//模拟按键未按下i ={$random}%6;//给i赋值0-5#(CLK_CLY*500);//等待复位时间结束#3;key_in[2] = 0;//前按键抖动开始#(CLK_CLY*1);//一个5-10ms的抖动时间repeat ((i+5)*50)beginkey_in[2] = $random;#(CLK_CLY*1);end key_in[2] = 0;//按键稳定#(CLK_CLY*100*500);//后抖动开始key_in[2] = 1;#(CLK_CLY*1);repeat ((i+5)*50)beginkey_in[2] = $random;#(CLK_CLY*1);end key_in[2] = 1;//按键稳定#(CLK_CLY*10*5000);key_in[0] = 1;//模拟按键未按下i ={$random}%6;//给i赋值0-5#(CLK_CLY*500);//等待复位时间结束#3;key_in[0] = 0;//前按键抖动开始#(CLK_CLY*1);//一个5-10ms的抖动时间repeat ((i+5)*50)beginkey_in[0] = $random;#(CLK_CLY*1);end key_in[0] = 0;//按键稳定#(CLK_CLY*100*500);//后抖动开始key_in[0] = 1;#(CLK_CLY*1);repeat ((i+5)*50)beginkey_in[0] = $random;#(CLK_CLY*1);end key_in[0] = 1;//按键稳定#(CLK_CLY*10*5000);key_in[0] = 1;//模拟按键未按下i ={$random}%6;//给i赋值0-5#(CLK_CLY*500);//等待复位时间结束#3;key_in[0] = 0;//前按键抖动开始#(CLK_CLY*1);//一个5-10ms的抖动时间repeat ((i+5)*50)beginkey_in[0] = $random;#(CLK_CLY*1);end key_in[0] = 0;//按键稳定#(CLK_CLY*100*500);//后抖动开始key_in[0] = 1;#(CLK_CLY*1);repeat ((i+5)*50)beginkey_in[0] = $random;#(CLK_CLY*1);end key_in[0] = 1;//按键稳定#(CLK_CLY*10*5000);key_in[1] = 1;//模拟按键未按下i ={$random}%6;//给i赋值0-5#(CLK_CLY*500);//等待复位时间结束#3;key_in[1] = 0;//前按键抖动开始#(CLK_CLY*1);//一个5-10ms的抖动时间repeat ((i+5)*50)beginkey_in[1] = $random;#(CLK_CLY*1);end key_in[1] = 0;//按键稳定#(CLK_CLY*100*500);//后抖动开始key_in[1] = 1;#(CLK_CLY*1);repeat ((i+5)*50)beginkey_in[1] = $random;#(CLK_CLY*1);end key_in[1] = 1;//按键稳定#(CLK_CLY*10*5000);//模拟意外抖动repeat (3)begin repeat ((i+5)*50)beginkey_in = $random;#(CLK_CLY*1);end key_in = 1;//按键稳定#(CLK_CLY*5000);end $stop;
end
endmodule
5、下板验证
在进行下板验证之后最终实现的效果和我们所改造的预期结果一致,这里格式限制上传不了视频,就不展示了。在下板验证时设计的引脚配置等由用户自己根据需求去设置。
三、不足之处
经过最后的检查之后,发现在开发板上进行验证时,在使用按键进行数码管显示数值的改变的这个过程当中我们看不到,因为是在标志位位1时计数里面进行改变,而我们的输出是在标志位为0时进行显示的,所以看不到,这里我们对seg0设计进行一个最简单粗暴的方法进行修改。这里修改的方法很low了,在后面的数字时钟的文章中我会加以完善,不足之处多多包涵。
修改之后的seg0文件:
//分频器
module seg0(input clk,input rst_n,input [1:0] key_in,input seg_sel,//位选output reg [7:0] seg_dual//段选
);
localparam ZERO = 8'b1100_0000, //共阳极段码ONE = 8'b1111_1001,TWO = 8'b1010_0100,THREE = 8'b1011_0000,FOUR = 8'b1001_1001,FIVE = 8'b1001_0010,SIX = 8'b1000_0010,SEVEN = 8'b1111_1000,EIGHT = 8'b1000_0000,NINE = 8'b1001_0000,A = 8'b1000_1000,b = 8'b1000_0011,c = 8'b1100_0110,d = 8'b1010_0001,E = 8'b1000_0110,f = 8'b1000_1110;
reg [26:0] cnt;
wire add_cnt;
wire end_cnt;
reg [4:0] flag;
wire add_flag;
wire end_flag;reg seg_flag;//数码管状态切换标志位
always @(posedge clk or negedge rst_n)beginif(!rst_n)cnt<=0;else if(add_cnt)beginif(end_cnt)cnt<=0;elsecnt<=cnt+1'b1;end
end
assign add_cnt=1'b1;
assign end_cnt=add_cnt && (cnt==50_000_000-1);always @(posedge clk or negedge rst_n)beginif(!rst_n)flag<=0;else if(add_flag)beginif(end_flag)flag<=0;elseflag<=flag+1'b1;end
end
assign add_flag=end_cnt;
assign end_flag=add_flag && (flag==16-1);always @(posedge clk or negedge rst_n)beginif(!rst_n)seg_flag<=0;else if(key_in[0])seg_flag<=~seg_flag;else seg_flag<=seg_flag;
endalways @(posedge clk or negedge rst_n)beginif(!rst_n)seg_dual<=8'b1111_1111;else if(seg_flag==0)begincase (flag)4'd0:seg_dual <=ZERO ;4'd1:seg_dual <=ONE ;4'd2:seg_dual <=TWO ;4'd3:seg_dual <=THREE; 4'd4:seg_dual <=FOUR ;4'd5:seg_dual <=FIVE ;4'd6:seg_dual <=SIX ;4'd7:seg_dual <=SEVEN;4'd8:seg_dual <=EIGHT;4'd9:seg_dual <=NINE ;4'd10:seg_dual<=A ;4'd11:seg_dual<=b ;4'd12:seg_dual<=c ;4'd13:seg_dual<=d ;4'd14:seg_dual<=E ;4'd15:seg_dual<=f ;default: ;endcaseend else if(seg_flag==1)beginif(key_in[1])begincase (flag)4'd0:seg_dual <=ZERO ;4'd1:seg_dual <=ONE ;4'd2:seg_dual <=TWO ;4'd3:seg_dual <=THREE; 4'd4:seg_dual <=FOUR ;4'd5:seg_dual <=FIVE ;4'd6:seg_dual <=SIX ;4'd7:seg_dual <=SEVEN;4'd8:seg_dual <=EIGHT;4'd9:seg_dual <=NINE ;4'd10:seg_dual<=A ;4'd11:seg_dual<=b ;4'd12:seg_dual<=c ;4'd13:seg_dual<=d ;4'd14:seg_dual<=E ;4'd15:seg_dual<=f ;default: ;endcaseendend
end
endmodule
经过本次修改之后就可以观察得到数码管显示数值的一个修改过程,到这里本次设计也就结束了。
相关文章:
FPGA开发——按键控制数码管的设计
一、概述 按键控制数码管是一种常见的电子显示技术,它结合了按键输入与数码管显示的功能。在这一设计中,用户通过按下不同的按键来发送指令,这些指令随后被处理并转换为数码管上显示的数字或字符。按键通常作为输入设备,通过电路…...

【AI学习】[2024北京智源大会]具身智能:具身智能关键技术研究:操纵、决策、导航
具身智能关键技术研究:操纵、决策、导航 董 豪 | 北京大学助理教授 依然是边看边做些记录 这张图的重点是在说,我们的大脑,也是不同的部分处理不同的功能。这里面有些功能,比如视觉、听觉理解等功能,LLM已经具备&…...
C语言实现UDP广播
UDP 广播发送方 1.创建套接字:使用socket()函数创建一个UDP套接字。 2.设置套接字选项:使用setsockopt()函数设置SO_BROADCAST选项以允许广播。 3.发送数据:使用sendto()函数将数据发送到特定的广播地址和端口。 #include <stdio.h> …...
速记Java八股文——Redis 篇
前言 分类汇总 50 常见的 Redis 篇 经典后端面试题,并对题目进行了精炼总结,旨在帮助大家高效记忆,在面试中游刃有余,不至于陷入词穷的窘境。 Redis 篇 什么是Redis? Redis是一个开源的内存数据结构存储系统,可用作数…...

CUDA编程05 - GPU内存架构和数据局部性
一:概述 到目前为止,我们已经学会了如何编写 CUDA 核函数,以及如何设置和分配大量线程来执行核函数。我们还了解了当前 GPU 硬件的计算架构,以及线程在硬件上调度执行过程。在本章中,我们将重点关注 GPU 的片上(on-chi…...

TCP协议程序设计
文章目录 前言一、TCP协议程序是什么?二、使用步骤 1.服务器端与客户端2.实操展示总结 前言 TCP网络程序设计是指利用Socket类编写通信程序。利用TCP协议进行通讯的两个应用程序是有主次之分的,一个称为服务器程序,另一个称为客户机程序&…...

【C++高阶】:自定义删除器的全面探索
✨ 我凌于山壑万里,一生自由随风起 🌏 📃个人主页:island1314 🔥个人专栏:C学习 🚀 欢迎关注:👍点赞 👂&am…...
Java中的不可变集合、Stream流以及异常处理的
目录 1. 不可变集合 如何创建不可变集合 2. Stream流 Stream基本操作 3. 异常处理 异常的分类 异常处理机制 1. 不可变集合 在Java中,不可变集合指的是一旦创建后内容不可更改的集合。这种集合的好处在于它们可以安全地被多个线程访问而无需同步,…...
LeetCode面试题Day1|LeetCode26 删除有序数组中的重复项、LeetCode80 删除有序数组中的重复项Ⅱ
前言: 暑假实在不知道干什么了,做一下力扣的《面试经典150题》吧,记录一下学习轨迹。(如果有要打非中文竞赛或者精进一下英语水平的记得把力扣调成英文) 题目1: 指路: . - 力扣(LeetCode)26…...

细说文件操作
你好!感谢支持孔乙己的新作,本文就文件操作与大家分享我的思路。 希望能大佬们多多纠正及支持 !!! 个人主页:爱摸鱼的孔乙己-CSDN博客 目录 1.什么是文件 1.1.程序设计文件 1.1.1.程序文件 1.1.2.数据文…...

Vue3从零开始——掌握setup、ref和reactive函数的奥秘
文章目录 一、Vue 3 组合式 API 概述二、setup 函数的基本使用2.1 setup 函数的特点2.2 setup 函数的基本结构2.3 实现一个简单的小demo 三、ref 函数的功能和应用3.1 ref函数介绍3.2 基本使用3.2.1 定义ref数据3.2.2 修改响应式变量 3.3 使用ref函数实现计数器 …...
C语言练习--屏幕上打印九九乘法表
int main() { int i 0; for (i 1; i < 10; i) { int j 0; for (j 1; j <i; j) { printf(" %d*%d%2d", i, j, i * j); } printf("\n"); } return 0; }...

将tsx引入vue
按钮 vue <cl-batch-btn >新增批量</cl-batch-btn> import batch from "//modules/ad/components/ uploading/batch.vue" import ClBatchBtn from "/~/crud/src/components/batch-btn"; tsx...

前端实现签字效果+合同展示
文章目录 获取一个高度会变的元素的高度获取元素设置的 transform适配手机transform-origin: 5% 0; 的原因修改后 签字效果取消el-dialog的头部边距为什么禁止界面滚动vue3 使用 nextTick实现效果 签字判断是横是竖canvas 去掉空白部分canvas裁剪图片最终完善代码,可…...
[AI Embedchain] 开始使用 - 快速开始
安装 首先安装 Python 包: pip install embedchain安装包后,根据您的偏好,您可以选择使用以下内容: 开源模型 本节提供了一个快速入门示例,展示了如何使用 Mistral 作为开源 LLM(大型语言模型ÿ…...
Linux网络协议.之 tcp,udp,socket网络编程(三).之多进程实现并发demon
一、fork创建进程,来实现多并发 这只是个demon,并不能用于实际项目,多进程,消耗太多资源。没有人这么玩 1、服务端代码: #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #in…...
Java线程(练习题)
Exercise 创建三个线程:一个线程打印 100个A,一个线程打印 100 个 B ,一个线程打印 100个C 输出效果:ABC ABC ABC…交替打印 package com.kane.exercise01;public class PrintABC implements Runnable {private static final Object lock …...

MySQL:初识数据库初识SQL建库
目录 1、初识数据库 1.1 什么是数据库 1.2 什么是MySQL 2、数据库 2.1 数据库服务&数据库 2.2 C/S架构 3、 初识SQL 3.1 什么是SQL 3.2 SQL分类 4、使用SQL 4.1 查看所有数据库 4.1.2 语句解析 4.2 创建数据库 4.2.1 if not exists校验 4.2.2 手动明确字符集…...

关于Redis的集群面试题
问题一:Redis的多数据库机制,了解多少? Redis支持多个数据库,并且每个数据库是隔离的不能共享,单机下的redis可以支持16个数据库(db0~db15);若在Redis Cluster集群架构下,则只有一个…...
带头双向循环链表(一)
今天我们来学习带头双向链表 带头双向循环链表的解释 带头双向链表顾名思义就是: 1、带了一个“头”在数据结构中的意思就是加了一个"哨兵位"。 2、这个链表是双向循环的链表即可以通过任意的节点访问它的上一个和下一个的节点也能通过链表的头直接访…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...