commit 0b5f410c06947d000bc055a77050d643cc93d47d Author: lincaigui <18166451309@163.com> Date: Mon Apr 15 13:26:09 2024 +0800 wake up diff --git a/doc/唤醒操作.vsdx b/doc/唤醒操作.vsdx new file mode 100644 index 0000000..83a713d Binary files /dev/null and b/doc/唤醒操作.vsdx differ diff --git a/doc/基于FPGA的手势识别控制系统设计.pdf b/doc/基于FPGA的手势识别控制系统设计.pdf new file mode 100644 index 0000000..4b3e8ec Binary files /dev/null and b/doc/基于FPGA的手势识别控制系统设计.pdf differ diff --git a/doc/激活bank0波形图.vsdx b/doc/激活bank0波形图.vsdx new file mode 100644 index 0000000..a2014d1 Binary files /dev/null and b/doc/激活bank0波形图.vsdx differ diff --git a/doc/状态机.vsdx b/doc/状态机.vsdx new file mode 100644 index 0000000..4ad4893 Binary files /dev/null and b/doc/状态机.vsdx differ diff --git a/doc/计数分频.vsdx b/doc/计数分频.vsdx new file mode 100644 index 0000000..6907d2f Binary files /dev/null and b/doc/计数分频.vsdx differ diff --git a/rtl/ges_recognize.v b/rtl/ges_recognize.v new file mode 100644 index 0000000..e69de29 diff --git a/rtl/i2c_ctrl.v b/rtl/i2c_ctrl.v new file mode 100644 index 0000000..4fbd8ce --- /dev/null +++ b/rtl/i2c_ctrl.v @@ -0,0 +1,253 @@ +module i2c_ctrl( + input wire sys_clk , + input wire sys_rst_n , + + output wire scl , + inout wire sda + +); +parameter I2C_CLK_DIV = 5'd24, + MAX = 10'd1000, + SLAVE_ID = 7'h73; +//状态机参数定义 +parameter IDLE = 3'd0, + START = 3'd1, + SLAVE_ADDR= 3'd2, + WAIT = 3'd3, + STOP = 3'd4; +reg [2: 0] state_c; +reg [2: 0] state_n; +//// + +//i2c时钟计数器 +reg [4: 0] cnt_clk; +reg i2c_clk; +///// + +//中间信号定义 +reg [9: 0] cnt_wait ;//1000us +reg skip_en_1 ;//跳转信号 +reg [2: 0] step ;//步骤 +reg [1: 0] cnt_i2c_clk ;//i2c计数器 +reg [2: 0] cnt_bit ;//bit计数器 +reg i2c_end ;//i2c结束信号 +wire sda_en ; +wire sda_in ; +reg i2c_sda ; +reg i2c_scl ; +reg [7: 0] slave_addr ; +reg [7: 0] device_addr ; +reg [7: 0] wr_data ; +//三态门 +assign sda_en = 1'b1;//主机控制从机 +assign sda_in = sda; +assign sda = (sda_en == 1'b1)? i2c_sda : 1'bz; +//i2c驱动时钟设计 +always @(posedge sys_clk or negedge sys_rst_n) begin + if(!sys_rst_n)begin + cnt_clk <= 5'd0; + end + else if(cnt_clk == I2C_CLK_DIV)begin + cnt_clk <= 5'd0; + end + else begin + cnt_clk <= cnt_clk + 1; + end +end + +always @(posedge sys_clk or negedge sys_rst_n) begin + if(!sys_rst_n)begin + i2c_clk <= 1'b1; + end + else if(cnt_clk == I2C_CLK_DIV)begin + i2c_clk <= ~i2c_clk; + end + else begin + i2c_clk <= i2c_clk; + end +end +///////// +//状态机,第一段 +always @(posedge i2c_clk or negedge sys_rst_n) begin + if(!sys_rst_n)begin + state_c <= IDLE; + end + else begin + state_c <= state_n; + end +end +//状态机第二段 +always @(*)begin + case(state_c) + IDLE: if(skip_en_1 == 1'b1)begin + state_n = START; + end + else begin + state_n = IDLE; + end + START: if(skip_en_1 == 1'b1)begin + state_n = SLAVE_ADDR; + end + else begin + state_n = START; + end + SLAVE_ADDR: if(skip_en_1 == 1'b1)begin + state_n = WAIT; + end + else begin + state_n = SLAVE_ADDR; + end + WAIT: if(skip_en_1 == 1'b1)begin + state_n = STOP; + end + else begin + state_n = WAIT; + end + STOP: if(skip_en_1 == 1'b1)begin + state_n = IDLE; + end + else begin + state_n = STOP; + end + default: begin + state_n = IDLE; + end + endcase +end +//状态机第三段 +always @(posedge i2c_clk or negedge sys_rst_n)begin + if(!sys_rst_n)begin + cnt_wait <= 10'd0; + skip_en_1 <= 1'b0; + step <= 3'd0; + cnt_i2c_clk <= 2'd0; + cnt_bit <= 3'd0; + i2c_end <= 1'b0; + end + else begin + case(state_c) + IDLE: begin + if(cnt_wait >= MAX - 1)begin + cnt_wait <= 10'd0; + end + else begin + cnt_wait <= cnt_wait + 1; + end + if((cnt_wait == MAX - 2'd2) && (step == 3'd0))begin + skip_en_1 <= 1'b1; + end + else begin + skip_en_1 <= 1'b0; + end + end + START: begin + cnt_i2c_clk <= cnt_i2c_clk + 1'd1; + if((cnt_i2c_clk == 2'd2) && (step == 3'd0))begin + skip_en_1 <= 1'b1; + end + else begin + skip_en_1 <= 1'b0; + end + end + SLAVE_ADDR: begin + cnt_i2c_clk <= cnt_i2c_clk + 1'd1; + if((cnt_i2c_clk == 2'd2) && (step == 3'd0) && (cnt_bit == 3'd7))begin + skip_en_1 <= 1'b1; + end + else begin + skip_en_1 <= 1'b0; + end + if((cnt_bit == 3'd7) && (cnt_i2c_clk == 2'd3))begin + cnt_bit <= 3'd0; + end + else if(cnt_i2c_clk == 2'd3)begin + cnt_bit <= cnt_bit + 1'd1; + end + else begin + cnt_bit <= cnt_bit; + end + end + WAIT: begin + if(cnt_wait == MAX - 1'd1)begin + cnt_wait <= 10'd0; + end + else begin + cnt_wait <= cnt_wait + 1'd1; + end + if((cnt_wait == MAX - 2'd2) && (step == 3'd0))begin + skip_en_1 <= 1'b1; + end + else begin + skip_en_1 <= 1'b0; + end + end + STOP: begin + cnt_i2c_clk <= cnt_i2c_clk + 1'd1; + if((cnt_i2c_clk == 2'd2) && (step == 3'd0))begin + skip_en_1 <= 1'b1; + end + else begin + skip_en_1 <= 1'b0; + end + if(cnt_i2c_clk == 2'd2)begin + i2c_end <= 1'b1; + end + else begin + i2c_end <= 1'b0; + end + if(i2c_end == 1'b1)begin + step <= step + 1'd1; + end + else begin + step <= step; + end + end + default: begin + cnt_wait <= 10'd0; + skip_en_1 <= 1'b0; + step <= step; + cnt_i2c_clk <= 2'd0; + cnt_bit <= 3'd0; + i2c_end <= 1'b0; + end + endcase + end +end +//step +always @(*)begin + case(step) + 3'd0: begin + slave_addr = {SLAVE_ID, 1'b0}; + device_addr = 8'h0; + wr_data = 8'h0; + end + default:begin + slave_addr = 8'h0; + device_addr = 8'h0; + wr_data = 8'h0; + end + endcase +end +//i2c_scl +always @(*)begin + case(state_c) + IDLE: i2c_scl = 1'b1; + START: i2c_scl = (cnt_i2c_clk <= 2'd2) ? 1'b1 : 1'b0; + SLAVE_ADDR: i2c_scl = ((cnt_i2c_clk == 2'd1) || (cnt_i2c_clk == 2'd2)) ? 1'b1 : 1'b0; + WAIT: i2c_scl = 1'b0; + STOP: i2c_scl = (cnt_i2c_clk >= 2'd1) ? 1'b1 : 1'b0; + endcase +end +//i2c_sda +always @(*)begin + case(state_c) + IDLE: i2c_sda = 1'b1; + START: i2c_sda = (cnt_i2c_clk > 2'd1) ? 1'b0 : 1'b1; + SLAVE_ADDR: i2c_sda = slave_addr[7 - cnt_bit]; + WAIT: i2c_sda = 1'b0; + STOP: i2c_sda = (cnt_i2c_clk >= 2'd2) ? 1'b1 : 1'b0; + default: i2c_sda = 1'b1; + endcase +end +assign scl = i2c_scl; +endmodule \ No newline at end of file diff --git a/rtl/i2c_ctrl.v.bak b/rtl/i2c_ctrl.v.bak new file mode 100644 index 0000000..8498ee7 --- /dev/null +++ b/rtl/i2c_ctrl.v.bak @@ -0,0 +1,253 @@ +module i2c_ctrl( + input wire sys_clk , + input wire sys_rst_n , + + output wire scl , + inout wire sda + +); +parameter I2C_CLK_DIV = 5'd24, + MAX = 10'd1000, + SLAVE_ID = 7'h73; +//状态机参数定义 +parameter IDLE = 3'd0, + START = 3'd1, + SLAVE_ADDR= 3'd2, + WAIT = 3'd3, + STOP = 3'd4; +reg [2: 0] state_c; +reg [2: 0] state_n; +//// + +//i2c时钟计数器 +reg [4: 0] cnt_clk; +reg i2c_clk; +///// + +//中间信号定义 +reg [9: 0] cnt_wait ;//1000us +reg skip_en_1 ;//跳转信号 +reg [2: 0] step ;//步骤 +reg [1: 0] cnt_i2c_clk ;// +reg [2: 0] cnt_bit ;//bit计数器 +reg i2c_end ;//i2c结束信号 +wire sda_en ; +wire sda_in ; +reg i2c_sda ; +reg i2c_scl ; +reg [7: 0] slave_addr ; +reg [7: 0] device_addr ; +reg [7: 0] wr_data ; +//三态门 +assign sda_en = 1'b1;//主机控制从机 +assign sda_in = sda; +assign sda = (sda_en == 1'b1)? i2c_sda : 1'bz; +//i2c驱动时钟设计 +always @(posedge sys_clk or negedge sys_rst_n) begin + if(!sys_rst_n)begin + cnt_clk <= 5'd0; + end + else if(cnt_clk == I2C_CLK_DIV)begin + cnt_clk <= 5'd0; + end + else begin + cnt_clk <= cnt_clk + 1; + end +end + +always @(posedge sys_clk or negedge sys_rst_n) begin + if(!sys_rst_n)begin + i2c_clk <= 1'b1; + end + else if(cnt_clk == I2C_CLK_DIV)begin + i2c_clk <= ~i2c_clk; + end + else begin + i2c_clk <= i2c_clk; + end +end +///////// +//状态机,第一段 +always @(posedge sys_clk or negedge sys_rst_n) begin + if(!sys_rst_n)begin + state_c <= IDLE; + end + else begin + state_c <= state_n; + end +end +//状态机第二段 +always @(*)begin + case(state_c) + IDLE: if(skip_en_1 == 1'b1)begin + state_n = START; + end + else begin + state_n = IDLE; + end + START: if(skip_en_1 == 1'b1)begin + state_n = SLAVE_ADDR; + end + else begin + state_n = START; + end + SLAVE_ADDR: if(skip_en_1 == 1'b1)begin + state_n = WAIT; + end + else begin + state_n = SLAVE_ADDR; + end + WAIT: if(skip_en_1 == 1'b1)begin + state_n = STOP; + end + else begin + state_n = WAIT; + end + STOP: if(skip_en_1 == 1'b1)begin + state_n = IDLE; + end + else begin + state_n = STOP; + end + default: begin + state_n = IDLE; + end + endcase +end +//状态机第三段 +always @(posedge i2c_clk or negedge sys_rst_n)begin + if(!sys_rst_n)begin + cnt_wait <= 10'd0; + skip_en_1 <= 1'b0; + step <= 3'd0; + cnt_i2c_clk <= 2'd0; + cnt_bit <= 3'd0; + i2c_end <= 1'b0; + end + else begin + case(state_c) + IDLE: begin + if(cnt_wait == MAX - 1)begin + cnt_wait <= 10'd0; + end + else begin + cnt_wait <= cnt_wait + 1; + end + if((cnt_wait == MAX - 2'd2) && (step == 3'd0))begin + skip_en_1 <= 1'b1; + end + else begin + skip_en_1 <= 1'b0; + end + end + START: begin + cnt_i2c_clk <= cnt_i2c_clk + 1'd1; + if((cnt_i2c_clk == 2'd2) && (step == 3'd0))begin + skip_en_1 <= 1'b1; + end + else begin + skip_en_1 <= 1'b0; + end + end + SLAVE_ADDR: begin + cnt_i2c_clk <= cnt_i2c_clk + 1'd1; + if((cnt_i2c_clk == 2'd2) && (cnt_bit == 3'd7) && (step == 3'd0))begin + skip_en_1 <= 1'b1; + end + else begin + skip_en_1 <= 1'b0; + end + if((cnt_bit == 3'd7) && (cnt_i2c_clk == 2'd3))begin + cnt_bit <= 3'd0; + end + else if(cnt_i2c_clk == 2'd3)begin + cnt_bit <= cnt_bit + 1'd1; + end + else begin + cnt_bit <= cnt_bit; + end + end + WAIT: begin + if(cnt_wait == MAX - 1'd1)begin + cnt_wait = 10'd0; + end + else begin + cnt_wait <= cnt_wait + 1'd1; + end + if((cnt_wait == MAX - 2'd2) && (step == 3'd0))begin + skip_en_1 <= 1'b1; + end + else begin + skip_en_1 <= 1'b0; + end + end + STOP: begin + cnt_i2c_clk <= cnt_i2c_clk + 1'd1; + if((cnt_i2c_clk == 2'd2) && (step == 3'd0))begin + skip_en_1 <= 1'b1; + end + else begin + skip_en_1 <= 1'b0; + end + if(cnt_i2c_clk == 2'd2)begin + i2c_end <= 1'b1; + end + else begin + i2c_end <= 1'b0; + end + if(i2c_end == 1'b1)begin + step <= step + 1'd1; + end + else begin + step <= step; + end + end + default: begin + cnt_wait <= 10'd0; + skip_en_1 <= 1'b0; + step <= step; + cnt_i2c_clk <= 2'd0; + cnt_bit <= 3'd0; + i2c_end <= 1'b0; + end + endcase + end +end +//step +always @(*)begin + case(step) + 3'd0: begin + slave_addr = {SLAVE_ID, 1'b0}; + device_addr = 8'h0; + wr_data = 8'h0; + end + default:begin + slave_addr = 8'h0; + device_addr = 8'h0; + wr_data = 8'h0; + end + endcase +end +//i2c_scl +always @(*)begin + case(state_c) + IDLE: i2c_scl = 1'b1; + START: i2c_scl = (cnt_i2c_clk >= 2'd2) ? 1'b1 : 1'b0; + SLAVE_ADDR: i2c_scl = ((cnt_i2c_clk == 2'd1) || (cnt_i2c_clk == 2'd2)) ? 1'b1 : 1'b0; + WAIT: i2c_scl = 1'b0; + STOP: i2c_scl = (cnt_i2c_clk >= 2'd1) ? 1'b1 : 1'b0; + endcase +end +//i2c_sda +always @(*)begin + case(state_c) + IDLE: i2c_sda = 1'b1; + START: i2c_sda = (cnt_i2c_clk >= 2'd1) ? 1'b0 : 1'b1; + SLAVE_ADDR: i2c_sda = slave_addr[7 - cnt_bit]; + WAIT: i2c_sda = 1'b0; + STOP: i2c_sda = (cnt_i2c_clk >= 2'd2) ? 1'b1 : 1'b0; + default: i2c_sda = 1'b1; + endcase +end +assign scl = i2c_scl; +endmodule \ No newline at end of file diff --git a/rtl/led_ctrl.v b/rtl/led_ctrl.v new file mode 100644 index 0000000..e69de29 diff --git a/rtl/paj7620_cfg.v b/rtl/paj7620_cfg.v new file mode 100644 index 0000000..e69de29