首页 >> 大全

PAJ7620U2手势识别——读取手势数据寄存器数据与LED指示(完)

2023-10-15 大全 33 作者:考证青年

文章目录 总结

前言

在前面的教程中呢,小编带领各位读者完成了对所有寄存器的配置,本章教程只需要完成对手势数据寄存器里面的数据读出即可,因为我们只检测上、下、左、右挥手数据,因此用四个led灯作为挥手数据结果指示即可。本章教程是基于FPGA的手势识别的最后一章教程,具体实现方法请继续往下浏览。

一、如何读取手势数据寄存器数据?

在上一章教程中,我们采用的是突发读操作的时序图来对模块进行配置的,但是本章教程我们采用单次读操作对模块进行配置,单次读操作与突发读操作在前半段配置方式都是一样的,都是要指定读取的寄存器:

但是在后半段,连续读操作是从DATA状态,跳转到主机返回ACK响应,再从ACK响应跳转到DATA状态,结合官方数据手册:

我们发现,不管是采用哪种读方式,读取到数据后,都不会自动停下,这时候结合前面的数据手册,需要我们设置“中断”,当读取到的8位数据不为全0时,则中断读操作。但是呢,我们采用的是FPGA来配置这个模块,对数据的处理就简单得多,因此只需要检测出该模块数据变化,将变化的数据作为LED灯亮起的触发信号,触发以后LED灯在下次触发信号到来时,一直保持亮起即可。

这里呢,我们采用单次读操作,因为后续利用 Tap II触发波形信号的时候,可以观测到从IDLE到STOP一整个的执行周期,因为整个执行周期是非常短暂的,远远小于我们手势变化的时间,因此在这里使用单次读操作是完全可以采集到手势数据的变化情况。

二、配置步骤 1.模块状态转移图绘制

手势识别数据集_手势识别0—9数据集_

从图中可以看出,读取0x43寄存器数值状态转移图与读取0x00寄存器状态转移图绘制方式一样,因此各位读者如果学会了读取0x00寄存器数值操作后,本章教程对大家应该没有难度。

2.模块波形图绘制

从波形图可以看出,除了跳转信号外,我们还需要引入两路信号,一路是,这个信号主要是在DATA状态下寄存拼接的数据。第二路信号是,这个信号是在信号拼接完成后,读取DATA状态末尾拼接完成的数据。我们取信号低四位,这低四位数据,某位由0变化为1后,则代表上、下、左、右挥手动作被检测出来,我们利用这个变化来驱动LED灯亮起。因为驱动LED灯亮起非常简单,我们可以在顶层文件直接编写代码,就不再进行波形图的绘制。

3.上板验证

设置信号为触发条件:

使用连续触发,抓取到的信号波形如图所示:

我们发现,在DATA状态下,一直没有采集到数据,并且4个LED灯也一直保持高电平,即熄灭状态。我们向左挥手,抓取到的信号波形如下:

可以看到,LED灯已经发生了变化,第二位已经由高电平变为低电平,变亮了。但是为什么DATA状态下,SDA还是为低电平呢?因为我们使用的是连续触发,触发时间非常短暂,采集到数据以后,马上让LED灯点亮,在下次采集数据时,已经归零了,但是LED灯还维持在点亮状态没有改变。接下来,我们分别朝右、上、下挥手,抓取到的信号波形如下:

LED灯低三位数值都有变化,因此我们代码验证通过,且上板现象与预期一致(具体的实验现象各位读者可自行绑定引脚测试,在这里小编就不做演示了),整个工程验证通过。

4.参考代码(和)

module  i2c_ctrl
(input	wire			sys_clk		,input	wire			sys_rst_n	,input	wire	[23:0]	cfg_data	,input	wire			i2c_start	,input	wire	[5:0]	cfg_num		,output	wire			scl			,							output	reg				cfg_start	,output	reg				i2c_clk		,output	reg		[2:0]	mode		,output	reg		[7:0]	po_data		,inout	wire			sda
);localparam	CNT_CLK_MAX		=	5'd25	;
localparam	CNT_WAIT_MAX	=	10'd1000;
localparam	CNT_DELAY_MAX	=	10'd1000;
localparam	SLAVE_ID		=	7'h73	;
localparam	SENSOR_ADDR		=	8'hEF	;
localparam	DATA_ADDR		=	8'h43	;
localparam	IDLE		=	4'd0	,START		=	4'd1	,SLAVE_ADDR	=	4'd2	,WAIT		=	4'd3	,STOP		=	4'd4	,ACK_1		=	4'd5	,DEVICE_ADDR	=	4'd6	,ACK_2		=	4'd7	,DATA		=	4'd8	,ACK_3		=	4'd9	,NACK		=	4'd10	;reg		[4:0]	cnt_clk		;	//分频计数器
reg		[9:0]	cnt_wait	;	//开始状态等待1000us计数器
reg				skip_en_0	;	//唤醒状态跳转信号
reg				skip_en_1	;	//激活bank0跳转信号
reg				skip_en_2	;	//配置0x00寄存器状态跳转信号
reg				skip_en_3	;	//读取0x00寄存器状态跳转信号
reg				skip_en_4	;	//配置51个操作寄存器
reg				skip_en_5	;	//配置0x43寄存器状态跳转信号
reg				skip_en_6	;	//读取0x43寄存器状态跳转信号
reg				error_en	;	//读取出来的值不是0x20,错误信号
reg		[3:0]	n_state		;	//次态
reg		[3:0]	c_state		;	//现态	
reg		[1:0]	cnt_i2c_clk	;	//对i2c_clk分频时钟个数计数			
reg		[2:0]	cnt_bit		;	//对传输的8bit数据进行计数	
reg				i2c_scl		;	//就是SCL		
reg				i2c_sda		;	//SDA赋值给i2c_sda
reg		[9:0]	cnt_delay	;	//发送完指令后等待1000us计数器			
reg				i2c_end		;	//i2c结束信号	
reg		[7:0]	po_data_reg	;	//采集数据,拼接完成后赋值给po_data
reg		[7:0]	slave_addr	;	//不同模式下7'h73+1'bx
reg		[7:0]	device_addr	;	//不同模式下寄存器地址变化
reg		[7:0]	wr_data		;	//向地址写入的数据
reg		[7:0]	rec_data	;	//唤醒操作读取0x00寄存器数据寄存
reg				ack			;
wire			sda_in		;
wire			sda_en		;assign	scl		=	i2c_scl		;
assign	sda_in	=	sda			;	//从设备发送到主机的数据
assign	sda_en	=	((c_state == ACK_1)||(c_state == ACK_2)||(c_state == ACK_3)||((c_state == DATA)&&(mode == 3'd3))||((c_state == DATA)&&(mode == 3'd6))) ? 1'b0 : 1'b1		;	//主机控制sda有效
assign	sda		=	(sda_en == 1'b1) ? i2c_sda : 1'bz  ;always@(posedge i2c_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)cfg_start  <=  1'b0  ;elsecfg_start  <=  i2c_end  ;always@(*)case(mode)3'd0	:slave_addr	=	{SLAVE_ID,1'b0}  ;3'd1	:beginslave_addr  =	{SLAVE_ID,1'b0}  ;device_addr	=	SENSOR_ADDR  ;wr_data		=	8'h00  ;end3'd2	:beginslave_addr  =	{SLAVE_ID,1'b0}  ;device_addr	=	8'h00  ;		end3'd3	:slave_addr  = 	{SLAVE_ID,1'b1}  ;3'd4	:beginslave_addr	<=  cfg_data[23:16]  ;device_addr	<=  cfg_data[15:8]   ;wr_data	    <=  cfg_data[7:0]	 ;end3'd5	:begin	slave_addr  <=  {SLAVE_ID,1'b0}  ;device_addr	<=  DATA_ADDR  ;end3'd6	:slave_addr  =  {SLAVE_ID,1'b1}  ;default	:beginslave_addr	<=  8'd0 ;device_addr	<=  8'd0 ;wr_data	    <=  8'd0 ;		endendcase//
//分频计数器进行计数
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)cnt_clk  <=  5'd0  ;else  if(cnt_clk == CNT_CLK_MAX - 1'b1)  cnt_clk  <=  5'd0  ;elsecnt_clk  <=  cnt_clk + 1'b1  ;//产生i2c驱动时钟	
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)i2c_clk  <=  1'b0  ;else  if(cnt_clk == CNT_CLK_MAX - 1'b1)i2c_clk  <=  ~i2c_clk  ;elsei2c_clk  <=  i2c_clk  ;
////状态机第一段
always@(posedge i2c_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)c_state  <=  IDLE  ;elsec_state  <=  n_state  ;//状态机第二段
always@(*)case(c_state)IDLE		:	if((skip_en_0 == 1'b1)||(skip_en_1 == 1'b1)||(skip_en_2 == 1'b1)||(skip_en_3 == 1'b1)||(skip_en_4 == 1'b1)||(skip_en_5 == 1'b1)||(skip_en_6 == 1'b1))n_state  =  START  ;elsen_state  =  IDLE  ;START		:	if((skip_en_0 == 1'b1)||(skip_en_1 == 1'b1)||(skip_en_2 == 1'b1)||(skip_en_3 == 1'b1)||(skip_en_4 == 1'b1)||(skip_en_5 == 1'b1)||(skip_en_6 == 1'b1))n_state  =  SLAVE_ADDR  ;elsen_state  =  START  ;SLAVE_ADDR	:	if(skip_en_0 == 1'b1)n_state  =  WAIT  ;else  if((skip_en_1 == 1'b1)||(skip_en_2 == 1'b1)||(skip_en_3 == 1'b1)||(skip_en_4 == 1'b1)||(skip_en_5 == 1'b1)||(skip_en_6 == 1'b1))n_state  =  ACK_1  ;elsen_state  =  SLAVE_ADDR  ;ACK_1		:	if((skip_en_1 == 1'b1)||(skip_en_2 == 1'b1)||(skip_en_4 == 1'b1)||(skip_en_5 == 1'b1))n_state  =  DEVICE_ADDR  ;else  if((skip_en_3 == 1'b1)||(skip_en_6 == 1'b1))n_state  =  DATA  ;elsen_state  =  ACK_1  ;DEVICE_ADDR	:	if((skip_en_1 == 1'b1)||(skip_en_2 == 1'b1)||(skip_en_4 == 1'b1)||(skip_en_5 == 1'b1))n_state  =  ACK_2  ;elsen_state  =  DEVICE_ADDR  ;ACK_2		:	if((skip_en_1 == 1'b1)||(skip_en_4 == 1'b1))n_state  =  DATA  ;else  if((skip_en_2 == 1'b1)||(skip_en_5 == 1'b1))n_state  =  STOP  ;elsen_state  =  ACK_2  ;DATA		:	if((skip_en_1 == 1'b1)||(skip_en_4 == 1'b1))n_state  =  ACK_3  ;else  if((skip_en_3 == 1'b1)||(skip_en_6 == 1'b1))n_state  =  NACK  ;else  if(error_en == 1'b1)n_state  =  IDLE  ;elsen_state  =  DATA  ;ACK_3		:	if((skip_en_1 == 1'b1)||(skip_en_4 == 1'b1))n_state  =  STOP  ;elsen_state  =  ACK_3  ;WAIT		:	if(skip_en_0 == 1'b1)n_state  =  STOP  ;elsen_state  =  WAIT  ;NACK		:	if((skip_en_3 == 1'b1)||(skip_en_6 == 1'b1))n_state  =  STOP  ;elsen_state  =  NACK  ;STOP		:	if((skip_en_0 == 1'b1)||(skip_en_1 == 1'b1)||(skip_en_2 == 1'b1)||(skip_en_3 == 1'b1)||(skip_en_4 == 1'b1)||(skip_en_5 == 1'b1)||(skip_en_6 == 1'b1))n_state  =  IDLE  ;elsen_state  =  STOP  ;default		:	n_state  =  IDLE  ;endcase//状态机第三段	
always@(posedge i2c_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)begincnt_wait	<=  10'd0	;skip_en_0	<=  1'b0	;skip_en_1	<=  1'b0	;skip_en_2   <=  1'b0	;skip_en_3   <=  1'b0 	;skip_en_4   <=  1'b0	;skip_en_5   <=  1'b0	;skip_en_6	<=  1'b0	;error_en	<=  1'b0	;cnt_i2c_clk	<=  2'd0	;cnt_bit		<=  3'd0	;cnt_delay	<=  10'd0	;mode		<=  3'd0	;i2c_end		<=  1'b0	;endelsecase(c_state)IDLE		:begincnt_wait  <=  cnt_wait + 1'b1  ;if((cnt_wait == CNT_WAIT_MAX - 2'd2)&&(mode == 3'd0))skip_en_0  <=  1'b1  ;elseskip_en_0  <=  1'b0  ;if((cnt_wait == CNT_WAIT_MAX - 2'd2)&&(mode == 3'd1))skip_en_1  <=  1'b1  ;elseskip_en_1  <=  1'b0  ;	if((cnt_wait == CNT_WAIT_MAX - 2'd2)&&(mode == 3'd2))skip_en_2  <=  1'b1  ;elseskip_en_2  <=  1'b0  ;	if((cnt_wait == CNT_WAIT_MAX - 2'd2)&&(mode == 3'd3))skip_en_3  <=  1'b1  ;elseskip_en_3  <=  1'b0  ;	if((i2c_start == 1'b1)&&(mode == 3'd4))skip_en_4  <=  1'b1  ;elseskip_en_4  <=  1'b0  ;	if((cnt_wait == CNT_WAIT_MAX - 2'd2)&&(mode == 3'd5))skip_en_5  <=  1'b1  ;elseskip_en_5  <=  1'b0  ;if((cnt_wait == CNT_WAIT_MAX - 2'd2)&&(mode == 3'd6))skip_en_6  <=  1'b1  ;elseskip_en_6  <=  1'b0  ;								endSTART		:begincnt_i2c_clk  <=  cnt_i2c_clk + 1'b1  ;			if((cnt_i2c_clk == 2'd2)&&(mode == 3'd0))skip_en_0  <=  1'b1  ;elseskip_en_0  <=  1'b0  ;if((cnt_i2c_clk == 2'd2)&&(mode == 3'd1))skip_en_1  <=  1'b1  ;elseskip_en_1  <=  1'b0  ;if((cnt_i2c_clk == 2'd2)&&(mode == 3'd2))skip_en_2  <=  1'b1  ;elseskip_en_2  <=  1'b0  ;	if((cnt_i2c_clk == 2'd2)&&(mode == 3'd3))skip_en_3  <=  1'b1  ;elseskip_en_3  <=  1'b0  ;	if((cnt_i2c_clk == 2'd2)&&(mode == 3'd4))skip_en_4  <=  1'b1  ;elseskip_en_4  <=  1'b0  ;	if((cnt_i2c_clk == 2'd2)&&(mode == 3'd5))skip_en_5  <=  1'b1  ;elseskip_en_5  <=  1'b0  ;	if((cnt_i2c_clk == 2'd2)&&(mode == 3'd6))skip_en_6  <=  1'b1  ;elseskip_en_6  <=  1'b0  ;								endSLAVE_ADDR	:begincnt_i2c_clk  <=  cnt_i2c_clk + 1'b1  ;if(cnt_i2c_clk == 2'd3)cnt_bit  <=  cnt_bit + 1'b1  ;elsecnt_bit  <=  cnt_bit  ;			if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd0))skip_en_0  <=  1'b1  ;elseskip_en_0  <=  1'b0  ;if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd1))skip_en_1  <=  1'b1  ;elseskip_en_1  <=  1'b0  ;if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd2))skip_en_2  <=  1'b1  ;elseskip_en_2  <=  1'b0  ;if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd3))skip_en_3  <=  1'b1  ;elseskip_en_3  <=  1'b0  ;if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd4))skip_en_4  <=  1'b1  ;elseskip_en_4  <=  1'b0  ;	if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd5))skip_en_5  <=  1'b1  ;elseskip_en_5  <=  1'b0  ;	if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd6))skip_en_6  <=  1'b1  ;elseskip_en_6  <=  1'b0  ;									endACK_1		:begincnt_i2c_clk  <=  cnt_i2c_clk + 1'b1  ;if((cnt_i2c_clk == 2'd2)&&(mode == 3'd1)&&(ack == 1'b1))skip_en_1  <=  1'b1  ;elseskip_en_1  <=  1'b0  ;if((cnt_i2c_clk == 2'd2)&&(mode == 3'd2)&&(ack == 1'b1))skip_en_2  <=  1'b1  ;elseskip_en_2  <=  1'b0  ;if((cnt_i2c_clk == 2'd2)&&(mode == 3'd3)&&(ack == 1'b1))skip_en_3  <=  1'b1  ;elseskip_en_3  <=  1'b0  ;	if((cnt_i2c_clk == 2'd2)&&(mode == 3'd4)&&(ack == 1'b1))skip_en_4  <=  1'b1  ;elseskip_en_4  <=  1'b0  ;	if((cnt_i2c_clk == 2'd2)&&(mode == 3'd5)&&(ack == 1'b1))skip_en_5  <=  1'b1  ;elseskip_en_5  <=  1'b0  ;	if((cnt_i2c_clk == 2'd2)&&(mode == 3'd6)&&(ack == 1'b1))skip_en_6  <=  1'b1  ;elseskip_en_6  <=  1'b0  ;									endDEVICE_ADDR	:begincnt_i2c_clk  <=  cnt_i2c_clk + 1'b1  ;if(cnt_i2c_clk == 2'd3)cnt_bit  <=  cnt_bit + 1'b1  ;elsecnt_bit  <=  cnt_bit  ;								if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd1))skip_en_1  <=  1'b1  ;elseskip_en_1  <=  1'b0  ;if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd2))skip_en_2  <=  1'b1  ;elseskip_en_2  <=  1'b0  ;if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd4))skip_en_4  <=  1'b1  ;elseskip_en_4  <=  1'b0  ;	if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd5))skip_en_5  <=  1'b1  ;elseskip_en_5  <=  1'b0  ;								endACK_2		:begincnt_i2c_clk  <=  cnt_i2c_clk + 1'b1  ;if((cnt_i2c_clk == 2'd2)&&(mode == 3'd1)&&(ack == 1'b1))skip_en_1  <=  1'b1  ;elseskip_en_1  <=  1'b0  ;	if((cnt_i2c_clk == 2'd2)&&(mode == 3'd2)&&(ack == 1'b1))skip_en_2  <=  1'b1  ;elseskip_en_2  <=  1'b0  ;	if((cnt_i2c_clk == 2'd2)&&(mode == 3'd4)&&(ack == 1'b1))skip_en_4  <=  1'b1  ;elseskip_en_4  <=  1'b0  ;if((cnt_i2c_clk == 2'd2)&&(mode == 3'd5)&&(ack == 1'b1))skip_en_5  <=  1'b1  ;elseskip_en_5  <=  1'b0  ;								endDATA		:begincnt_i2c_clk  <=  cnt_i2c_clk + 1'b1  ;if(cnt_i2c_clk == 2'd3)cnt_bit  <=  cnt_bit + 1'b1  ;elsecnt_bit  <=  cnt_bit  ;				if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd1))skip_en_1  <=  1'b1  ;elseskip_en_1  <=  1'b0  ;	if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd3)&&(rec_data == 8'h20))skip_en_3  <=  1'b1  ;elseskip_en_3  <=  1'b0  ;	if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd4))skip_en_4  <=  1'b1  ;elseskip_en_4  <=  1'b0  ;if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd6))skip_en_6  <=  1'b1  ;elseskip_en_6  <=  1'b0  ;								if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd3)&&(rec_data != 8'h20))beginerror_en  <=  1'b1  ;mode	  <=  3'd0  ;endelsebeginerror_en  <=  1'b0  ;mode	  <=  mode  ;end							endACK_3		:begincnt_i2c_clk  <=  cnt_i2c_clk + 1'b1  ;if((cnt_i2c_clk == 2'd2)&&(mode == 3'd1)&&(ack == 1'b1))skip_en_1  <=  1'b1  ;elseskip_en_1  <=  1'b0  ;if((cnt_i2c_clk == 2'd2)&&(mode == 3'd4)&&(ack == 1'b1))skip_en_4  <=  1'b1  ;elseskip_en_4  <=  1'b0  ;								end						 WAIT		:beginif((cnt_delay == CNT_DELAY_MAX - 2'd2)&&(mode == 3'd0))skip_en_0  <=  1'b1  ;elseskip_en_0  <=  1'b0  ;cnt_delay  <=  cnt_delay + 1'b1  ;endNACK		:begincnt_i2c_clk  <=  cnt_i2c_clk + 1'b1  ;if((cnt_i2c_clk == 2'd2)&&(mode == 3'd3)&&(ack == 1'b1))skip_en_3  <=  1'b1  ;elseskip_en_3  <=  1'b0  ;	if((cnt_i2c_clk == 2'd2)&&(mode == 3'd6)&&(ack == 1'b1))skip_en_6  <=  1'b1  ;elseskip_en_6  <=  1'b0  ;								endSTOP		:begincnt_i2c_clk  <=  cnt_i2c_clk + 1'b1  ;			if((cnt_i2c_clk == 2'd2)&&(mode == 3'd0))skip_en_0  <=  1'b1  ;elseskip_en_0  <=  1'b0  ;if((cnt_i2c_clk == 2'd2)&&(mode == 3'd1))skip_en_1  <=  1'b1  ;elseskip_en_1  <=  1'b0  ;if((cnt_i2c_clk == 2'd2)&&(mode == 3'd2))skip_en_2  <=  1'b1  ;elseskip_en_2  <=  1'b0  ;if((cnt_i2c_clk == 2'd2)&&(mode == 3'd3))skip_en_3  <=  1'b1  ;elseskip_en_3  <=  1'b0  ;	if((cnt_i2c_clk == 2'd2)&&(mode == 3'd4))skip_en_4  <=  1'b1  ;elseskip_en_4  <=  1'b0  ;if((cnt_i2c_clk == 2'd2)&&(mode == 3'd5))skip_en_5  <=  1'b1  ;elseskip_en_5  <=  1'b0  ;	if((cnt_i2c_clk == 2'd2)&&(mode == 3'd6))skip_en_6  <=  1'b1  ;elseskip_en_6  <=  1'b0  ;									if(cnt_i2c_clk == 2'd2)i2c_end  <=  1'b1  ;elsei2c_end  <=  1'b0  ;						    if((i2c_end == 1'b1)&&(mode <= 3'd3))mode  <=  mode + 1'b1  ;else  if((mode == 3'd4)&&(i2c_end == 1'b1)&&(cfg_num == 6'd51))mode  <=  mode + 1'b1  ;else  if((i2c_end == 1'b1)&&(mode == 3'd5))mode  <=  mode + 1'b1  ;elsemode  <=  mode  ;enddefault		:begincnt_wait  	<=  10'd0   ;skip_en_0	<=  1'b0	;skip_en_1	<=  1'b0	;skip_en_2   <=  1'b0	;skip_en_3   <=  1'b0	;skip_en_4   <=  1'b0	;skip_en_5   <=  1'b0	;skip_en_6   <=  1'b0	;error_en	<=  1'b0	;cnt_i2c_clk	<=  2'd0	;cnt_bit		<=  3'd0	;cnt_delay	<=  10'd0	;mode		<=  mode	;i2c_end		<=  1'b0	;endendcasealways@(posedge i2c_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)rec_data  <=  8'd0  ;elsecase(c_state)DATA	:	if((mode == 3'd3)&&(cnt_i2c_clk == 2'd1))rec_data  <=  {rec_data[6:0],sda_in}  ;elserec_data  <=  rec_data  ;default	:	rec_data  <=  8'd0  ;endcasealways@(posedge i2c_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)po_data_reg  <=  8'd0  ;else  case(c_state)DATA	:	if((mode == 3'd6)&&(cnt_i2c_clk == 2'd1))po_data_reg  <=  {po_data_reg[6:0],sda_in}  ;elsepo_data_reg  <=  po_data_reg  ;default	:	po_data_reg  <=  po_data_reg  ;endcasealways@(posedge i2c_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)po_data  <=  8'd0  ;else  if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd6))po_data  <=  po_data_reg  ;elsepo_data  <=  po_data  ;always@(*)case(c_state)ACK_1,ACK_2,ACK_3  :  ack  =  ~sda_in  ;NACK			   :  ack  =  i2c_sda  ;default	:	ack  =  1'b0  ;endcasealways@(*)case(c_state)IDLE		:	i2c_scl  =  1'b1  ;START		:	if(cnt_i2c_clk == 2'd3)i2c_scl  =  1'b0  ;elsei2c_scl  =  1'b1  ;SLAVE_ADDR,ACK_1,DEVICE_ADDR,ACK_2,DATA,ACK_3,NACK:	if((cnt_i2c_clk == 2'd0)||(cnt_i2c_clk == 2'd3))i2c_scl  =  1'b0  ;elsei2c_scl  =  1'b1  ;WAIT		:	i2c_scl  =  1'b0  ;STOP		:	if(cnt_i2c_clk == 2'd0)i2c_scl  =  1'b0  ;elsei2c_scl  =  1'b1  ;default		:	i2c_scl  =  1'b1  ;endcasealways@(*)case(c_state)IDLE		:	i2c_sda  =  1'b1  ;START		:	if(cnt_i2c_clk == 2'd0)i2c_sda  =  1'b1  ;elsei2c_sda  =  1'b0  ;SLAVE_ADDR	:	i2c_sda  =  slave_addr[7 - cnt_bit]  ;ACK_1,ACK_2,ACK_3,:	i2c_sda	 =  1'b0  ;NACK		:	i2c_sda  =  1'b1  ;DEVICE_ADDR	:	i2c_sda  =  device_addr[7 - cnt_bit]  ;DATA		:	i2c_sda  =  wr_data[7 - cnt_bit]  ;WAIT		:	i2c_sda  =  1'b0  ;STOP		:	if((cnt_i2c_clk == 2'd0)||(cnt_i2c_clk == 2'd1))i2c_sda  <=  1'b0  ;elsei2c_sda  <=  1'b1  ;default		:	i2c_sda  <=  1'b1  ;endcaseendmodule

module  paj7620_top
(	input	wire			sys_clk		,input	wire			sys_rst_n	,output	wire			scl			,output	reg		[3:0]	led			,inout	wire			sda	
);wire	[23:0]	cfg_data	;
wire			i2c_start	;
wire	[5:0]	cfg_num		;
wire			i2c_clk		;
wire	[2:0]	mode		;
wire			cfg_start	;
wire	[7:0]	po_data		;always@(posedge i2c_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)led  <=  4'b1111  ;else  if(po_data[3:0] == 4'b0001)led  <=  4'b1110  ;else  if(po_data[3:0] == 4'b0010)led  <=  4'b1101  ;else  if(po_data[3:0] == 4'b0100)led  <=  4'b1011  ;	else  if(po_data[3:0] == 4'b1000)led  <=  4'b0111  ;elseled  <=  led  ;i2c_ctrl  i2c_ctrl_inst
(.sys_clk	(sys_clk	)	,.sys_rst_n	(sys_rst_n	)	,.cfg_data	(cfg_data	)	,.i2c_start	(i2c_start	)	,.cfg_num	(cfg_num	)	,.scl		(scl		)	,.i2c_clk	(i2c_clk	)	,.mode		(mode		)	,.cfg_start	(cfg_start	)	,.po_data	(po_data	)	,.sda        (sda        )
);paj7620_cfg  paj7620_cfg_inst
(.i2c_clk	(i2c_clk	),.sys_rst_n	(sys_rst_n	),.cfg_start	(cfg_start	),.mode		(mode		),.cfg_data	(cfg_data	),.cfg_num	(cfg_num	),.i2c_start  (i2c_start  )
);endmodule

总结

小编在这里用了7章的教程,带领各位读者完成了对手势识别模块上、下、左、右的识别配置,感谢各位读者的支持,后续将为大家带来4x4矩阵键盘密码锁工程的实现,敬请期待。

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了