国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

PAJ7620U2手勢識別——讀取手勢數(shù)據(jù)寄存器數(shù)據(jù)與LED顯示(完)

這篇具有很好參考價值的文章主要介紹了PAJ7620U2手勢識別——讀取手勢數(shù)據(jù)寄存器數(shù)據(jù)與LED顯示(完)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。


前言

??在前面的教程中呢,小編帶領(lǐng)各位讀者完成了對所有寄存器的配置,本章教程只需要完成對手勢數(shù)據(jù)寄存器里面的數(shù)據(jù)讀出即可,因為我們只檢測上、下、左、右揮手數(shù)據(jù),因此用四個led燈作為揮手數(shù)據(jù)結(jié)果指示即可。本章教程是基于FPGA的PAJ7620U2手勢識別的最后一章教程,具體實現(xiàn)方法請繼續(xù)往下瀏覽。

一、如何讀取手勢數(shù)據(jù)寄存器數(shù)據(jù)?

??在上一章教程中,我們采用的是突發(fā)讀操作的時序圖來對模塊進行配置的,但是本章教程我們采用單次讀操作對模塊進行配置,單次讀操作與突發(fā)讀操作在前半段配置方式都是一樣的,都是要指定讀取的寄存器:
PAJ7620U2手勢識別——讀取手勢數(shù)據(jù)寄存器數(shù)據(jù)與LED顯示(完)
??但是在后半段,連續(xù)讀操作是從DATA狀態(tài),跳轉(zhuǎn)到主機返回ACK響應(yīng),再從ACK響應(yīng)跳轉(zhuǎn)到DATA狀態(tài),結(jié)合官方數(shù)據(jù)手冊:
PAJ7620U2手勢識別——讀取手勢數(shù)據(jù)寄存器數(shù)據(jù)與LED顯示(完)
??我們發(fā)現(xiàn),不管是采用哪種讀方式,讀取到數(shù)據(jù)后,都不會自動停下,這時候結(jié)合前面的數(shù)據(jù)手冊,需要我們設(shè)置“中斷”,當(dāng)讀取到的8位數(shù)據(jù)不為全0時,則中斷讀操作。但是呢,我們采用的是FPGA來配置這個模塊,對數(shù)據(jù)的處理就簡單得多,因此只需要檢測出該模塊數(shù)據(jù)變化,將變化的數(shù)據(jù)作為LED燈亮起的觸發(fā)信號,觸發(fā)以后LED燈在下次觸發(fā)信號到來時,一直保持亮起即可。
??這里呢,我們采用單次讀操作,因為后續(xù)利用Singal Tap II觸發(fā)波形信號的時候,可以觀測到從IDLE到STOP一整個的執(zhí)行周期,因為整個執(zhí)行周期是非常短暫的,遠遠小于我們手勢變化的時間,因此在這里使用單次讀操作是完全可以采集到手勢數(shù)據(jù)的變化情況。

二、配置步驟

1.模塊狀態(tài)轉(zhuǎn)移圖繪制

PAJ7620U2手勢識別——讀取手勢數(shù)據(jù)寄存器數(shù)據(jù)與LED顯示(完)
??從圖中可以看出,讀取0x43寄存器數(shù)值狀態(tài)轉(zhuǎn)移圖與讀取0x00寄存器狀態(tài)轉(zhuǎn)移圖繪制方式一樣,因此各位讀者如果學(xué)會了讀取0x00寄存器數(shù)值操作后,本章教程對大家應(yīng)該沒有難度。

2.模塊波形圖繪制

PAJ7620U2手勢識別——讀取手勢數(shù)據(jù)寄存器數(shù)據(jù)與LED顯示(完)
PAJ7620U2手勢識別——讀取手勢數(shù)據(jù)寄存器數(shù)據(jù)與LED顯示(完)
??從波形圖可以看出,除了跳轉(zhuǎn)信號外,我們還需要引入兩路信號,一路是po_data_reg,這個信號主要是在DATA狀態(tài)下寄存拼接的數(shù)據(jù)。第二路信號是po_data,這個信號是在po_data_reg信號拼接完成后,讀取DATA狀態(tài)末尾拼接完成的數(shù)據(jù)。我們?nèi)o_data信號低四位,這低四位數(shù)據(jù),某位由0變化為1后,則代表上、下、左、右揮手動作被檢測出來,我們利用這個變化來驅(qū)動LED燈亮起。因為驅(qū)動LED燈亮起非常簡單,我們可以在頂層文件直接編寫代碼,就不再進行波形圖的繪制。

3.上板驗證

??設(shè)置skip_en_6信號為觸發(fā)條件:
PAJ7620U2手勢識別——讀取手勢數(shù)據(jù)寄存器數(shù)據(jù)與LED顯示(完)
??使用連續(xù)觸發(fā),抓取到的信號波形如圖所示:
PAJ7620U2手勢識別——讀取手勢數(shù)據(jù)寄存器數(shù)據(jù)與LED顯示(完)
??我們發(fā)現(xiàn),在DATA狀態(tài)下,一直沒有采集到數(shù)據(jù),并且4個LED燈也一直保持高電平,即熄滅狀態(tài)。我們向左揮手,抓取到的信號波形如下:
PAJ7620U2手勢識別——讀取手勢數(shù)據(jù)寄存器數(shù)據(jù)與LED顯示(完)
??可以看到,LED燈已經(jīng)發(fā)生了變化,第二位已經(jīng)由高電平變?yōu)榈碗娖剑兞亮?。但是為什么DATA狀態(tài)下,SDA還是為低電平呢?因為我們使用的是連續(xù)觸發(fā),觸發(fā)時間非常短暫,po_data采集到數(shù)據(jù)以后,馬上讓LED燈點亮,在下次采集數(shù)據(jù)時,po_data已經(jīng)歸零了,但是LED燈還維持在點亮狀態(tài)沒有改變。接下來,我們分別朝右、上、下?lián)]手,抓取到的信號波形如下:
PAJ7620U2手勢識別——讀取手勢數(shù)據(jù)寄存器數(shù)據(jù)與LED顯示(完)
PAJ7620U2手勢識別——讀取手勢數(shù)據(jù)寄存器數(shù)據(jù)與LED顯示(完)

PAJ7620U2手勢識別——讀取手勢數(shù)據(jù)寄存器數(shù)據(jù)與LED顯示(完)
??LED燈低三位數(shù)值都有變化,因此我們代碼驗證通過,且上板現(xiàn)象與預(yù)期一致(具體的實驗現(xiàn)象各位讀者可自行綁定引腳測試,在這里小編就不做演示了),整個工程驗證通過。

4.參考代碼(i2c_ctrl和paj7620_top)

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		;	//分頻計數(shù)器
reg		[9:0]	cnt_wait	;	//開始狀態(tài)等待1000us計數(shù)器
reg				skip_en_0	;	//喚醒狀態(tài)跳轉(zhuǎn)信號
reg				skip_en_1	;	//激活bank0跳轉(zhuǎn)信號
reg				skip_en_2	;	//配置0x00寄存器狀態(tài)跳轉(zhuǎn)信號
reg				skip_en_3	;	//讀取0x00寄存器狀態(tài)跳轉(zhuǎn)信號
reg				skip_en_4	;	//配置51個操作寄存器
reg				skip_en_5	;	//配置0x43寄存器狀態(tài)跳轉(zhuǎn)信號
reg				skip_en_6	;	//讀取0x43寄存器狀態(tài)跳轉(zhuǎn)信號
reg				error_en	;	//讀取出來的值不是0x20,錯誤信號
reg		[3:0]	n_state		;	//次態(tài)
reg		[3:0]	c_state		;	//現(xiàn)態(tài)	
reg		[1:0]	cnt_i2c_clk	;	//對i2c_clk分頻時鐘個數(shù)計數(shù)			
reg		[2:0]	cnt_bit		;	//對傳輸?shù)?bit數(shù)據(jù)進行計數(shù)	
reg				i2c_scl		;	//就是SCL		
reg				i2c_sda		;	//SDA賦值給i2c_sda
reg		[9:0]	cnt_delay	;	//發(fā)送完指令后等待1000us計數(shù)器			
reg				i2c_end		;	//i2c結(jié)束信號	
reg		[7:0]	po_data_reg	;	//采集數(shù)據(jù),拼接完成后賦值給po_data
reg		[7:0]	slave_addr	;	//不同模式下7'h73+1'bx
reg		[7:0]	device_addr	;	//不同模式下寄存器地址變化
reg		[7:0]	wr_data		;	//向地址寫入的數(shù)據(jù)
reg		[7:0]	rec_data	;	//喚醒操作讀取0x00寄存器數(shù)據(jù)寄存
reg				ack			;
wire			sda_in		;
wire			sda_en		;

assign	scl		=	i2c_scl		;
assign	sda_in	=	sda			;	//從設(shè)備發(fā)送到主機的數(shù)據(jù)
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  ;
	else
		cfg_start  <=  i2c_end  ;

always@(*)
	case(mode)
		3'd0	:slave_addr	=	{SLAVE_ID,1'b0}  ;
		3'd1	:begin
					slave_addr  =	{SLAVE_ID,1'b0}  ;
					device_addr	=	SENSOR_ADDR  ;
					wr_data		=	8'h00  ;
				 end
		3'd2	:begin
					slave_addr  =	{SLAVE_ID,1'b0}  ;
					device_addr	=	8'h00  ;		
				 end
		3'd3	:slave_addr  = 	{SLAVE_ID,1'b1}  ;
		3'd4	:begin
					slave_addr	<=  cfg_data[23:16]  ;
					device_addr	<=  cfg_data[15:8]   ;
					wr_data	    <=  cfg_data[7:0]	 ;
				 end
		3'd5	:begin	
					slave_addr  <=  {SLAVE_ID,1'b0}  ;
					device_addr	<=  DATA_ADDR  ;
				 end
		3'd6	:slave_addr  =  {SLAVE_ID,1'b1}  ;
		default	:begin
					slave_addr	<=  8'd0 ;
					device_addr	<=  8'd0 ;
					wr_data	    <=  8'd0 ;		
				 end
    endcase

//
//分頻計數(shù)器進行計數(shù)
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  ;
	else
		cnt_clk  <=  cnt_clk + 1'b1  ;
	
//產(chǎn)生i2c驅(qū)動時鐘	
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  ;
	else
		i2c_clk  <=  i2c_clk  ;
//

//狀態(tài)機第一段
always@(posedge i2c_clk or negedge sys_rst_n)
	if(sys_rst_n == 1'b0)
		c_state  <=  IDLE  ;
	else
		c_state  <=  n_state  ;
		
//狀態(tài)機第二段
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  ;
						else
							n_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  ;
						else
							n_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  ;
						else
							n_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  ;
						else
							n_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  ;
						else
							n_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  ;
						else
							n_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  ;
						else
							n_state  =  DATA  ;
		ACK_3		:	if((skip_en_1 == 1'b1)||(skip_en_4 == 1'b1))
							n_state  =  STOP  ;
						else
							n_state  =  ACK_3  ;
		WAIT		:	if(skip_en_0 == 1'b1)
							n_state  =  STOP  ;
						else
							n_state  =  WAIT  ;
		NACK		:	if((skip_en_3 == 1'b1)||(skip_en_6 == 1'b1))
							n_state  =  STOP  ;
						else
							n_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  ;
						else
							n_state  =  STOP  ;
		default		:	n_state  =  IDLE  ;
    endcase

//狀態(tài)機第三段	
always@(posedge i2c_clk or negedge sys_rst_n)
	if(sys_rst_n == 1'b0)
		begin
			cnt_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	;
		end
	else
		case(c_state)
			IDLE		:begin
							cnt_wait  <=  cnt_wait + 1'b1  ;
							if((cnt_wait == CNT_WAIT_MAX - 2'd2)&&(mode == 3'd0))
								skip_en_0  <=  1'b1  ;
							else
								skip_en_0  <=  1'b0  ;
							if((cnt_wait == CNT_WAIT_MAX - 2'd2)&&(mode == 3'd1))
								skip_en_1  <=  1'b1  ;
							else
								skip_en_1  <=  1'b0  ;	
							if((cnt_wait == CNT_WAIT_MAX - 2'd2)&&(mode == 3'd2))
								skip_en_2  <=  1'b1  ;
							else
								skip_en_2  <=  1'b0  ;	
							if((cnt_wait == CNT_WAIT_MAX - 2'd2)&&(mode == 3'd3))
								skip_en_3  <=  1'b1  ;
							else
								skip_en_3  <=  1'b0  ;	
							if((i2c_start == 1'b1)&&(mode == 3'd4))
								skip_en_4  <=  1'b1  ;
							else
								skip_en_4  <=  1'b0  ;	
							if((cnt_wait == CNT_WAIT_MAX - 2'd2)&&(mode == 3'd5))
								skip_en_5  <=  1'b1  ;
							else
								skip_en_5  <=  1'b0  ;
							if((cnt_wait == CNT_WAIT_MAX - 2'd2)&&(mode == 3'd6))
								skip_en_6  <=  1'b1  ;
							else
								skip_en_6  <=  1'b0  ;								
						 end
			START		:begin
							cnt_i2c_clk  <=  cnt_i2c_clk + 1'b1  ;			
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd0))
								skip_en_0  <=  1'b1  ;
							else
								skip_en_0  <=  1'b0  ;
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd1))
								skip_en_1  <=  1'b1  ;
							else
								skip_en_1  <=  1'b0  ;
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd2))
								skip_en_2  <=  1'b1  ;
							else
								skip_en_2  <=  1'b0  ;	
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd3))
								skip_en_3  <=  1'b1  ;
							else
								skip_en_3  <=  1'b0  ;	
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd4))
								skip_en_4  <=  1'b1  ;
							else
								skip_en_4  <=  1'b0  ;	
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd5))
								skip_en_5  <=  1'b1  ;
							else
								skip_en_5  <=  1'b0  ;	
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd6))
								skip_en_6  <=  1'b1  ;
							else
								skip_en_6  <=  1'b0  ;								
						 end
			SLAVE_ADDR	:begin
							cnt_i2c_clk  <=  cnt_i2c_clk + 1'b1  ;
							if(cnt_i2c_clk == 2'd3)
								cnt_bit  <=  cnt_bit + 1'b1  ;
							else
								cnt_bit  <=  cnt_bit  ;			
							if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd0))
								skip_en_0  <=  1'b1  ;
							else
								skip_en_0  <=  1'b0  ;
							if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd1))
								skip_en_1  <=  1'b1  ;
							else
								skip_en_1  <=  1'b0  ;
							if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd2))
								skip_en_2  <=  1'b1  ;
							else
								skip_en_2  <=  1'b0  ;
							if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd3))
								skip_en_3  <=  1'b1  ;
							else
								skip_en_3  <=  1'b0  ;
							if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd4))
								skip_en_4  <=  1'b1  ;
							else
								skip_en_4  <=  1'b0  ;	
							if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd5))
								skip_en_5  <=  1'b1  ;
							else
								skip_en_5  <=  1'b0  ;	
							if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd6))
								skip_en_6  <=  1'b1  ;
							else
								skip_en_6  <=  1'b0  ;									
						 end
			ACK_1		:begin
							cnt_i2c_clk  <=  cnt_i2c_clk + 1'b1  ;
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd1)&&(ack == 1'b1))
								skip_en_1  <=  1'b1  ;
							else
								skip_en_1  <=  1'b0  ;
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd2)&&(ack == 1'b1))
								skip_en_2  <=  1'b1  ;
							else
								skip_en_2  <=  1'b0  ;
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd3)&&(ack == 1'b1))
								skip_en_3  <=  1'b1  ;
							else
								skip_en_3  <=  1'b0  ;	
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd4)&&(ack == 1'b1))
								skip_en_4  <=  1'b1  ;
							else
								skip_en_4  <=  1'b0  ;	
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd5)&&(ack == 1'b1))
								skip_en_5  <=  1'b1  ;
							else
								skip_en_5  <=  1'b0  ;	
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd6)&&(ack == 1'b1))
								skip_en_6  <=  1'b1  ;
							else
								skip_en_6  <=  1'b0  ;									
						 end
			DEVICE_ADDR	:begin
							cnt_i2c_clk  <=  cnt_i2c_clk + 1'b1  ;
							if(cnt_i2c_clk == 2'd3)
								cnt_bit  <=  cnt_bit + 1'b1  ;
							else
								cnt_bit  <=  cnt_bit  ;								
							if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd1))
								skip_en_1  <=  1'b1  ;
							else
								skip_en_1  <=  1'b0  ;
							if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd2))
								skip_en_2  <=  1'b1  ;
							else
								skip_en_2  <=  1'b0  ;
							if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd4))
								skip_en_4  <=  1'b1  ;
							else
								skip_en_4  <=  1'b0  ;	
							if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd5))
								skip_en_5  <=  1'b1  ;
							else
								skip_en_5  <=  1'b0  ;								
						 end
			ACK_2		:begin
							cnt_i2c_clk  <=  cnt_i2c_clk + 1'b1  ;
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd1)&&(ack == 1'b1))
								skip_en_1  <=  1'b1  ;
							else
								skip_en_1  <=  1'b0  ;	
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd2)&&(ack == 1'b1))
								skip_en_2  <=  1'b1  ;
							else
								skip_en_2  <=  1'b0  ;	
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd4)&&(ack == 1'b1))
								skip_en_4  <=  1'b1  ;
							else
								skip_en_4  <=  1'b0  ;
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd5)&&(ack == 1'b1))
								skip_en_5  <=  1'b1  ;
							else
								skip_en_5  <=  1'b0  ;								
						 end
			DATA		:begin
							cnt_i2c_clk  <=  cnt_i2c_clk + 1'b1  ;
							if(cnt_i2c_clk == 2'd3)
								cnt_bit  <=  cnt_bit + 1'b1  ;
							else
								cnt_bit  <=  cnt_bit  ;				
							if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd1))
								skip_en_1  <=  1'b1  ;
							else
								skip_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  ;
							else
								skip_en_3  <=  1'b0  ;	
							if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd4))
								skip_en_4  <=  1'b1  ;
							else
								skip_en_4  <=  1'b0  ;
							if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd6))
								skip_en_6  <=  1'b1  ;
							else
								skip_en_6  <=  1'b0  ;								
							if((cnt_i2c_clk == 2'd2)&&(cnt_bit == 3'd7)&&(mode == 3'd3)&&(rec_data != 8'h20))
								begin
									error_en  <=  1'b1  ;
									mode	  <=  3'd0  ;
								end
							else
								begin
									error_en  <=  1'b0  ;
									mode	  <=  mode  ;
								end							
						 end
			ACK_3		:begin
							cnt_i2c_clk  <=  cnt_i2c_clk + 1'b1  ;
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd1)&&(ack == 1'b1))
								skip_en_1  <=  1'b1  ;
							else
								skip_en_1  <=  1'b0  ;
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd4)&&(ack == 1'b1))
								skip_en_4  <=  1'b1  ;
							else
								skip_en_4  <=  1'b0  ;								
						 end						 
			WAIT		:begin
							if((cnt_delay == CNT_DELAY_MAX - 2'd2)&&(mode == 3'd0))
								skip_en_0  <=  1'b1  ;
							else
								skip_en_0  <=  1'b0  ;
							cnt_delay  <=  cnt_delay + 1'b1  ;
						 end
			NACK		:begin
							cnt_i2c_clk  <=  cnt_i2c_clk + 1'b1  ;
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd3)&&(ack == 1'b1))
								skip_en_3  <=  1'b1  ;
							else
								skip_en_3  <=  1'b0  ;	
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd6)&&(ack == 1'b1))
								skip_en_6  <=  1'b1  ;
							else
								skip_en_6  <=  1'b0  ;								
						 end
			STOP		:begin
							cnt_i2c_clk  <=  cnt_i2c_clk + 1'b1  ;			
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd0))
								skip_en_0  <=  1'b1  ;
							else
								skip_en_0  <=  1'b0  ;
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd1))
								skip_en_1  <=  1'b1  ;
							else
								skip_en_1  <=  1'b0  ;
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd2))
								skip_en_2  <=  1'b1  ;
							else
								skip_en_2  <=  1'b0  ;
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd3))
								skip_en_3  <=  1'b1  ;
							else
								skip_en_3  <=  1'b0  ;	
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd4))
								skip_en_4  <=  1'b1  ;
							else
								skip_en_4  <=  1'b0  ;
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd5))
								skip_en_5  <=  1'b1  ;
							else
								skip_en_5  <=  1'b0  ;	
							if((cnt_i2c_clk == 2'd2)&&(mode == 3'd6))
								skip_en_6  <=  1'b1  ;
							else
								skip_en_6  <=  1'b0  ;									
							if(cnt_i2c_clk == 2'd2)
								i2c_end  <=  1'b1  ;
							else
								i2c_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  ;
							else
								mode  <=  mode  ;
						 end
			default		:begin
							cnt_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	;
						 end
		endcase
		
always@(posedge i2c_clk or negedge sys_rst_n)
	if(sys_rst_n == 1'b0)
		rec_data  <=  8'd0  ;
	else
		case(c_state)
			DATA	:	if((mode == 3'd3)&&(cnt_i2c_clk == 2'd1))
							rec_data  <=  {rec_data[6:0],sda_in}  ;
						else
							rec_data  <=  rec_data  ;
			default	:	rec_data  <=  8'd0  ;
		endcase
		
always@(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}  ;
						else
							po_data_reg  <=  po_data_reg  ;
			default	:	po_data_reg  <=  po_data_reg  ;
		endcase
		
always@(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  ;
	else
		po_data  <=  po_data  ;
		
always@(*)
	case(c_state)
		ACK_1,ACK_2,ACK_3  :  ack  =  ~sda_in  ;
		NACK			   :  ack  =  i2c_sda  ;
		default	:	ack  =  1'b0  ;
	endcase
		
always@(*)
	case(c_state)
		IDLE		:	i2c_scl  =  1'b1  ;
		START		:	if(cnt_i2c_clk == 2'd3)
							i2c_scl  =  1'b0  ;
						else
							i2c_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  ;
						else
							i2c_scl  =  1'b1  ;
		WAIT		:	i2c_scl  =  1'b0  ;
		STOP		:	if(cnt_i2c_clk == 2'd0)
							i2c_scl  =  1'b0  ;
						else
							i2c_scl  =  1'b1  ;
		default		:	i2c_scl  =  1'b1  ;
    endcase
	
always@(*)
	case(c_state)
		IDLE		:	i2c_sda  =  1'b1  ;
		START		:	if(cnt_i2c_clk == 2'd0)
							i2c_sda  =  1'b1  ;
						else
							i2c_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  ;
						else
							i2c_sda  <=  1'b1  ;
		default		:	i2c_sda  <=  1'b1  ;
    endcase

endmodule
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  ;
	else
		led  <=  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

總結(jié)

??小編在這里用了7章的教程,帶領(lǐng)各位讀者完成了對paj7620手勢識別模塊上、下、左、右的識別配置,感謝各位讀者的支持,后續(xù)將為大家?guī)?x4矩陣鍵盤密碼鎖工程的實現(xiàn),敬請期待。文章來源地址http://www.zghlxwxcb.cn/news/detail-443262.html

到了這里,關(guān)于PAJ7620U2手勢識別——讀取手勢數(shù)據(jù)寄存器數(shù)據(jù)與LED顯示(完)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • PAJ7620U2手勢識別——喚醒操作(1)

    PAJ7620U2手勢識別——喚醒操作(1)

    ??本教程是基于FPGA的手勢識別實現(xiàn)教程,使用到的手勢識別模塊是PAJ7620U2,本文主要向各位讀者闡述如何通過I2C協(xié)議去喚醒該模塊,從模塊狀態(tài)轉(zhuǎn)移圖、模塊波形圖的繪制,到最后代碼的編寫及驗證,一步一步教會各位讀者如何利用FPGA去實現(xiàn)。 ??下面我們簡單介紹一下

    2024年02月05日
    瀏覽(21)
  • 基于FPGA的手勢識別(PAJ7620U2)

    基于FPGA的手勢識別(PAJ7620U2)

    1.基本信息 ????????PAJ7620U2 是原相科技(PixArt)公司推出的一款光學(xué)數(shù)組式傳感器,內(nèi)置光源和環(huán)境光抑制濾波器集成的 LED,鏡頭和手勢感測器在一個小的立方體模組,能在黑暗或低光環(huán)境下工作。同時傳感器內(nèi)置手勢識別,支持 9 個手勢類型和輸出的手勢中斷結(jié)果。并

    2024年04月09日
    瀏覽(21)
  • PAJ7620U2手勢識別——激活BANK0(2)

    PAJ7620U2手勢識別——激活BANK0(2)

    ??在前一章教程中,小編帶領(lǐng)各位讀者通過I2C協(xié)議配置了手勢識別模塊當(dāng)中,較簡單的喚醒操作。在本章教程中,小編會繼續(xù)帶領(lǐng)各位讀者繼續(xù)配置PAJ7620U2手勢識別模塊,本章主要是講解如何激活BANK0,詳細操作請各位讀者繼續(xù)瀏覽下去。 ??相信很多讀者都會有這樣的疑

    2024年02月08日
    瀏覽(18)
  • STM32 手勢識別傳感器模塊(PAJ7620)學(xué)習(xí)

    STM32 手勢識別傳感器模塊(PAJ7620)學(xué)習(xí)

    目錄 模塊介紹: 基本部分: 引腳配置: 工作原理: 展示部分: 代碼部分展示(在正點的基礎(chǔ)上加了一個讀手勢去控制舵機): 視頻展示: 基本部分: 手勢模塊搭載的芯片是PAJ7620,無論是正點原子的還是別的手勢模塊的底層是一致的,甚至代碼也是通用的。 芯片內(nèi)部集成了

    2024年02月07日
    瀏覽(24)
  • 10.1 調(diào)試事件讀取寄存器

    10.1 調(diào)試事件讀取寄存器

    當(dāng)讀者需要獲取到特定進程內(nèi)的寄存器信息時,則需要在上述代碼中進行完善,首先需要編寫 CREATE_PROCESS_DEBUG_EVENT 事件,程序被首次加載進入內(nèi)存時會被觸發(fā)此事件,在該事件內(nèi)首先我們通過 lpStartAddress 屬性獲取到當(dāng)前程序的入口地址,并通過 SuspendThread 暫停程序的運行,

    2024年02月08日
    瀏覽(23)
  • optee讀取Arm系統(tǒng)寄存器的模板

    optee讀取Arm系統(tǒng)寄存器的模板

    快速鏈接: . ?????? 個人博客筆記導(dǎo)讀目錄(全部) ?????? 付費專欄-付費課程 【購買須知】: 【精選】ARMv8/ARMv9架構(gòu)入門到精通-[目錄] ?????? 聯(lián)系方式-加入交流群 ---- 聯(lián)系方式-加入交流群 先寫一個通用的內(nèi)聯(lián)函數(shù)模板,然后再通過宏控來定義各種讀寫函數(shù)。

    2024年02月12日
    瀏覽(26)
  • ZC-CLS381RGB顏色識別+8x8點陣指示——配置顏色識別寄存器組(上)

    ZC-CLS381RGB顏色識別+8x8點陣指示——配置顏色識別寄存器組(上)

    ??在現(xiàn)代工業(yè)生產(chǎn)中,顏色識別技術(shù)已經(jīng)成為了一個非常重要的技術(shù)。顏色識別可以用于產(chǎn)品質(zhì)量檢測、物料分類、機器視覺等領(lǐng)域。本文將介紹如何使用FPGA結(jié)合ZC-CLS381RGB進行顏色識別。 ??本教程通過對采集到的圖像信息中,R、G、B三個顏色分量的占比,來判斷識別到

    2024年02月03日
    瀏覽(87)
  • 三菱plc數(shù)據(jù)寄存器D

    三菱plc數(shù)據(jù)寄存器D

    在輸入和輸出處理、模擬控制和位置控制期間,需要許多數(shù)據(jù)寄存器來存儲數(shù)據(jù)和參數(shù)。數(shù)據(jù)寄存器為16位,最高位為符號位。兩個數(shù)據(jù)寄存器可以組合存儲32位數(shù)據(jù),最高位仍然是符號位。 ? 數(shù)據(jù)寄存器分為以下幾類: 通用數(shù)據(jù)寄存器D0 ~ D199有200個點。 斷電/鎖存寄存器D20

    2024年02月08日
    瀏覽(28)
  • PLC從HTTP服務(wù)端獲取JSON文件,解析數(shù)據(jù)到寄存器

    PLC從HTTP服務(wù)端獲取JSON文件,解析數(shù)據(jù)到寄存器

    ? ? ? ?智能網(wǎng)關(guān)IGT-DSER集成了多種PLC協(xié)議,方便實現(xiàn)各種PLC與HTTP服務(wù)端之間通訊。通過網(wǎng)關(guān)的參數(shù)配置軟件綁定JSON文件的字段與PLC寄存器地址,配置URL,即可采用POST命令,將JSON文件提交給HTTP的服務(wù)端; 服務(wù)端有返回的JSON,或者GET命令獲取到的JSON,網(wǎng)關(guān)進行解析后將數(shù)據(jù)

    2024年01月23日
    瀏覽(20)
  • Modbus協(xié)議的數(shù)據(jù)模型和地址模型,Modbus寄存器40001,30001是什么意思?

    在使用Modbus協(xié)議的時候,經(jīng)常會遇到諸如40001、30001,10001之類的地址,這些數(shù)字代表什么含義呢? 這其實是Modbus協(xié)議的數(shù)據(jù)模型和地址模型。 Modbus協(xié)議的數(shù)據(jù)模型 ?數(shù)據(jù)模型是對從站設(shè)備可訪問的數(shù)據(jù)進行抽象,Modbus協(xié)議的數(shù)據(jù)模型定義了四種可訪問的數(shù)據(jù): 數(shù)據(jù)區(qū)塊 數(shù)據(jù)

    2024年02月05日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包