FPGA 34 矩阵键盘 模块设计_fpga按键模块设计_没有价值的生命的博客-程序员秘密

技术标签: fpga  FPGA  verilog  

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t93Mpr2Y-1627401356069)(FPGA 09 阻塞和非阻塞状态的理解.assets/test.png)]

FPGA 34 矩阵键盘 模块设计

​ 最早的 MCU(即单片机)其 IO 口相对较少,而且用到按键过多的话, 就会占用过多的 IO。 人们为了解决这个问题就引入了“矩阵键盘”。 在矩阵键盘中,每条行线和列线在交叉处都不是直接连同, 而是通过一个按键直接相连,这样以来一个 4*4 的矩阵键盘只需要 8 根控制线就可以完成16 个按键的控制。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-md3ZukjT-1631430335809)(E:/Blog_Template/source/_posts/img/blog_img/fpga/image-20210602155737943.png)]

矩阵键盘工作原理 :

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1oYfNTiT-1631430335811)(E:/Blog_Template/source/_posts/img/blog_img/fpga/image-20210602155831214.png)]

​ 检测矩阵键盘中某一按键是否被按下, 采用的方法是列扫描法。 图中一共有 8条控制线, 4 条行控制线(ROW),4 条列控制线(COL) 。在原理图图中,我们可以看到,ROW的信号【对于FPGA】是一个输入IO,COL0、1、2、3 是一个输出IO的配置,所以FPGA 只需要读取ROW0、1、2、3 端口的信号来进行判断。

​ 假如我们让 COL0=0,然后去读取 ROW 的值,如果 4 个 ROW 信号的电平全部为高,则表明当前列并无按键按下,则切换到扫描下一列,再去读取 4 个 ROW 信号的值,根据读到的 ROW 值判断当前是哪一个按键被按下。例如当扫描第三列的时候,即 COL=4’b1011 时,检测到 ROW=4’b1011,则说明“A”被按下。

矩阵键盘扫描驱动模块设计 :

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xtfU9O1q-1631430335813)(E:/Blog_Template/source/_posts/img/blog_img/fpga/image-20210602170014986.png)]

端口描述:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tKxC7FcN-1631430335815)(E:/Blog_Template/source/_posts/img/blog_img/fpga/image-20210602170036488.png)]

矩阵键盘检测状态转移图 :(P208)

key_board.v 文件

module key_board
(
	Clk,
	Rst_n,
	Key_Board_Row_i,

	Key_flag,
	Key_Value,
	Key_Board_Col_o
);

	input Clk ;
	input Rst_n;
	input [3:0]Key_Board_Row_i;

	output reg Key_flag;
	output reg [3:0]Key_Value;
	output reg [3:0]Key_Board_Col_o;

	
	// 输入列寄存器信号,输入以后做一次寄存
	reg [3:0]Key_Board_Row_r;

	reg En_Cnt ;	//滤波定时器
	reg [19:0] counter1; //滤波定时,时钟周期计数器
	reg Cnt_Done;	//滤波时间完成标志信号

	reg [3:0]Col_Tmp ; 	// 列按键按下状态 
	reg  Key_Flag_r; 	// 按键成功标志位
	
	reg [7:0]Key_Value_tmp;
	
	reg  [10:0]state;
	
	//按键按下标志位
	[email protected](posedge Clk)
		Key_flag <= Key_Flag_r;
	
	// 状态机状态参数
	localparam 
		IDEL				= 11'b00000000001,
		P_FILTER			= 11'b00000000010,
		READ_ROW_P 		= 11'b00000000100,
		SCAN_C0 			= 11'b00000001000,
		SCAN_C1 			= 11'b00000010000,
		SCAN_C2 			= 11'b00000100000,
		SCAN_C3 			= 11'b00001000000,
		PRESS_RESULT 	= 11'b00010000000,
		WAIT_R			= 11'b00100000000,
		R_FILTER 		= 11'b01000000000,
		READ_ROW_R 		= 11'b10000000000;

	// 滤波定时计数器

	[email protected](posedge Clk or negedge Rst_n)
	if(!Rst_n)
		counter1 <= 20'd0;
	else if(En_Cnt)begin
		if(counter1 == 20'd999999)
			counter1 <= 20'd0;
		else
			counter1 <= counter1 + 1'b1;
	end
	else
		counter1 <= 20'd0;
		
	[email protected](posedge Clk or negedge Rst_n)
	if(!Rst_n)
		Cnt_Done <= 1'b0;
	else if(counter1 == 20'd999999)
		Cnt_Done <= 1'b1;
	else
		Cnt_Done <= 1'b0;



	//状态机
	always @(posedge Clk or negedge Rst_n)
	if(!Rst_n)
	begin
	  state <= IDEL ;
	  Key_Board_Col_o <= 4'b0000 ; //输出端口默认设置为低电平,只有按键按下时,默认的上拉电平就会变成低电平
	  En_Cnt <= 1'b0;
	  Col_Tmp <= 4'd0;
	  Key_Flag_r <= 1'b0;
	  Key_Value_tmp <= 8'd0;
	  Key_Board_Row_r <= 4'b1111;
	end
	else
	begin
		case (state)
			IDEL: 
				if(~&Key_Board_Row_i)begin  // Key_Board_Row_i  不等于 4‘d1111,说明有按键按下
					En_Cnt <= 1'b1 ;    // 开启滤波定时器
					state <= P_FILTER;  // 跳转进入前级滤波状态
				end
				else begin			// 按键未按下
					En_Cnt <=1'b0 ; // 消抖滤波定时器关闭
					state  <=IDEL ; // 等待状态 
				end
			P_FILTER :
				if(Cnt_Done) begin	//消抖滤波定时时间结束
				  	En_Cnt <= 1'b0; //关闭滤波定时器
					state <= READ_ROW_P; //跳转进入滤波检测状态
				end
				else begin			//消抖定时未结束
					En_Cnt <= 1'b1; //继续保持
					state <= P_FILTER;// 状态继续保持当前值
				end
			READ_ROW_P:
				if (~&Key_Board_Row_i) begin  //滤波后,第二次确定按键确实按下
					Key_Board_Row_r <= Key_Board_Row_i; // 存取当前状态的值
					Key_Board_Col_o <= 4'b1110;  // 设置 Key_Board_Col_o 的输出信号为 4‘b1110,其它列设置为高电平
					state <= SCAN_C0;	// 跳转进入第C0列的判断
				end
				else begin 			//这次是按键抖动
					state  <=IDEL ; // 进入空闲等待状态
					Key_Board_Col_o <= 4'b0000;  // 设置 Key_Board_Col_o 的输出信号为 4‘b0000
				end
			SCAN_C0 :
				begin
					Key_Board_Col_o <= 4'b1101;  // 设置 Key_Board_Col_o 的输出信号为 4‘b1101
					state <= SCAN_C1;	// 跳转进入第C1列的判断
					if(~&Key_Board_Row_i) //其它3列设置为高电平后,Key_Board_Row_i 仍然为按键按下状态
						Col_Tmp <= 4'b0001 ; // 表示此次按下的按键是再第一列
					else
						Col_Tmp <= 4'b0000 ; // 表示此次按下的按键不在这列
				end
			SCAN_C1 :
				begin
					Key_Board_Col_o <= 4'b1011;  // 设置 Key_Board_Col_o 的输出信号为 4‘b1011
					state <= SCAN_C2;	// 跳转进入第C2列的判断
					if(~&Key_Board_Row_i) //其它3列设置为高电平后,Key_Board_Row_i 仍然为按键按下状态
						Col_Tmp <= 4'b0010 | Col_Tmp ; // 表示此次按下的按键是再第2列
					else
						Col_Tmp <= Col_Tmp ; // 表示此次按下的按键不在这列
				end
			SCAN_C2 :
				begin
					Key_Board_Col_o <= 4'b0111;  // 设置 Key_Board_Col_o 的输出信号为 4'b0111
					state <= SCAN_C3;	// 跳转进入第C3列的判断
					if(~&Key_Board_Row_i) //其它3列设置为高电平后,Key_Board_Row_i 仍然为按键按下状态
						Col_Tmp <= 4'b0100 | Col_Tmp ; // 表示此次按下的按键是再第2列
					else
						Col_Tmp <= Col_Tmp ; // 表示此次按下的按键不在这列
				end
			SCAN_C3 :
				begin
					state <= PRESS_RESULT;	// 进入此状态后,表示按键检测已经结束,需要进入下一个按键结果分析状态
					if(~&Key_Board_Row_i) 	// 其它3列设置为高电平后,Key_Board_Row_i 仍然为按键按下状态
						Col_Tmp <= 4'b1000 | Col_Tmp ; // 表示此次按下的按键是再第3列
					else
						Col_Tmp <= Col_Tmp ; // 表示此次按下的按键不在这列
				end
			PRESS_RESULT:
				begin
					state <= WAIT_R;		// 本次结果分析完成后,进入按键松开滤波状态
					Key_Board_Col_o <= 4'b0000; //按键检测查找完成,所以重新设置,输出Key_Board_Col_o的信号为 4‘b0000
					if(((Key_Board_Row_r[0] + Key_Board_Row_r[1] + Key_Board_Row_r[2] + Key_Board_Row_r[3]) == 4'd3) &&
					((Col_Tmp[0] + Col_Tmp[1] + Col_Tmp[2] + Col_Tmp[3]) == 4'd1)) // 检验是否只有一个按键按下
					begin
						Key_Flag_r <= 1'b1;							//产生按键成功标志信号
						Key_Value_tmp <= {Key_Board_Row_r,Col_Tmp}; //位拼接,等下来查找
					end
					else
					begin
						Key_Flag_r <= 1'b0; 			//非单个按键按下,不产生按键完成信号
						Key_Value_tmp <= Key_Value_tmp; //按键值保持上一次按键的值
					end
				end
			WAIT_R :
				begin
					Key_Flag_r <= 0 ; // 按键成功标志信号清零
					if(&Key_Board_Row_i) //  Key_Board_Row_i = 4’b1111 表示(按键未按下)即,按键松开,此时我们进入后消抖状态
					begin
						En_Cnt =1'b1; // 开启消抖滤波的计时器
						state <= R_FILTER ; //进入后消抖判断转态
					end
					else // 按键仍然按下,我们在这次保持等待状态
					begin
						state <= WAIT_R ;
						En_Cnt =1'b0; // 消抖滤波的计时器暂时先不开启
					end	
				end
			R_FILTER :
				if(Cnt_Done)begin  //后消抖滤波定时完成
					En_Cnt <= 1'b0; 		//关闭滤波定时器使能信号
					state <= READ_ROW_R; 	//进入按键完全释放状态判断
				end
				else
				begin
					En_Cnt <= 1'b1; 		// 滤波消抖定时器正在进行
					state  <= R_FILTER;		// 继续保持滤波状态
				end
			READ_ROW_R :
				if(&Key_Board_Row_i)  // (Key_Board_Row_i =4'd1111)即,确定按键已经松开,本次按键检测已经完成
					state <= IDEL;
				else 	// 按键还没松开,再次后消抖滤波
				begin
					state <= R_FILTER;		// 再次进入后消抖滤波状态
					En_Cnt <= 1'b1; 		// 开启滤波消抖定时器
				end
			default:  state <= IDEL; // 默认,或者运行出错,进入空闲状态
		endcase  
	end

	//按键输出状态查找表  根据 : Key_Value_tmp <= {Key_Board_Row_r,Col_Tmp};  实现数据的查找
	always @(posedge Clk or negedge Rst_n)
	if(!Rst_n)
		Key_Value <= 4'd0 ;
	else if(Key_Flag_r)  // 先判断,按键是否按下成功
	begin
		case (Key_Value_tmp)
			8'b1110_0001 : Key_Value <= 4'd0;
			8'b1110_0010 : Key_Value <= 4'd1;
			8'b1110_0100 : Key_Value <= 4'd2;
			8'b1110_1000 : Key_Value <= 4'd3;
			
			8'b1101_0001 : Key_Value <= 4'd4;
			8'b1101_0010 : Key_Value <= 4'd5;
			8'b1101_0100 : Key_Value <= 4'd6;
			8'b1101_1000 : Key_Value <= 4'd7;
			
			8'b1011_0001 : Key_Value <= 4'd8;
			8'b1011_0010 : Key_Value <= 4'd9;
			8'b1011_0100 : Key_Value <= 4'd10;
			8'b1011_1000 : Key_Value <= 4'd11;
			
			8'b0111_0001 : Key_Value <= 4'd12;
			8'b0111_0010 : Key_Value <= 4'd13;
			8'b0111_0100 : Key_Value <= 4'd14;
			8'b0111_1000 : Key_Value <= 4'd15; 
			default: Key_Value <= Key_Value ;
		endcase
	end

endmodule







矩阵键盘模型:

`timescale 1ns/1ns
module Key_Board_model(
    Key_Col,
    Key_Row
    );
    // 矩阵键盘模型
    // 注: 写的是一个键盘的模型,相当于模拟矩阵的输入和输出
    // 主要是模拟按键按下,信号输出给fpga 的过程,其过程包括按键抖动信号
    input [3:0]Key_Col; //对于矩阵键盘来说,Key_Col 是一个 输入信号,对fpga是一个输出信号
    output reg [3:0]Key_Row; //Key_Row 是一个输出信号,对pga 是有一个输入信号

    reg [5:0]myrand ;
    reg [3:0]Key_Row_r; //行寄存器
    reg key_row_sel ;
    reg [1:0]now_col,now_row ; //当前行与当前列

    initial begin
        now_col =0;
        now_row =0;
        key_row_sel =0 ;
        myrand =0 ;
    end

    initial begin
        Key_Row_r = 4'b1111 ; // 初始状态,即模型按键未按下时刻,矩阵键盘的行信号默认都是上拉电平,即全是高电平
        #50000000 ;
        // 顺序按键按下,
        press_key(0, 0); //第一行
        press_key(0, 1);
        press_key(0,2);
        press_key(0,3);

        press_key(1, 0); //第二行
        press_key(1, 1);
        press_key(1,2);
        press_key(1,3);

        press_key(2, 0); //第三行
        press_key(2, 1);
        press_key(2,2);
        press_key(2,3);
        
        press_key(3, 0); //第四行
        press_key(3, 1);
        press_key(3,2);
        press_key(3,3);
		  
        $stop;

    end
    // 编写press_key任务(函数)  调用方式: press_key(row,col); //参数输入按键的位置row,col
    task press_key;
        input [1:0]row,col;
        // 按键按下进行执行下列操作
        begin
            key_row_sel = 0;//将行选择信号设置为有效状态
            Key_Row_r = 4'b1111; // 初始状态按键未按下
            Key_Row_r[row] = 0 ; // row,按键按下,让Key_Row_r 的这个row bit 未设置为0 ,表示按键按下
            now_row = row;  
            repeat(20)begin //重复 20 次,随机产生按键按下时 20 个不同的行状态
                myrand = {$random} % 65536; //随机延时
                #myrand Key_Row_r[row] = ~Key_Row_r[row]; // 模拟按键抖动(电平时高时低)状态
            end
            key_row_sel = 1; //将行选择信号设置为有效状态
            now_col = col;   //消抖以后,获取当前列输入信号 col ???
            #22000000;
            key_row_sel =0 ;
            Key_Row_r = 4'b1111; // 进入按键后滤波状态
            repeat(20)begin //重复 20 次,随机产生按键松开时 20 个不同行状态
                myrand = {$random} % 65536;
                #myrand Key_Row_r[row] = ~Key_Row_r[row];
            end
            Key_Row_r = 4'b1111; // 按键完全释放
            #22000000;
        end
    endtask

    always @(*) 
    if (key_row_sel)  //行信号有效
        case(now_row) //根据输入的列信号,获取按键Key_Row输出的行信号
            2'd0:Key_Row = {1'b1,1'b1,1'b1,Key_Col[now_col]};
            2'd1:Key_Row = {1'b1,1'b1,Key_Col[now_col],1'b1};
            2'd2:Key_Row = {1'b1,Key_Col[now_col],1'b1,1'b1};
            2'd3:Key_Row = {Key_Col[now_col],1'b1,1'b1,1'b1};
        endcase
    else
        Key_Row = Key_Row_r ; 

endmodule


验证测试脚本文件:

`timescale 1ns/1ns
//矩阵键盘的仿真模型
module Key_Board_tb;

    reg Clk;
    reg Rst_n;

    wire [3:0]Key_Row;
    wire [3:0]Key_Col;

    wire Key_flag;
    wire [3:0]Key_Value;

    key_board key_board_0(
	.Clk(Clk),
	.Rst_n(Rst_n),
	.Key_Board_Row_i(Key_Row),

	.Key_flag(Key_flag),
	.Key_Value(Key_Value),
	.Key_Board_Col_o(Key_Col)
    );

    Key_Board_model Key_Board_model_inst(Key_Col,Key_Row);

    initial Clk =1 ;
    always #10 Clk = ~Clk ;

    initial begin
        Rst_n =0;
        #200
        Rst_n =1;
    end

endmodule





FPGA 上拉设置问题 (注:不设置矩阵键盘测试无法正常工作,开始被坑了很多遍)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ormashuQ-1631430335818)(E:/Blog_Template/source/_posts/img/blog_img/fpga/image-20210606213358925.png)]

step1:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jm0H98Uj-1631430335819)(E:/Blog_Template/source/_posts/img/blog_img/fpga/image-20210606213452072.png)]

step2:

在这里插入图片描述

step3:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gsc2vOVz-1631430335820)(E:/Blog_Template/source/_posts/img/blog_img/fpga/image-20210606213600534.png)]

step4:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4LbAMsOt-1631430335821)(E:/Blog_Template/source/_posts/img/blog_img/fpga/image-20210606213656950.png)]

step5:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jfxVTcqw-1631430335821)(E:/Blog_Template/source/_posts/img/blog_img/fpga/image-20210606213750711.png)]

最终配置效果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JA5ZOWJU-1631430335822)(E:/Blog_Template/source/_posts/img/blog_img/fpga/image-20210606213828750.png)]

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lj1986817902/article/details/120250839

智能推荐

东方财富股吧标题爬取分析_一加六的博客-程序员秘密

共45个贴吧,日期从2018-03-01至2021-03-01共36个月的股吧帖子,爬取股吧名称、阅读、评论、标题、作者和发帖时间,并分析总体情绪亮点回顾时间问题获取的时间未加年份,解决方法,观察发现发帖日期月份逐级递减,按获取顺序下一个时间月份在同一年内小于等于上一个月份,设一个全局变量m储存月份,因为当前为3月份,将其初始值设为12,与获取的最新月份new_m比较,若new_m&gt;m,使当前年份减一,数据去重问题有时候爬取会因各自问题中断,当你再次续爬时数据会重复,于是我加了一个用于.

Android自定义EditText:一款简单实用的智能EditText(一键删除&自定义样式)_Carson带你学Android的博客-程序员秘密

前言Android开发中,EditText的使用 非常常见本文将带来一款 附带一键删除功能 & 自定义样式丰富的 SuperEditText控件的使用,希望你们会喜欢。 已在Github开源:Super_EditText,欢迎 Star ! 目录1. 简介一款 自定义样式丰富 & 附带一键删除功能的 SuperEditText控件 已在Github开源:Super_Edit

Java.lang.ClassNotFoundException: com.google.common.reflect.TypeToken_Mr.Chen'的博客-程序员秘密

导致错误的原因是因为使用@FeignClient注解的前提需要增加依赖引入&lt;dependency&gt; &lt;groupId&gt;com.google.guava&lt;/groupId&gt; &lt;artifactId&gt;guava&lt;/artifactId&gt; &lt;version&gt;18.0&lt;/version&gt;&l...

python爬虫高级教程:多线程队列,生产消费模式爬虫_多线程爬虫使用队列因为什么_Python_sn的博客-程序员秘密

在爬取大量数据时,由于有成千上万的数据,单线程爬虫显然不能满足我们的需求,这时候多线程爬虫就来了,本篇文章使用Threading和Queue简单介绍。很多人学习python,不知道从何学起。很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。很多已经做案例的人,却不知道如何去学习更加高深的知识。那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!??¤QQ群:623406465首先先了解多线程队列,生产消费模式的大致步骤。1.主线程

[囧途系列之特别篇]IT者的生存之路_weixin_30781433的博客-程序员秘密

此文特别送给 一个网友 kkgbn[盖宝宁] 前言: 我的一个很早的转文:一对夫妻程序员的故事, 看到了一个由kkgbn发表的评论: 评论的大意是“希望能多发发正能量的帖子,把程序员的迷茫带走。让我们一起找到生活的出路。" ,详细内容大家可以进入该帖子查看。 个人觉得很有感触,感谢kkgbn提出的好建议,同时有感而发写此文特此送给kkgbn以及有类似感触的...

Android Kotlin项目生成文档工具Dokka(JavaDoc)_dokka android_leifuCode的博客-程序员秘密

Android Kotlin项目生成文档工具Dokka一 概述二 kotin项目文档生成工具Dokka三 项目中Dokka的配置四 如何使用Dokka生成文档五 查看Dokka生成文档一 概述我们知道使用Java代码书写的Android项目,可以直接用Androidstudio自带的JavaDoc生成工具自动生成(Tools—&gt;GenerateJavaDoc),那么使用Kotlin语言书写的Androidstudio项目和使用Kotlin和java混合开发的android项目呢,可不可以使

随便推点

java使用modbus tcp协议与设备通讯,获取设备状态_wangstyle_007的博客-程序员秘密

参考地址:https://blog.csdn.net/sifanlook/article/details/81251626最近项目应用场景:读出污水池坑中水泵状态、污水坑溢出液位报警等设备状态。引入相关maven依赖 &lt;repositories&gt; &lt;repository&gt; &lt;releases&gt; &lt;enabled&gt;false&lt;/enabled&gt; &lt;/releases&g

RStudio安装xlsx包_小小潘多拉的博客-程序员秘密

1.下载和安装Javahttps://www.java.com/zh_CN/,在电脑的环境变量里新建JAVA_HOME变量,在Path中添加Java安装目录2.打开Rstudio,在Tools – Global Options –General – R version Change选项中切换为32-bit3.在Console中进入以下命令即可Sys.setenv(JAVA_...

新手.关于css父级加入绝对定位后,子标签的text-align失效的解决方法_li标签下使用绝对定位失效_gg古古的博客-程序员秘密

&lt;div&gt; &lt;ul&gt; &lt;li&gt;菜单&lt;/li&gt;&lt;li&gt;菜单&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;问题:在给div加入绝对定位后,让li左浮动,设置左间距(margin-left),让li并排且有间距的排列,但是却无法让li在ul里居中排列。解决:此时只要让ul 设display...

产品经理必修课(7):文档管理_yufawu的博客-程序员秘密

一、产品经理要不要懂技术?大家通常提到的产品经理,除了常规意义上全权负责产品的产品经理之外,还有产品设计师、用户体验产品经理,以及后台产品经理、需求分析师等很多种。不同的公司,产品经理负责的事务也各不相同。从行业角度,也可以分为技术型产品的 PM、设计型产品的 PM、运营导向产品的 PM。再细一点划分,还可以分出电商产品的 PM、社交产品的PM或者搜索产品的 PM等。在某招聘网站上,产品经理的...

brew services start redis 无法使用问题排查_brew services 启动失败日志_尘埃726的博客-程序员秘密

起因Mac上使用brew services start --all指令同时启动多个服务显示成功但是,连接四个服务所在端口均无响应。仔细核对过brew指令启动服务使用的路径、配置文件路径均无问题。怀疑过是不是用户权限、系统防火墙之类影响。后检查日志信息时,发现无权限访问日志文件,此原因导致服务实际启动失败,而brew表面显示启动成功。经修改目录权限后重启服务一切正常,问题解决。brew s...

java8-Stream流之数值函数(求和、最大值、最小值、平均值)_stream流求平均值_一只渣渣的博客-程序员秘密

//todo stream流的使用 //todo filter:过滤操作;保留符合过滤条件的对象;这是一个中间操作;后面可以带最终操作 //todo mapToInt: 将数据根据double类型来处理; public static void main(String[] args) { List&lt;SalesOrder&gt; list = creat...

推荐文章

热门文章

相关标签