BASYS2开发板初学记录(2)——Verilog程序编写

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/WilliamYuYuYu/article/details/78931368

ASYS2开发板初学记录(2)——Verilog程序编写

2017-12-26

注:win10系统+软件Xilinx_ISE14.7+开发板BASYS2

关键词:

FPGA

BASYS2

Xilinx_ISE

Verilog

紧接着上篇,填第一个坑:Verilog程序。

大学数电课学了Verilog,略有意思。

于是第一次就奉献在了Basys2上面。

写程序之前画一个流程图是非常方便整理思路的,(但是后来想想,对于Verilog这种硬件描述语言,流程图并不实用,波形时序图 似乎更能表达这里面的逻辑)

懒得改成时序图了,就把流程图贴出来吧:

(废话结束,祭出神器:Processon,可在线编辑各种脑图)


目的:

我做的是一个遥控机械手,遥控器5个信号输入分别控制5个手指,另外加第6个信号输入实现5个手指一起运动的动作组,用来按摩,没错。

硬件:

1》遥控器:富斯i10商品控,玩过航模的应该很清楚,这款遥控器支持10通道PWM信号输出,以及PPM信号输出。(这次使用PWM信号,因为简单,实在太简单。)

2》机械手:5个舵机,一个舵机控制一个手指。

原理:

遥控器的10个通道输出PWM波形,示波器真是个好东西,于是发现:每个通道的PWM波形为20ms一个周期,占空比5% (1ms)到10% (2ms)。

而舵机的控制需要的PWM信号输入也刚好是20ms一个周期,占空比5% (1ms)到10% (2ms)的PWM波形,也就是说,舵机直接遥控器的接收机就可以遥控了,压根没有开发板什么事,固定翼飞机就是玩的。可是不能这么没追求啊,我们要按摩啊!这就需要开发板处理6个通道的信号输入,输出5个信号。

每个CLK上升沿检测ch6通道信号,如果为高就进入自动按摩模式,5个手指一个个依次合拢,再依次张开的循环。如果为低,就进入遥控模式,5个通道遥控5个手指的位置。遥控器只有2个摇杆,输出4个模拟量,外加1个辅助通道,输出1个数字量。

程序流程图

这里写图片描述

不知是否能看清,所以截图了细节在下面:

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

完整程序如下:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: William Yu
// 
// Create Date:    22:44:03 12/23/2017 
// Design Name:         
// Module Name:    tele_pwm 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module tele_pwm(

   input wire clk,
    input wire reset,

    input wire ch1,
    input wire ch2,
    input wire ch3,
    input wire ch4,  
    input wire ch5,
    input wire ch6,

    output reg pwmout1,
    output reg pwmout2,
    output reg pwmout3,
    output reg pwmout4,
    output reg pwmout5,

   output wire [3:0] ledout             

  );


// ----------- counter --------------

reg [26:0] counter;

always @(posedge clk) 
begin
      if (reset)
          counter <= 0;
      else
      counter <= counter + 1;
end


// ----------- led check --------------

assign ledout = counter[26:23];    // 将counter的高4位传给led_out以降低频率,看到led灯闪烁 //167ms左右



// ----------- pwm input and output --------------
reg ch6_flag=0;
reg dance_en=0;
reg [19:0] counter20ms_2=0;  //20ms=20ns* 1000 000  //10^6 < 2^20

reg [31:0] counter8s = 0;   //8s= 20ns* 400 000 000  //400 000 000 < 2^32  //仿真检查刚开始的状态 
//reg [31:0] counter8s = 100000001;//仿真检查2s之后的状态
//reg [31:0] counter8s = 200000001;//仿真检查4s之后的状态
//reg [31:0] counter8s = 300000001;//仿真检查4s之后的状态

always @(posedge clk)
begin
    // ----------- tele --------------
    if(dance_en == 0)begin
        if (ch1)    //pwm1
            pwmout1<=1;
            else
            pwmout1<=0; 
        if (ch2)   //pwm2
            pwmout2<=1;
            else  
            pwmout2<=0; 
        if (ch3)   //pwm3
            pwmout3<=1;
            else  
            pwmout3<=0;
        if (ch4)   //pwm4
            pwmout4<=1;
            else  
            pwmout4<=0;  
        if (ch5)   //pwm4
            pwmout5<=1;
            else  
            pwmout5<=0;  
    end



    // ----------- dance --------------
    else begin
        counter8s <= counter8s+1;
        ///[A]1s动作组
        if(counter8s < 50000000 )begin //1s=20ns * 50 000 000
            counter20ms_2 <= counter20ms_2 + 1;
            ///高脉冲
            if(counter20ms_2 > 100000)begin//2ms=20ns*100 000
               pwmout1<=0;
            end
            else begin
                pwmout1<=1;
            end
            ///低脉冲
            if(counter20ms_2 > 50000)begin//1ms=20ns*50 000
                pwmout2<=0;
               pwmout3<=0;
                pwmout4<=0;
                pwmout5<=0;
            end
            else begin
                pwmout2<=1;
               pwmout3<=1;
                pwmout4<=1;
                pwmout5<=1;
            end
            if(counter20ms_2>1000000)  //20ms= 20ns*10^6
                counter20ms_2<=0;
        end 

       ///[B]2s动作组
        else if(counter8s < 100000000 )begin //2s=20ns * 100 000 000
            counter20ms_2 <= counter20ms_2 + 1;
            ///高脉冲
            if(counter20ms_2 > 100000)begin//2ms=20ns*100 000
               pwmout1<=0;
                pwmout2<=0;
            end
            else begin
               pwmout1<=1;
                pwmout2<=1;
            end
            ///低脉冲
            if(counter20ms_2 > 50000)begin//1ms=20ns*50 000
               pwmout3<=0;
                pwmout4<=0;
                pwmout5<=0;
            end
            else begin
               pwmout3<=1;
                pwmout4<=1;
                pwmout5<=1;
            end
            if(counter20ms_2>1000000)  //20ms= 20ns*10^6
                counter20ms_2<=0;
        end 

        ///[C]3s动作组
        else if(counter8s < 150000000 )begin //3s=20ns * 150 000 000
            counter20ms_2 <= counter20ms_2 + 1;
            ///高脉冲
            if(counter20ms_2 > 100000)begin//2ms=20ns*100 000
               pwmout1<=0;
                pwmout2<=0;
                pwmout3<=0;
            end
            else begin
               pwmout1<=1;
                pwmout2<=1;
                pwmout3<=1;
            end
            ///低脉冲
            if(counter20ms_2 > 50000)begin//1ms=20ns*50 000
                pwmout4<=0;
                pwmout5<=0;
            end
            else begin
                pwmout4<=1;
                pwmout5<=1;
            end
            if(counter20ms_2>1000000)  //20ms= 20ns*10^6
                counter20ms_2<=0;
        end

        ///[D]4s动作组
        else if(counter8s < 200000000 )begin //4s=20ns * 200 000 000
            counter20ms_2 <= counter20ms_2 + 1;
            ///高脉冲
            if(counter20ms_2 > 100000)begin//2ms=20ns*100 000
               pwmout1<=0;
                pwmout2<=0;
                pwmout3<=0;
                pwmout4<=0;
            end
            else begin
               pwmout1<=1;
                pwmout2<=1;
                pwmout3<=1;
                pwmout4<=1;
            end
            ///低脉冲
            if(counter20ms_2 > 50000)begin//1ms=20ns*50 000
                pwmout5<=0;
            end
            else begin
                pwmout5<=1;
            end
            if(counter20ms_2>1000000)  //20ms= 20ns*10^6
                counter20ms_2<=0;
        end

        ///[E]5s动作组
        else if(counter8s < 250000000 )begin //5s=20ns * 250 000 000
            counter20ms_2 <= counter20ms_2 + 1;
            ///高脉冲
            if(counter20ms_2 > 100000)begin//2ms=20ns*100 000
                pwmout2<=0;
                pwmout3<=0;
                pwmout4<=0;
            end
            else begin
                pwmout2<=1;
                pwmout3<=1;
                pwmout4<=1;
            end
            ///低脉冲
            if(counter20ms_2 > 50000)begin//1ms=20ns*50 000
                pwmout1<=0;
                pwmout5<=0;
            end
            else begin
                pwmout1<=1;
                pwmout5<=1;
            end
            if(counter20ms_2>1000000)  //20ms= 20ns*10^6
                counter20ms_2<=0;
        end

        ///[F]6s动作组
        else if(counter8s < 300000000 )begin //6s=20ns * 300 000 000
            counter20ms_2 <= counter20ms_2 + 1;
            ///高脉冲
            if(counter20ms_2 > 100000)begin//2ms=20ns*100 000
                pwmout3<=0;
                pwmout4<=0;
            end
            else begin
                pwmout3<=1;
                pwmout4<=1;
            end
            ///低脉冲
            if(counter20ms_2 > 50000)begin//1ms=20ns*50 000
                pwmout1<=0;
                pwmout2<=0;
                pwmout5<=0;
            end
            else begin
                pwmout1<=1;
                pwmout2<=1;
                pwmout5<=1;
            end
            if(counter20ms_2>1000000)  //20ms= 20ns*10^6
                counter20ms_2<=0;
        end

        ///[G]7s动作组
        else if(counter8s < 350000000 )begin //7s=20ns * 350 000 000
            counter20ms_2 <= counter20ms_2 + 1;
            ///高脉冲
            if(counter20ms_2 > 100000)begin//2ms=20ns*100 000
                pwmout4<=0;
            end
            else begin
                pwmout4<=1;
            end
            ///低脉冲
            if(counter20ms_2 > 50000)begin//1ms=20ns*50 000
                pwmout1<=0;
                pwmout2<=0;
                pwmout3<=0;
                pwmout5<=0;
            end
            else begin
                pwmout1<=1;
                pwmout2<=1;
               pwmout3<=1;
                pwmout5<=1;
            end
            if(counter20ms_2>1000000)  //20ms= 20ns*10^6
                counter20ms_2<=0;
        end

        ///[H]8s动作组
        else begin        //8s
            counter20ms_2 <= counter20ms_2 + 1;
            ///高脉冲无
            ///低脉冲
            if(counter20ms_2> 50000)begin//1ms=20ns*50 000
               pwmout1<=0;
                pwmout2<=0;
               pwmout3<=0;
                pwmout4<=0;
                pwmout5<=0;
            end
            else begin
               pwmout1<=1;
                pwmout2<=1;
                pwmout3<=1;
                pwmout4<=1;
                pwmout5<=1;
            end


            if(counter20ms_2>1000000)  //20ms= 20ns*10^6
                counter20ms_2<=0;

            //8s溢出循环
            if(counter8s > 400000000)   //8s= 20ns* 400 000 000 
                counter8s<=0;

        end
    end



end





// ----------- check ch6 --------------
reg [16:0] ch6_counter = 0;  //ch6_counter在1ms到2ms之间, 2ms=20ns* 100 000  //10^5 < 2^17
reg [19:0] counter20ms=0;  //20ms=20ns* 1000 000  //10^6 < 2^20

always @(posedge clk)
begin
        if(counter20ms>1000000)begin  //一个clk是20ns,10^6是20ms
            counter20ms<=0;
            ch6_counter<=0;end
        else 
        counter20ms <= counter20ms +1;  

        if (ch6) begin  
            ch6_counter<=ch6_counter+1;
            if (ch6_counter > 75000)   //1.5ms=75000 * 20ns
            ch6_flag <= 1;
            else ch6_flag <=0;
        end

end


reg [19:0] counter_ch6_flag=0;

always @(posedge clk)
begin
    if(ch6_flag)
            dance_en<=1;    
    else begin  //记录ch6低电平持续时间是否持续超过2ms,超过则认为已经拉低
        counter_ch6_flag<=counter_ch6_flag+1;   
        if(counter_ch6_flag>1000000)  
        begin
            dance_en<=0;
            counter_ch6_flag<=0;
        end
    end
end



endmodule

结束。

(2017-12-24–William Yu)

阅读更多

没有更多推荐了,返回首页