天天看點

(總結)(原創)LCD屏的學習總結

(總結)(原創)LCD屏的學習總結(針對ST7920)

  前言:這麼長時間一直沒有寫部落格,是因為總結的東西不能随便的發出來,因為不夠完善,尤其對于我這種初學者,但經過一段時間的經曆,必須要有深思熟慮,有自己的親身經曆在裡面。在這兩個星期的時間裡,在一個簡單的LCD屏的驅動上汲取了許多 營養。該有個學習總結了。

     1、學習态度和做事的方式。

  認真、全面、仔細、耐心。這是最重要的幾點,我一共寫了多達3個完全不同的版本去驅動LCD,卻一直沒有我想要的結果,一直在懷疑我的軟體問題,可到最後在發現是我沒有仔細閱讀通信協定,在初始化的過程中 少了一個指令。另外在仿真的時候也沒有對所有的情況做一個完整的檢查。

  2、将組合電路和時序電路的分離。

  一個好用的設計應該是在設計的初期就應該預想到寄存器的個數和它的功能,我認為在電路設計中有很大的部分是在于決定我的寄存器的安放。 在我最後的設計中,我使用了一個移位寄存器,一個發送資料緩沖器,對于每行的資料存儲區的輸出也有一個資料緩沖,以應對于作出顯示内容的選擇。我在初學設計的時候使用的都是時序群組合混合的方式,但在這次的設計中我使用的是分開描述的方式,這樣書寫的方式有利于對于整個系統的了解和實作,對于電路綜合後有一個預測和把握。剛開始的時候應用的不是很熟練,漸漸的發現自己對于Verilog的語句和實作方式都沒有很好的了解,比如阻塞指派和非阻塞指派沒有很好的了解,對于begin和end塊語句的順序執行方式也沒有體會到。

  3、軟體代碼和說明

  (1)我沒有使用專門的ROM是直接自己書寫的ROM。

  (2)我對于發送資料的方式有點問題,應該是先發高位再發低位,我做成了先發低位再發高位,隻需要将右移改為左移,将高8位輸出。

  (3)控制方式,我将每行要發送的漢字存儲到ROM裡,然後根據輸入的顯示編碼,就達到文字的改變(這是因為我是為任意波形發生器寫的專門的調節顯示子產品的,經過改進可以應用于其他方式),然後向LCD發送資料是從第一行向最後一行不斷地重複掃描。

  (4)希望大家提出建議,誠懇的需要大家的批評。

  (5) 本文是針對st7920寫的驅動。 

  4、源代碼如下:

 //-----------------------------------------------------

// Design Name : lcd

// File Name   : gz_lcd_v3.v

// Function    : lcd

// Aurthor     : guanzhou

//Vertion      : v 3.0

//Date         : 2009.10.22

//-----------------------------------------------------

`timescale  1ns/100ps

module lcd

    (

    //input 

    rclk,rst,

    addr_f,addr_p,addr_m,

    control,

    //ouput 

    e,rs,rw,

    data

    );

    parameter    max_count_f  =  4_749_999;

    //parameter    max_count_f  =  2;

    parameter    wide_count_f  =  23;

    parameter    wide_f  =  3,

                wide_p  =  3,

                wide_m  =  3;

    parameter    word_size  =  11;

    parameter    max_b  =  63;

    parameter   order_set = 8\'b0011_0000,

                cursor_set  =  8\'b0000_1110,

                addr_set  =  8\'b0000_0001,

                display_set  =  8\'b0000_0100;

    parameter    idle  =  4\'b0001,

                mode  =  4\'b0010,

                freq  =  4\'b0100,

                phase  =  4\'b1000;

    input rclk,rst;

    input [wide_f-1:0] addr_f;

    input [wide_p-1:0] addr_p;

    input [wide_m-1:0] addr_m;

    input [2:0] control;

    output e,rs,rw;

    output [7:0] data;

    reg shift;

    //========================================================

    //分頻

    //========================================================

    reg  [wide_count_f-1:0] count_f;

    reg clk;

    always @(posedge rclk or negedge rst)

    begin

        if(!rst)

            begin

                count_f  <=  0;

                clk  <=  0;

            end

        else if(count_f==max_count_f)

            begin

                count_f  <=  0;

                clk  <=  ~clk;

            end

        else

            count_f  <=  count_f  +  1\'b1;

    end

    wire e;

    assign e  =  clk;                        //讀寫信号為4Hz的時鐘信号

    reg [max_b+15:0]     data_f,

                        data_p,

                        data_m;

    always @(addr_m or addr_f or addr_p)          //定義ROM

    begin

        case(addr_m)

            3\'d0:  data_m[max_b-1:0]  =  64\'hCEF7_D3CA_CEA2_B5E7;

            3\'d1:  data_m[max_b-1:0]  =  64\'hCFE0_CEBB_CFE0_CEBB;

            3\'d2:  data_m[max_b-1:0]  =  64\'hC6B5_C2CA_C6B5_C2CA;

            3\'d3:  data_m[max_b-1:0]  =  64\'hCEF7_D3CA_CEA2_B5E7;

            3\'d4:  data_m[max_b-1:0]  =  64\'hCEF7_D3CA_CEA2_B5E7;

            3\'d5:  data_m[max_b-1:0]  =  64\'hCFE0_CEBB_CFE0_CEBB;

            3\'d6:  data_m[max_b-1:0]  =  64\'hC6B5_C2CA_C6B5_C2CA;

            3\'d7:  data_m[max_b-1:0]  =  64\'hCEF7_D3CA_CEA2_B5E7;

        endcase

        case(addr_f)

            3\'d0:  data_f[max_b-1:0]  =  64\'hC6B5_C2CA_C6B5_C2CA;

            3\'d1:  data_f[max_b-1:0]  =  64\'hCFE0_CEBB_CFE0_CEBB;

            3\'d2:  data_f[max_b-1:0]  =  64\'hCEF7_D3CA_CEA2_B5E7;

            3\'d3:  data_f[max_b-1:0]  =  64\'hCFE0_CEBB_CFE0_CEBB;

            3\'d4:  data_f[max_b-1:0]  =  64\'hC6B5_C2CA_C6B5_C2CA;

            3\'d5:  data_f[max_b-1:0]  =  64\'hCEF7_D3CA_CEA2_B5E7;

            3\'d6:  data_f[max_b-1:0]  =  64\'hCFE0_CEBB_CFE0_CEBB;

            3\'d7:  data_f[max_b-1:0]  =  64\'hCEF7_D3CA_CEA2_B5E7;

        endcase

        case(addr_p)

            3\'d0:  data_p[max_b-1:0]  =  64\'hCFE0_CEBB_CFE0_CEBB;

            3\'d1:  data_p[max_b-1:0]  =  64\'hC6B5_C2CA_C6B5_C2CA;

            3\'d2:  data_p[max_b-1:0]  =  64\'hCFE0_CEBB_CFE0_CEBB;

            3\'d3:  data_p[max_b-1:0]  =  64\'hCEF7_D3CA_CEA2_B5E7;

            3\'d4:  data_p[max_b-1:0]  =  64\'hC6B5_C2CA_C6B5_C2CA;

            3\'d5:  data_p[max_b-1:0]  =  64\'hCFE0_CEBB_CFE0_CEBB;

            3\'d6:  data_p[max_b-1:0]  =  64\'hCEF7_D3CA_CEA2_B5E7;

            3\'d7:  data_p[max_b-1:0]  =  64\'hC6B5_C2CA_C6B5_C2CA;

        endcase

    end

    always @(control)                               //要求在每一行前面加上訓示星号,表明目前的波形設定

    begin

        case(control)

            3\'b001:

                begin

                    data_m[max_b+15:max_b]  <=  16\'hA1F2;

                    data_f[max_b+15:max_b]  <=  16\'hA2A0;

                    data_p[max_b+15:max_b]  <=  16\'hA2A0;

                end

            3\'b010:

                begin

                    data_m[max_b+15:max_b]  <=  16\'hA2A0;

                    data_f[max_b+15:max_b]  <=  16\'hA1F2;

                    data_p[max_b+15:max_b]  <=  16\'hA2A0;

                end

            3\'b100:

                begin

                    data_m[max_b+15:max_b]  <=  16\'hA2A0;

                    data_f[max_b+15:max_b]  <=  16\'hA2A0;

                    data_p[max_b+15:max_b]  <=  16\'hA1F2;

                end

            default:

                begin

                    data_m[max_b+15:max_b]  <=  16\'hA2A0;

                    data_f[max_b+15:max_b]  <=  16\'hA2A0;

                    data_p[max_b+15:max_b]  <=  16\'hA2A0;

                end

        endcase

    end

    //========================================================

    //行掃描循環控制狀态機

    //========================================================

    reg [7:0] data;

    reg rs,rw;

    reg [4:0] bit_count;

    reg [4:0] state,next_state;

    reg [max_b+15:0] data_shift;

    always @(state or bit_count)

    begin

        shift =  0;

        next_state  =  state;

        case(state)

            idle:

                begin                       

                    if(bit_count==word_size-2)

                            shift  =  1;

                    if(bit_count==word_size-3)

                        next_state  =  mode;

                end

            mode:

                begin

                    if(bit_count==word_size-2)

                            shift  =  1;

                    if(bit_count==word_size-3)

                        next_state  =  freq;

                end            

            freq:

                begin

                    if(bit_count==word_size-2)

                            shift  =  1;

                    if(bit_count==word_size-3)

                        next_state  =  phase;

                end

            phase:

                begin

                    if(bit_count==word_size-2)

                            shift  =  1;

                    if(bit_count==word_size-3)

                        next_state  =  mode;

                end

            default:    

                begin

                    shift =  0;

                    next_state  =  state;

                end

        endcase

    end

    always @(posedge clk or negedge rst)

    begin

        if(!rst)

            state  <=  idle;

        else

            state  <=  next_state;

    end

    //==========================================================

    //發送文字資訊資料

    //==========================================================

    always @(posedge clk or negedge rst)

    begin

        if(!rst)

            begin

                data  <=  order_set;

                bit_count  <=  0;

                data_shift  <=  {39\'d0,display_set,addr_set,cursor_set,order_set,order_set};

            end

        else

            begin

                if(shift)                   // ?????

                    case(state)

                        idle:

                            begin

                                data_shift  <=  {39\'d0,display_set,addr_set,cursor_set,order_set,order_set};

                                data  <=  order_set;

                            end

                        mode: 

                            begin

                                data_shift  <=  data_m;

                                data  <=  8\'h90;

                            end

                        freq:

                            begin

                                data_shift  <=  data_f;

                                data  <=  8\'h80;

                            end

                        phase:

                            begin

                                data_shift  <=  data_p;

                                data  <=  8\'h98;

                            end

                        default: 

                            begin

                                data_shift  <=  data_shift;

                                data  <= 8\'h00;

                            end

                    endcase

                else

                    begin

                        data  <=  data_shift[7:0];

                        data_shift  <=  {8\'b1111_1111,data_shift[max_b+15:8]};

                    end

                if(shift)

                    bit_count  <=  0;

                else

                    bit_count  <= bit_count  +  1\'b1;

            end

    end

    //================================================================

    //發送資料格式指令

    //================================================================

    always @(posedge clk or negedge rst)

    begin

        if(!rst)

            begin

                rw  <=     1;

                rs  <=  1;

            end

        else

            if(state==idle)

                begin

                    rs  <=  0;

                    rw  <=  0;

                end

            else if(shift)

                begin

                    rs  <=  0;

                    rw  <=  0;

                end

            else

                begin

                    rs  <=  1;

                    rw  <=  0;

                end

    end                

endmodule                

(總結)(原創)LCD屏的學習總結