As mentioned above, "Hello World" will be the first language to learn in C, C ++ and other languages.CodeHowever, in FPGA, because of the complexity of circuit driving, similar to single-chip microcomputer, we cannot achieve "Hello World" display on the computer, but must rely on relevant hardware. Therefore, we have to explain the driver of the lcd1602 character liquid crystal and the hello World display on a certain basis.
Similar to the preceding MCU key jitter transplant code, the MCU lcd1602 driver code can also be transplanted here. This routine is not original in Bingo. It is based on the Code of the netizen "The hour does not recognize the month". It is transplanted and modified to the bingo version (O (Taobao _ blank) O Haha ~).
The circuit diagram is not explained here. It is too simple.
1. Driver description
Because FPGA's high-speed parallel operations are not sequential execution, the code is different from MCU. Here we will first explain the driver principle:
(1) frequency division to get a fixed frequency of kHz and initialize lcd1602. As shown in, the frequency of LCD _en should be controlled within 2 MB (different lcd1602 parameters may vary ).
(2) initialize and give data through a three-stage state machine.
(3) read an "array" cyclically and feed the lcd1602 data cyclically, facilitating changes in the form of interfaces.
Ii. FPGA lcd1602 fsm1. code
/*************************************** **********
* Module name: lcd1602_driver
* Engineer: crazy bingo
* Target device: ep2c8q208c8
* Tool versions: Quartus II 11.0
* Create Date: 2011-7-3
* Revision: V1.0
* Description:
**************************************** **********/
Module lcd1602_driver
(
Input CLK,
Input rst_n,
Output LCD _en, // LCD enable
Output Reg LCD _rs, // record, statement
Output LCD _rw,
Output Reg [7:0] LCD _data
);
Parameter [expiration :0] line_rom1 = "I am crazybingo! ";
Parameter [expiration :0] line_rom2 = "Hello world * ^_^ *";
//--------------------------------------
Reg [15:0] CNT;
Always @ (posedge CLK or negedge rst_n)
Begin
If (! Rst_n)
CNT <= 0;
Else
CNT <= CNT + 1' B1;
End
Assign LCD _en = CNT [15]; // LCD enable, keep same time
Assign LCD _rw = 1' B0; // write only
Wire 1__flag = (CNT = 16 '0000fff )? 1 'b1: 1' B0; // when LCD _en is steady, write a cmd
//---------------------------------------
// Gray code: 40 States
Parameter idle = 8'h00; // idle
// LCD init
Parameter disp_set = 8 'h01; // Display Mode
Parameter disp_off = 8 'h03; // off display
Parameter clr_scr = 8'h02; // clear the LCD
Parameter cursor_set1 = 8 'h06; // cursor set
Parameter cursor_set2 = 8 'h07; // on display, cursor set
// Display 1th line
Parameter row1_addr = 8'h05;
Parameter row1_0 = 8 'h04;
Parameter row1_1 = 8 'h0c;
Parameter row1_2 = 8 'h0d;
Parameter row1_3 = 8 'h0f;
Parameter row1_4 = 8 'h0e;
Parameter row1_5 = 8'h0a;
Parameter row1_6 = 8'h0b;
Parameter row1_7 = 8'h09;
Parameter row1_8 = 8'h08;
Parameter row1_9 = 8'h18;
Parameter row1_a = 8 'h19;
Parameter row1_ B = 8 'h1b;
Parameter row1_c = 8'h1a;
Parameter row1_d = 8'h1e;
Parameter row1_e = 8'h1f;
Parameter row1_f = 8'h1d;
// Display 2th line
Parameter row2_addr = 8 'h1c;
Parameter row2_0 = 8 'h14;
Parameter row2_1 = 8'h15;
Parameter row2_2 = 8'h17;
Parameter row2_3 = 8'h16;
Parameter row2_4 = 8 'h12;
Parameter row2_5 = 8 'h13;
Parameter row2_6 = 8 'h11;
Parameter row2_7 = 8 'h10;
Parameter row2_8 = 8 'h30;
Parameter row2_9 = 8 'h31;
Parameter row2_a = 8 'h33;
Parameter row2_ B = 8 'h32;
Parameter row2_c = 8 'h36;
Parameter row2_d = 8 'h37;
Parameter row2_e = 8 'h35;
Parameter row2_f = 8 'h34;
//---------------------------------------
Reg [5:0] current_state, next_state;
// FSM: always1
Always @ (posedge CLK or negedge rst_n)
Begin
If (! Rst_n)
Current_state <= idle;
Else if (pai_flag)
Current_state <= next_state;
End
//---------------------------------------
// FSM: always2
Always @*
Begin
Case (current_state)
// LCD init
Idle: next_state = disp_set;
Disp_set: next_state = disp_off;
Disp_off: next_state = clr_scr;
Clr_scr: next_state = cursor_set1;
Cursor_set1: next_state = cursor_set2;
Cursor_set2: next_state = roww.addr;
// Display 1th line
Row1_addr: next_state = row1_0;
Row1_0: next_state = row1_1;
Row1_1: next_state = row1_2;
Row1_2: next_state = row1_3;
Row1_3: next_state = row1_4;
Row1_4: next_state = row1_5;
Row1_5: next_state = row1_6;
Row1_6: next_state = row1_7;
Row1_7: next_state = row1_8;
Row1_8: next_state = row1_9;
Row1_9: next_state = row1_a;
Row1_a: next_state = row1_ B;
Row1_ B: next_state = row1_c;
Row1_c: next_state = row1_d;
Row1_d: next_state = row1_e;
Row1_e: next_state = row1_f;
Row1_f: next_state = row2_addr;
// Display 2th line
Row2_addr: next_state = row2_0;
Row2_0: next_state = row2_1;
Row2_1: next_state = row2_2;
Row2_2: next_state = row2_3;
Row2_3: next_state = row2_4;
Row2_4: next_state = row2_5;
Row2_5: next_state = row2_6;
Row2_6: next_state = row2_7;
Row2_7: next_state = row2_8;
Row2_8: next_state = row2_9;
Row2_9: next_state = row2_a;
Row2_a: next_state = row2_ B;
Row2_ B: next_state = row2_c;
Row2_c: next_state = row2_d;
Row2_d: next_state = row2_e;
Row2_e: next_state = row2_f;
Row2_f: next_state = row1_addr;
Default: next_state = idle;
Endcase
End
//---------------------------------------
// FSM: always3
Always @ (posedge CLK or negedge rst_n)
Begin
If (! Rst_n)
Begin
LCD _rs <= 0;
LCD _data <= 8'hxx;
End
Else if (pai_flag)
Begin
// Write statement
Case (next_state)
Idle: LCD _rs <= 0; // statement
// LCD init
Disp_set: LCD _rs <= 0; // statement
Disp_off: LCD _rs <= 0; // statement
Clr_scr: LCD _rs <= 0; // statement
Cursor_set1: LCD _rs <= 0; // statement
Cursor_set2: LCD _rs <= 0; // statement
// Display 1th line
Row1_addr: LCD _rs <= 0; // statement
Row1_0: LCD _rs <= 1; // record
Row1_1: LCD _rs <= 1; // record
Row1_2: LCD _rs <= 1; // record
Row1_3: LCD _rs <= 1; // record
Row1_4: LCD _rs <= 1; // record
Row1_5: LCD _rs <= 1; // record
Row1_6: LCD _rs <= 1; // record
Row1_7: LCD _rs <= 1; // record
Row1_8: LCD _rs <= 1; // record
Row1_9: LCD _rs <= 1; // record
Row1_a: LCD _rs <= 1; // record
Row1_ B: LCD _rs <= 1; // record
Row1_c: LCD _rs <= 1; // record
Row1_d: LCD _rs <= 1; // record
Row1_e: LCD _rs <= 1; // record
Row1_f: LCD _rs <= 1; // record
// Display 2th line
Row2_addr: LCD _rs <= 0; // statement
Row2_0: LCD _rs <= 1; // record
Row2_1: LCD _rs <= 1; // record
Row2_2: LCD _rs <= 1; // record
Row2_3: LCD _rs <= 1; // record
Row2_4: LCD _rs <= 1; // record
Row2_5: LCD _rs <= 1; // record
Row2_6: LCD _rs <= 1; // record
Row2_7: LCD _rs <= 1; // record
Row2_8: LCD _rs <= 1; // record
Row2_9: LCD _rs <= 1; // record
Row2_a: LCD _rs <= 1; // record
Row2_ B: LCD _rs <= 1; // record
Row2_c: LCD _rs <= 1; // record
Row2_d: LCD _rs <= 1; // record
Row2_e: LCD _rs <= 1; // record
Row2_f: LCD _rs <= 1; // record
Endcase
// Write LCD _data
Case (next_state)
Idle: LCD _data <= 8 'hxx;
// LCD init
Disp_set: LCD _data <= 8 'h38; // set 16x2, 5x7, 8 bits record
Disp_off: LCD _data <= 8 'h08; // off display
Clr_scr: LCD _data <= 8 'h01; // clear LCD
Cursor_set1: LCD _data <= 8 'h06; // cursor set
Cursor_set2: LCD _data <= 8 'h0c; // on display
// Display 1th line
Row1_addr: LCD _data <= 8'h80;
Row1_0: LCD _data <= line_rom1 [:120];
Row1_1: LCD _data <= line_rom1 [119:112];
Row1_2: LCD _data <= line_rom1 [11:104];
Row1_3: LCD _data <= line_rom1 [103: 96];
Row1_4: LCD _data <= line_rom1 [95: 88];
Row1_5: LCD _data <= line_rom1 [87: 80];
Row1_6: LCD _data <= line_rom1 [79: 72];
Row1_7: LCD _data <= line_rom1 [71: 64];
Row1_8: LCD _data <= line_rom1 [63: 56];
Row1_9: LCD _data <= line_rom1 [55: 48];
Row1_a: LCD _data <= line_rom1 [47: 40];
Row1_ B: LCD _data <= line_rom1 [39: 32];
Row1_c: LCD _data <= line_rom1 [31: 24];
Row1_d: LCD _data <= line_rom1 [23: 16];
Row1_e: LCD _data <= line_rom1 [15: 8];
Row1_f: LCD _data <= line_rom1 [7: 0];
// Display 2th line
Row2_addr: LCD _data <= 8'hc0;
Row2_0: LCD _data <= line_rom2 [:120];
Row2_1: LCD _data <= line_rom2 [119:112];
Row2_2: LCD _data <= line_rom2 [11:104];
Row2_3: LCD _data <= line_rom2 [103: 96];
Row2_4: LCD _data <= line_rom2 [95: 88];
Row2_5: LCD _data <= line_rom2 [87: 80];
Row2_6: LCD _data <= line_rom2 [79: 72];
Row2_7: LCD _data <= line_rom2 [71: 64];
Row2_8: LCD _data <= line_rom2 [63: 56];
Row2_9: LCD _data <= line_rom2 [55: 48];
Row2_a: LCD _data <= line_rom2 [47: 40];
Row2_ B: LCD _data <= line_rom2 [39: 32];
Row2_c: LCD _data <= line_rom2 [31: 24];
Row2_d: LCD _data <= line_rom2 [23: 16];
Row2_e: LCD _data <= line_rom2 [15: 8];
Row2_f: LCD _data <= line_rom2 [7: 0];
Endcase
End
End
Endmodule
2. State Machine
(1) The following is the state machine:
(2) The module can be divided into several statuses.
3. "Hello World" physical display
Parameter [expiration :0] line_rom1 = "I am crazybingo! ";
Parameter [expiration :0] line_rom2 = "Hello world * ^_^ *";