IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 键盘扫描和编码器 -> 正文阅读

[嵌入式]键盘扫描和编码器

设计思想

? ? ? ? 键盘扫描和编码器用于在拥有键盘的数字系统中手工输入数据,通过检测按键是否按下,产生一个唯一对应此按键的扫描码,设计十六进制键盘电路的键盘扫描和编码器。

? ? ? ? ??????????

????????利用状态机来循环检测信号的列位置,其中ab/c表示为a:S_row(所有行信号相与),b:row(行信号),c:Vaild(使能信号)。S_0初始状态,S_i表示检测第i列的状态,S_5表示已经找到列信号。刚开始,一旦检测到S_raw有效,说明有按键按下,此时在所有列信号置(clo=1111,即15)的情况下,依次检测行信号,先进入第一列(S_1)检测,如果在S_1状态下的row有效,就说明有按键按下,通过改变col的值来记录列号,否则依次检测其他状态。

??????此模块定义为hex_keypad_grayhill,输入信号有S_row、row,输出信号有code(按键字母)、vaild、col,利用S_row和row信号,通过状态机找到行信号col,然后结合row和col找到code(按键字母)。

? ? ? ? 对于上述模块中使用到的S_row,可由模块synchronizer决定的,通过检测各行线值的或来决定的,即只要给该设计模块行信号row即可。

? ? ? ? 所以整个顶层模块定义为keypad,当输入信号row,就能输出列col与code。

? ? ? ? 对于如何给keypad一个初始row值,可通过测试模块调用row_signal模块(模拟键盘产生信号模块)生成row,row_signal模块的输入信号为列信号col与key(键盘),通过col与key的逻辑关系输出信号row。

??????????row_signal 输入:key、col;输出:row;

? ? ? ? ? keypad?输入:row?;输出:code、col;? ? ?

?????????????????????????synchronizer输入:row;? ? ?输出:S_row

? ? ? ? ? ? ? ? ? ? ? ? ??hex_keypad_grayhill输入:S_row、row;输出:code、col;

????????所以进行测试时,先利用模拟按键信号发生器给定key值(字母),调用row_signal检测按键有效性并确定按键所处的row,就能给keypad传参,得到输出code(字母)。

????????

//顶层模块:
module keypad(clock,reset,row,code,vaild,col);
	input clock,reset;
	input [3:0] row;
	output [3:0] code;
	output vaild;
	output [3:0] col;
	wire s _row;
	hex_keypad_grayhill U1(.code(code),.col(col),.valid(valid),
													.row(row),.s row(s_row),.clock(clock),.reset(reset));
	synchronizer U2(.s_row(s_row),.row(row),.clock(clock),..reset(reset));
endmodule
//编码模块:
module hex_keypad_grayhill(code,col,valid,row,s_row,clock,reset);
	output[3:0] code;
	output valid;
	output[3:0] col;
	input[3:0] row;
	input s_row;
	input clock,reset;
	reg[3:0] col;
	reg[3:0] code;
	reg [5:0] state,next_state;
	parameter s_O=6'b000001,s_1=6'b000010,s_2=6'b000100;
	parameter s_3=6'b001000,s_4=6'b010000,s_5=6'b100000;
	assign valid=((state==s_1)||(state==s_2)||(state==s_3)||(state==s_4))&&row;
 always@(row or col)
		case({row,col})
			8'b0001_0001: code=0;
			8'b0001_0010: code=1;
			8'b0001_0100: code=2;
			8'b0001_1000: code=3;
			8'b0010_0001: code=4;
			8'b0010_0010: code=5;
			8'b0010_0100: code=6;
			8'b0010_1000: code=7;
			8'b0100_0001: code=8;
			8'b0100_0010: code=9;
			8'b0100_0100: code=10;   //A
			8'b0100_1000: code=11;	 //B
			8'b1000_0001: code=12;
			8'b1000_0010: code=13;
			8'b1000_0100: code=14;
			8'b1000_1000: code=15;
      default code=O;
		endcase
	always@(state or s_row or row) //next-state logic
		begin
			next_state=state; col=O;
			case(state)
					s_0:begin 
							col=15;
							if(s_row) next_state=s_1;
							end
					s_1:begin
							col=1;
							if(row) next_state=s_5;
							else next_state=s_2;
							end
					s_2:begin
							col=2;
							if(row) next_state=s_5;
							else next_state=s_3;
							end
					s_3:begin
							col=4;
							if(row) next_state=s_5;
							else next_state=s_4;
							end
					s_4:begin
						  col=8;
							if(row) next_state=s_5;
							else next_state=s_0;
							end
					s_5:begin
						  col=15;
							if(!row) next_state=s_0;
							end
			endcase
		end
	always@(posedge clock or posedge reset)
		if(reset)
			state<=s_o;
		else
			state<=next_state;
endmodule
//计算s_row模块
module synchronizer(s_row, row,clock,reset);
	output s_row;
	input [3:0] row;
	input clock,reset;
	reg a_row,s_row;
	always@(negedge clock or posedge reset)
	begin
		if(reset)
			begin
				a_row<=0;s_row<=O;
			end
		else 
			begin
			a_row<=(row[0]||[row[1]||row[2]||row[3]);
			s_row<=a_row;
			end
	end
endmodule
//模拟键盘产生信号
module row_signal(row,key.,col);output [3:0] row;
	input[15:0] key;
	input [3:0] col;
	reg[3:0] row;
	always@(key or col)
	begin
		row[0]=key[0]&&col[0]||key[1]&&col[1]||key[2]&&col[2]||key[3]&&col[3];
		row[1]=key[4]&&col[0]||key[5]&&col[1]||key[6]&&coI[2]||key[7]&&col[3];
		row[2]=key[8]&&col[0]||key[9]&&col[1]||key[10]&&col[2]||key[11]&&col[3];
		row[3]=key[12]&&col[0]||key[13]&&col[1]||key[14]&&col[2]||key[15]&&col[3];
	end
endmodule
//Testbench
module hex_keypad_grayhill_tb;
	wire [3:0] code;
	wire valid;
	wire [3:0] col;
	wire [3:0] row;
	reg clock;
	reg reset;
	reg [15:0] key;
	integer j,k;
	reg [39:0] pressed;
	parameter [39:0] key_0="key_o";
	parameter [39:0] key_1="key_1";
	parameter i39:0] key3="key_a";
	parameter [39:0] key_4="key_4";
	parameter [39:0] key_5="key_5";
	parameter [39:0] key_6="key_6";
	parameter [39:0] key_7="key_7";
	parameter [39:0] key_8="key_8";
	parameter [39:0] key_9="key_9";
	parameter [39:0] key_A="key_A";
	parameter [39:0] key_B="key_B";
	parameter [39:0] key_C="key_c";
	parameter [39:0] key_D="key_D";
	parameter [39:0] key_E="key_E";
	parameter [39:0] key_F="key_F";
	parameter [39:0] None="None";
	keypad U1(.clock(clock),.reset(reset), .row(row),.code(code),.vaild(vaild),.col(col));
//top module
	row_signal U2(.row(row),.key(key),.col(col));// Simulatesignal generation
	always@(key)
	begin
		case(key)
			16'h0000: pressed=None;
			16'h0001: pressed=key_0;
			16'h0002: pressed=key_1;
			16'h0004: pressed=key_2;
			16'h0008: pressed=key_3;
			16'h0010: pressed=key_4;
			16'h0020: pressed=key_5;
			16'h0040: pressed=key_6;
			16'h0080: pressed=key_7;
			16'h0100: pressed=key_8;
			16'h0200: pressed=key_9;
			16'h0400: pressed=key_A;
			16'h0800: pressed=key_B;
			16'h1000: pressed=key_C;
			16'h2000: pressed=key_D;
			16'h4000: pressed=key_E;
			16'h8000: pressed=key_F;
			default:pressed=None;
		endcase
	end
	initial #2000 $stop;
	initial 
		begin 
			clock=O;
			forever #5 clock=~clock;
		end
	initial
		begin 
			reset=1;
			#10 reset=0;
		end
	initial
		begin 
			for(k=O;k<=1;k=k+1)
			begin 
				key=0;
				#20 for(j=0;j<=16;j=j+1)
						begin
								#20 key[j]=1;
								#60 key=0;
							end
			end
		end
endmodule

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-10-08 20:58:04  更:2022-10-08 20:58:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 20:33:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码