//Set parameters parameter IDLE = 4'b0000; //initial state parameter CLEAR = 4'b0001; //clear parameter RETURN = 4'b0011; //return home parameter MODE = 4'b0010; //entry mode set parameter DISPLAY= 4'b0110; //display ON/OFF control parameter SHIFT= 4'b0111; //cursor or display shift parameter FUNCTION = 4'b0101; //function set parameter CGRAM = 4'b0100; //set CGRAM address parameter DDRAM = 4'b1100; //set DDRAM address parameter WRITE = 4'b1101; //write data to RAMparameter STOP = 4'b1111; //release control
采用格雷码编码的好处是状态转移时相邻状态只需跳转移位,这样可以降低功耗(在大规模数字IC设计中很明显),也可避免一些时序上的问题。
接下来就是状态机的主体了: always@(posedge LCD_clk or negedge rst_n) begin if(!rst_n) begin state <= IDLE; LCD_DATA <= 8'bzzzz_zzzz; char_cnt <= 6'd0; end else begin case(state) //start IDLE:begin state <= CLEAR; LCD_DATA <= 8'bzzzz_zzzz; end //clear CLEAR:begin state <= RETURN; LCD_DATA <= 8`b00000001; //清屏 end //home RETURN:begin state <= MODE; LCD_DATA <= 8`b00000010; //光标返回 end //cursor move to the right //display don't move MODE:begin state <= DISPLAY; LCD_DATA <= 8'b0000_0110; //光标右移,显示不动 end //display on //cursor and blinking of cursor off DISPLAY:begin state <= SHIFT; LCD_DATA <= 8'b0000_1100; //开整体显示,有光标,不闪烁 end //cursor moving 光标或显示移位 //move to the right SHIFT:begin state <= FUNCTION; LCD_DATA <= 8'b0001_0100; //右移光标, end //功能设置命令 //Set interface data length(8-bit) //numbers of display line(2-line) //display font type(5*7 dots) FUNCTION:begin state <= DDRAM; LCD_DATA <= 8'b0011_1000; end //Set DDRAM address in address cnter DDRAM:begin state <= WRITE; if(char_cnt <=11) LCD_DATA <= 8'b1000_0000; //显示数据存储器地址80 else LCD_DATA <= 8'b1100_0000; //显示数据存储器地址80+40 end //Write data into internal RAM WRITE:begin if(char_cnt == 11)begin state <= DDRAM; end else begin state <= WRITE; end if(char_cnt == 27)begin state <= STOP; end LCD_DATA <= data_display; char_cnt <= char_cnt + 1'b1; end //Finish STOP: state <= STOP; //Other state default:state <= IDLE; endcase end end