基于FPGA实现的TTP229-BSF触摸按键点灯小程序

一、说明

        首先非常感谢这位博主提供的帮助@u俺的me-CSDN博客,他写的关于TTP229触摸按键的文章直入主题,帮我规避了很多陷阱,让我少走了很多弯路。

二、TTP229-BSF模块使用

        TTP229触摸按键是一个系列的全称,我们在使用时一定先注意具体型号,请参考我上文提到的博主的这边文章:触摸IC TTP229学习笔记-CSDN博客。我这里使用到的是TTP229-BSF,模块的配置和使用在数据手册里面有详细的说明,这里我将正确的数据手册贴出来供大家参考(我是将按键模块配置为16键输入、使用串行输出的模式来进行使用的,因此我把关于这种模式配置的关键信息在数据手册里面进行了高亮,便于大家快速阅读)。【免费】TTP229-BSF数据手册资源-CSDN文库

        通过阅读数据手册可以知道:16键输入、串行输出模式需要将TP1和TP2通过大电阻接到数字地(用跳线帽按照图示将引脚打通)。

三、Verilog源码与仿真

        TTP229-BSF驱动如下:(第一次发文章,没找到Verilog高亮选项,抱歉)

module ttp229bsf_drive(
    input                               i_clk                      ,
    input                               i_rst_n                    ,
    input                               i_SDO                      ,
    output                              o_SCL                      ,
    output             [  15:0]         o_key_data                 ,
    output                              o_key_data_valid            

);

localparam                              P_CNT_TW = 500             ;//15us
localparam                              P_SYSTEM_CLK = 33_333_333  ;
localparam                              P_TTP229_FREQ = 500_000    ;//FREQ: 1KHz ~ 512KHz
localparam                              P_CLK_PERIOD = P_SYSTEM_CLK/P_TTP229_FREQ;
localparam                              P_CNT_TOUT = 66_666        ;



reg                                     r_SDO_0d                   ;
reg                                     r_SDO_1d                   ;
reg                    [  15:0]         r_Tw_cnt                   ;
reg                    [  15:0]         r_DV_cnt                   ;
reg                                     r_Tw_cnt_en                ;
reg                                     r_SCL_cnt_en               ;
reg                    [  15:0]         r_SCL_cnt                  ;
reg                                     r_SCL                      ;
reg                    [   7:0]         r_bit_cnt                  ;
reg                    [  15:0]         r_key_data                 ;
reg                                     r_key_data_valid           ;
reg                    [  15:0]         r_Tout_cnt1                ;
reg                    [  15:0]         r_Tout_cnt2                ;
reg                                     r_finish_flag              ;

wire                                    w_pose_SDO                 ;
wire                                    w_nege_SDO                 ;



assign      w_pose_SDO = r_SDO_0d && (!r_SDO_1d);
assign      w_nege_SDO = (!r_SDO_0d) && r_SDO_1d;
assign      o_SCL      = r_SCL;
assign      o_key_data = r_key_data;
assign      o_key_data_valid = r_key_data_valid;



//i_SDO打一拍
always@(posedge i_clk, negedge i_rst_n)begin
    if(~i_rst_n)begin
        r_SDO_0d <= 'd0;
        r_SDO_1d <= 'd0;
    end
    else begin
        r_SDO_0d <= i_SDO;
        r_SDO_1d <= r_SDO_0d;
    end
end


//r_DV_cnt
always@(posedge i_clk, negedge i_rst_n)begin
    if(~i_rst_n)
        r_DV_cnt <= 'd0;
    else if(w_nege_SDO)
        r_DV_cnt <= 'd0;
    else if(w_pose_SDO || r_DV_cnt >= 'd1)
        r_DV_cnt <= r_DV_cnt + 'd1;
    else
        r_DV_cnt <= 'd0;
end


//Tw延时计数器使能
always@(posedge i_clk, negedge i_rst_n)begin
    if(~i_rst_n)
        r_Tw_cnt_en <= 'd0;
    else if(w_nege_SDO && r_DV_cnt == (P_CLK_PERIOD - 'd1))
        r_Tw_cnt_en <= 'd0;
    else if(w_nege_SDO && r_DV_cnt != (P_CLK_PERIOD - 'd1))
        r_Tw_cnt_en <= 'd1;
    else if(r_Tw_cnt == P_CNT_TW - 'd1)
        r_Tw_cnt_en <= 'd0;
    else
        r_Tw_cnt_en <= r_Tw_cnt_en;
end


//Tw延时计数器
always@(posedge i_clk, negedge i_rst_n)begin
    if(~i_rst_n)
        r_Tw_cnt <= 'd0;
    else if(r_Tw_cnt == P_CNT_TW - 'd1)
        r_Tw_cnt <= 'd0;
    else if(r_Tw_cnt_en)
        r_Tw_cnt <= r_Tw_cnt + 'd1;
    else
        r_Tw_cnt <= r_Tw_cnt;
end


//SCL计数器使能
always@(posedge i_clk, negedge i_rst_n)begin
    if(~i_rst_n)
        r_SCL_cnt_en <= 'd0;
    else if(r_Tw_cnt == P_CNT_TW - 'd1)
        r_SCL_cnt_en <= 'd1;
    else if(r_bit_cnt == 'd15 && r_SCL_cnt == (P_CLK_PERIOD - 'd1) >> 'd1)
        r_SCL_cnt_en <= 'd0;
    else
        r_SCL_cnt_en <= r_SCL_cnt_en;
end


//SCL计数器
always@(posedge i_clk, negedge i_rst_n)begin
    if(~i_rst_n)
        r_SCL_cnt <= 'd0;
    else if(r_SCL_cnt == P_CLK_PERIOD - 'd1)
        r_SCL_cnt <= 'd0;
    else if(r_SCL_cnt_en)
        r_SCL_cnt <= r_SCL_cnt + 'd1;
    else
        r_SCL_cnt <= 'd0;
end


//SCL(0 ~ 332)
always@(posedge i_clk, negedge i_rst_n)begin
    if(~i_rst_n)
        r_SCL <= 'd0;
    else if(r_Tw_cnt == P_CNT_TW - 'd1)
        r_SCL <= ~r_SCL;
    else if(r_SCL_cnt == (P_CLK_PERIOD - 'd1) >> 'd1)
        r_SCL <= ~r_SCL;
    else if(r_SCL_cnt == P_CLK_PERIOD - 'd1)
        r_SCL <= ~r_SCL;
    else
        r_SCL <= r_SCL;
end


//bit_cnt
always@(posedge i_clk, negedge i_rst_n)begin
    if(~i_rst_n)
        r_bit_cnt <= 'd0;
    else if(r_bit_cnt == 'd15 && (r_SCL_cnt == P_CLK_PERIOD - 'd1))
        r_bit_cnt <= 'd0;
    else if(r_SCL_cnt == P_CLK_PERIOD - 'd1)
        r_bit_cnt <= r_bit_cnt + 'd1;
    else if(r_finish_flag)
        r_bit_cnt <= 'd0;
    else
        r_bit_cnt <= r_bit_cnt;
end


//按键数据
always@(posedge i_clk, negedge i_rst_n)begin
    if(~i_rst_n)
        r_key_data <= 'd0;
    else if(r_bit_cnt == 'd0)
        r_key_data[r_bit_cnt] <= i_SDO;
    else if(r_bit_cnt >= 'd1)
        r_key_data[r_bit_cnt] <= r_SDO_1d;
    else
        r_key_data <= r_key_data;
end


//按键数据有效
always@(posedge i_clk, negedge i_rst_n)begin
    if(~i_rst_n)
        r_key_data_valid <= 'd0;
    else if(r_bit_cnt == 'd15 && r_SCL_cnt == (P_CLK_PERIOD - 'd1) >> 'd1)
        r_key_data_valid <= 'd1;
    else if(r_Tw_cnt_en)
        r_key_data_valid <= 'd0;
    else
        r_key_data_valid <= r_key_data_valid;
end


//Tout
always@(posedge i_clk, negedge i_rst_n)begin
    if(~i_rst_n)
        r_Tout_cnt1 <= 'd0;
    else if(r_Tout_cnt1 == (P_CNT_TOUT >> 1) - 'd1)
        r_Tout_cnt1 <= 'd0;
    else if(r_key_data_valid)
        r_Tout_cnt1 <= r_Tout_cnt1 + 'd1;
    else    
        r_Tout_cnt1 <= r_Tout_cnt1;
end

always@(posedge i_clk, negedge i_rst_n)begin
    if(~i_rst_n)
        r_Tout_cnt2 <= 'd0;
    else if(r_Tout_cnt2 == 'd1 && r_Tout_cnt1 == (P_CNT_TOUT >> 1) - 'd1)
        r_Tout_cnt2 <= 'd0;
    else if(r_Tout_cnt1 == ((P_CNT_TOUT >> 1) - 'd1))
        r_Tout_cnt2 <= r_Tout_cnt2 + 'd1;
    else
        r_Tout_cnt2 <= r_Tout_cnt2;
end


//finish_flag
always@(posedge i_clk, negedge i_rst_n)begin
    if(~i_rst_n)
        r_finish_flag <= 'd0;
    else if(r_Tout_cnt2 == 'd1 && r_Tout_cnt1 == ((P_CNT_TOUT >> 1) - 'd1))
        r_finish_flag <= 'd1;
    else
        r_finish_flag <= 'd0;
end

endmodule

        Vivado仿真: 

四、结束语

        小编最后用TTP229-BSF驱动输出的按键数据(o_key_data)去点灯了。虽然仿真和最终的实验现象正确,但驱动代码难免还有不周的地方,欢迎各位朋友指正与交流。

 

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值