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、这个链表是双向循环的链表即可以通过任意的节点访问它的上一个和下一个的节点也能通过链表的头直接访…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
日常一水C
多态 言简意赅:就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过,当子类和父类的函数名相同时,会隐藏父类的同名函数转而调用子类的同名函数,如果要调用父类的同名函数,那么就需要对父类进行引用&#…...
Chrome 浏览器前端与客户端双向通信实战
Chrome 前端(即页面 JS / Web UI)与客户端(C 后端)的交互机制,是 Chromium 架构中非常核心的一环。下面我将按常见场景,从通道、流程、技术栈几个角度做一套完整的分析,特别适合你这种在分析和改…...
Python训练营-Day26-函数专题1:函数定义与参数
题目1:计算圆的面积 任务: 编写一个名为 calculate_circle_area 的函数,该函数接收圆的半径 radius 作为参数,并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求:函数接收一个位置参数 radi…...
