天天看點

Verilog HDL 模拟 汽車尾燈自動控制系統

Verilog HDL 模拟 汽車尾燈自動控制系統

文章目錄

  • ​​Verilog HDL 模拟 汽車尾燈自動控制系統​​
  • ​​一、要求介紹:​​
  • ​​二、代碼實作​​
  • ​​1、主子產品的代碼​​
  • ​​2、時鐘分頻子產品​​
  • ​​三、效果展示​​

一、要求介紹:

設計一個汽車尾燈自動控制系統

要求:根據汽車行駛狀态自動控制汽車尾燈

直行:尾燈不亮

右轉:右側尾燈亮而且按秒閃爍,左側尾燈不亮

左轉:左側尾燈亮而且按秒閃爍,右側尾燈不亮

臨時停車或故障:兩側尾燈同時閃爍

倒車顯示(可選)

注:用三色 LED 代表左右汽車尾燈,用撥碼開關控制汽車行駛狀态,還可以考慮用七段數位管和單色 LED 顯示汽車狀态

二、代碼實作

1、主子產品的代碼

module car(rst, clk, start, left, right, error, back, 
led11, led12, led13, led21, led22, led23);

    input rst; 
    // reset.
    input clk;
    // clock.
    
    input start;
    // strat the car.
    input left;
    // go left.
    input right;
    // go right.
    input error;
    // if error.
    input back;
    // go back.
    
    output reg led11;
    output reg led12;
    output reg led13;
    output reg led21;
    output reg led22;
    output reg led23;
    // lights.
    
    wire clkout1;
    wire clkout2;
    
    time_split #(.N(6000000),
                        .WIDTH(23)) t1 (
                    .clk(clk),
                    .rst_n(rst),
                    .clkout(clkout1));
                    // time_split 1.
                    // 2 Hz.
    
    time_split #(.N(3000000),
                        .WIDTH(23)) t2 (
                    .clk(clk),
                    .rst_n(rst),
                    .clkout(clkout2));
                    // time_split 2.    
                    // 4 Hz.
    
    always@(posedge clk)
    begin
        if(start)
        // the car has started.
        begin
        if(~left && ~right && ~error && back)
        // no other operators.
        begin        
                led11 <= 1;
                led12 <= 1;
                led13 <= 1;
                led21 <= 1;
                led22 <= 1;
                led23 <= 1;
                // all the lights are closed.
            end
            
            // four situations.
            else
            begin
                if(left)
                // turn left.
                begin
                    led11 <= 1;
                    led12 <= clkout1;// turn left.
                    // 2 Hz.
                    led13 <= 1;
                    led21 <= 1;
                    led22 <= 1;
                    led23 <= 1;
                end
                
                if(right)
                // turn right.
                begin
                    led11 <= 1;
                    led12 <= 1;
                    led13 <= 1;
                    led21 <= 1;
                    led22 <= clkout1;// turn right.
                    // 2 Hz.
                    led23 <= 1;
                end
                
                if(error)
                // if there is an error or stop the car.
                begin
                    led11 <= clkout2;
                    // if there is an error or stop the car.
                    // 4 Hz.
                    led12 <= 1;
                    led13 <= 1;
                    led21 <= clkout2;
                    // if there is an error or stop the car.
                    // 4 Hz.
                    led22 <= 1;
                    led23 <= 1;
                end
                
                if(~back)
                // if go back
                begin
                    led11 <= 1;
                    led12 <= 1;
                    led13 <= clkout1;// if go back
                    // 2 Hz.
                    led21 <= 1;
                    led22 <= 1;
                    led23 <= clkout1;// if go back
                    // 2 Hz.
                end
                
            end
        end
        
        else
        // do not start.
        begin
            led11 <= 1;
            led12 <= 1;
            led13 <= 1;
            led21 <= 1;
            led22 <= 1;
            led23 <= 1;
            // all the lights are closed.      

2、時鐘分頻子產品

// ********************************************************************
// >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// ********************************************************************
// File name    : divide.v
// Module name  : divide
// Author       : STEP
// Description  : clock divider
// Web          : www.stepfpga.com
// 
// --------------------------------------------------------------------
// Code Revision History : 
// --------------------------------------------------------------------
// Version: |Mod. Date:   |Changes Made:
// V1.0     |2017/03/02   |Initial ver
// --------------------------------------------------------------------
// Module Function:任意整數時鐘分頻
 
module time_split (    clk,rst_n,clkout);
 
        input    clk,rst_n;                       //輸入信号,其中clk連接配接到FPGA的C1腳,頻率為12MHz
        output    clkout;                          //輸出信号,可以連接配接到LED觀察分頻的時鐘
 
        //parameter是verilog裡常數語句
//    parameter    WIDTH    = 3;             //計數器的位數,計數的最大值為 2**WIDTH-1
//    parameter    N    = 5;             //分頻系數,請確定 N < 2**WIDTH-1,否則計數會溢出
//    
    
    
    parameter N=12000000;
    parameter WIDTH=24;
 
    reg    [WIDTH-1:0]    cnt_p,cnt_n;     //cnt_p為上升沿觸發時的計數器,cnt_n為下降沿觸發時的計數器
    reg            clk_p,clk_n;     //clk_p為上升沿觸發時分頻時鐘,clk_n為下降沿觸發時分頻時鐘
 
    //上升沿觸發時計數器的控制
    always @ (posedge clk or negedge rst_n )         //posedge和negedge是verilog表示信号上升沿和下降沿
                                                         //當clk上升沿來臨或者rst_n變低的時候執行一次always裡的語句
        begin
            if(!rst_n)
                cnt_p<=0;
            else if (cnt_p==(N-1))
                cnt_p<=0;
            else cnt_p<=cnt_p+1;             //計數器一直計數,當計數到N-1的時候清零,這是一個模N的計數器
        end
 
         //上升沿觸發的分頻時鐘輸出,如果N為奇數得到的時鐘占空比不是50%;如果N為偶數得到的時鐘占空比為50%
         always @ (posedge clk or negedge rst_n)
        begin
            if(!rst_n)
                clk_p<=0;
            else if (cnt_p<(N>>1))          //N>>1表示右移一位,相當于除以2去掉餘數
                clk_p<=0;
            else 
                clk_p<=1;               //得到的分頻時鐘正周期比負周期多一個clk時鐘
        end
 
        //下降沿觸發時計數器的控制            
    always @ (negedge clk or negedge rst_n)
        begin
            if(!rst_n)
                cnt_n<=0;
            else if (cnt_n==(N-1))
                cnt_n<=0;
            else cnt_n<=cnt_n+1;
        end
 
        //下降沿觸發的分頻時鐘輸出,和clk_p相差半個時鐘
    always @ (negedge clk)
        begin
            if(!rst_n)
                clk_n<=0;
            else if (cnt_n<(N>>1))  
                clk_n<=0;
            else 
                clk_n<=1;                //得到的分頻時鐘正周期比負周期多一個clk時鐘
        end
 
        assign clkout = (N==1)?clk:(N[0])?(clk_p&clk_n):clk_p;      //條件判斷表達式
                                                                    //當N=1時,直接輸出clk
                                                                    //當N為偶數也就是N的最低位為0,N(0)=0,輸出clk_p
                                                                    //當N為奇數也就是N最低位為1,N(0)=1,輸出clk_p&clk_n。正周期多是以是相與
endmodule      

然後,我們進行管腳的配置設定:

Verilog HDL 模拟 汽車尾燈自動控制系統

接下來就是進行編譯:

Verilog HDL 模拟 汽車尾燈自動控制系統

最後進行燒錄:

Verilog HDL 模拟 汽車尾燈自動控制系統

三、效果展示

我們還是采用視訊的方法來進行效果的展示與呈現:

(如果你喜歡的話就去點個贊吧)

​​https://www.bilibili.com/video/BV1JL411778U?spm_id_from=333.999.0.0​​

Verilog HDL 模拟 汽車尾燈自動控制系統

繼續閱讀