12
返回列表 发新帖
楼主: 噗噗熊

小脚丫Step FPGA Starter Kit 上手指南

   关闭 [复制链接]
  • TA的每日心情
    奋斗
    2017-6-14 11:22
  • 签到天数: 44 天

    连续签到: 1 天

    [LV.5]常住居民I

    发表于 2015-11-23 16:54:21 | 显示全部楼层
    分享到:
    实验案例-按键消抖
    按键消抖时间.png
    keyboard.jpg
    程序源码如下:
    1. /**************************************************
    2. module: key_board
    3. author: wanganran
    4. description: elimination buffeting of keystroke, key_out go low-high-low when key_in go high-low-high
    5. input: clk_in,rst_n_in,key_in
    6. output: key_out,key_flag_out
    7. date: 2015.10.23
    8. **************************************************/
    9. module key_board #
    10. (
    11. parameter KEY_CLK_PERIOD=250000 //related with key_clk's frequency
    12. )
    13. (
    14. input clk_in,  //25mhz
    15. input rst_n_in,  //active with low
    16. input key_in,  //keyboard in, high for normal, low for press
    17. output key_out,  //key_out will have a pulse when key_in be pressed
    18. output reg key_flag_out  //flag for key_out's change, floating if not use
    19. );

    20. //key_clk = 100hz, duty cycle is 1/250000(one clk_in period)
    21. reg key_clk;
    22. reg[17:0] clk_cnt=0;
    23. always@(posedge clk_in or negedge rst_n_in)
    24.         begin
    25.                 if(!rst_n_in)
    26.                         begin
    27.                                 clk_cnt<=0;
    28.                                 key_clk<=0;
    29.                         end
    30.                 else if(clk_cnt==(KEY_CLK_PERIOD-1))
    31.                                 begin
    32.                                         clk_cnt<=0;
    33.                                         key_clk<=1;
    34.                                 end
    35.                 else begin
    36.                                 clk_cnt<=clk_cnt+1;  
    37.                                 key_clk<=0;
    38.                         end
    39.         end

    40. //delay to elimination buffeting of keystroke
    41. //every time the key was pressed,the key_out will have a pulse(one clk_in period)
    42. reg key_n_r1 = 0;
    43. reg key_n_r2 = 0;
    44. reg key_n_r3 = 0;
    45. reg key_n_r5 = 0;
    46. assign key_n = ~key_in;
    47. assign key_n_r4 = key_n_r2&key_n_r3;
    48. assign key_out = key_n_r4&(~key_n_r5);
    49. always@(posedge clk_in or negedge rst_n_in)
    50.         begin
    51.                 if(!rst_n_in)
    52.                         begin
    53.                                 key_n_r1<=0;
    54.                                 key_n_r2<=0;
    55.                                 key_n_r3<=0;
    56.                         end
    57.                 else begin
    58.                                 key_n_r1<=key_n;
    59.                                 key_n_r5<=key_n_r4;
    60.                                 if(key_clk)
    61.                                         begin
    62.                                                 key_n_r2<=key_n_r1;
    63.                                                 key_n_r3<=key_n_r2;
    64.                                         end
    65.                         end
    66.         end

    67. //key_flag_out turn over every time when key_out active
    68. //we can judge the key was pressed or not by check the key_flag_out
    69. //reg key_flag_out = 0;
    70. always@(posedge clk_in or negedge rst_n_in)
    71.         begin
    72.                 if(!rst_n_in) key_flag_out <= 0;
    73.                 else if(key_out) key_flag_out <= ~key_flag_out;
    74.         end
    75.        
    76. endmodule
    复制代码
    测试源码如下:
    1. /**************************************************
    2. module: key_board_test
    3. author: wanganran
    4. description: The testbench for module key_board
    5. input:
    6. output:
    7. date: 2015.11.05
    8. **************************************************/
    9. `timescale 1ns / 100ps

    10. module key_board_test;

    11. parameter CLK_PERIOD = 40;  //CLK_PERIOD=40ns, Frequency=25MHz

    12. reg sys_clk;
    13. initial
    14.         sys_clk = 1'b0;
    15. always
    16.         sys_clk = #(CLK_PERIOD/2) ~sys_clk;

    17. reg sys_rst_n;  //active low
    18. initial
    19.         begin
    20.                 sys_rst_n = 1'b0;
    21.                 #200;
    22.                 sys_rst_n = 1'b1;
    23.         end

    24. integer        ii;
    25. reg key_in;  //active low
    26. initial
    27.         begin
    28.                 key_in = 1'b1;
    29.                 #600;
    30.                 for(ii=0;ii<=3;ii=ii+1)  key_in = #50 ~key_in;
    31.                
    32.                 #50 key_in = 1'b0;
    33.                 #500 key_in = 1'b1;
    34.                
    35.                 for(ii=0;ii<=3;ii=ii+1)  key_in = #50 ~key_in;
    36.         end
    37.        
    38. parameter KEY_CLK_PERIOD=6; //related with key_clk's frequency
    39. wire key_out,key_flag_out;
    40. key_board #
    41. (
    42. .KEY_CLK_PERIOD(KEY_CLK_PERIOD)
    43. )
    44. key_board_uut
    45. (
    46. .clk_in(sys_clk),  //25mhz
    47. .rst_n_in(sys_rst_n),  //active with low
    48. .key_in(key_in),  //keyboard in, high for normal, low for press
    49. .key_out(key_out),  //key_out will have a pulse when key_in be pressed
    50. .key_flag_out(key_flag_out)  //flag for key_out's change, floating if not use
    51. );
    52.        
    53. Endmodule
    复制代码
    仿真结果如下图所示:
    3.png
    2.png
    从仿真的波形观察按键前后的抖动没有触发key_out信号,整个按键过程中key_out信号只触发一次,最终实现消抖。
    实际编译分配管脚信息如下:
    4.png
    编译加载按动KEY1,因为key_outLED1)信号为脉冲,眼睛分辨不出,我们观看key_flag_outLED2)的闪烁变化,OK


    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2017-6-14 11:22
  • 签到天数: 44 天

    连续签到: 1 天

    [LV.5]常住居民I

    发表于 2015-11-23 17:34:42 | 显示全部楼层
    下面为基于小脚丫FPGA开发板和Nokia5110液晶显示屏的数字时钟设计
    框架如下:
    程序设计框架.png
    数字时钟功能介绍:
    按键K1,模式调节,设计共分4中模式(运行模式、时针调节、分针调节、秒针调节),按动K1依次切换模式
    按键K2,时间调节,当数字时钟在时针调节、分针调节或秒针调节模式时,按动K2调节对应时间位
    硬件连接图中,程序复位控制线控制程序复位,断开重连设计复位
    程序源码如下:
    Digital_clock.v  顶层文件
    1. /**************************************************
    2. module: Digital_clock
    3. author: wanganran
    4. description: clock divide, generate pulse and 50 percent clock_div
    5. input: clk_in,rst_n_in
    6. output: clk_div_50per_out,clk_div_pulse_out,clk_div_pulse_out1
    7. date: 2015.10.23
    8. **************************************************/
    9. module Digital_clock
    10. (
    11. input clk_in,  //clk_in = 25mhz
    12. input rst_n_in,  //rst_n_in, active low
    13. input key1_set,  //clock mode select key
    14. input key2_up,  //clock time adapt key
    15. output led1_set,
    16. output led2_up,

    17. output lcd_rst_n_out,  //nokia5110 reset, active low
    18. output lcd_ce_n_out,  //nokia5110 chip select, active low
    19. output lcd_dc_out,  //nokia5110 data or command control
    20. output lcd_bl_out,  //nokia5110 backlight
    21. output lcd_clk_out,  //nokia5110 clock
    22. output lcd_data_out  //nokia5110 data
    23. );

    24. //reg rst_n_in = 1;

    25. wire scan_clk;
    26. wire key_clk;
    27. wire sec_clk;
    28. Clock_div Clock_div_uut
    29. (
    30. .clk_in(clk_in),  //clk_in = 25mhz
    31. .rst_n_in(rst_n_in),  //rst_n_in, active low
    32. .clk_div_50per_out(scan_clk),  //clock divide output, duty cycle is 50 percent
    33. .clk_div_pulse_out(key_clk),  //clock divide output, duty cycle = 1/CLK_DIV_PULSE_PERIOD(one clk_in period)
    34. .clk_div_pulse_out1(sec_clk)  //clock divide output, duty cycle = 1/CLK_DIV_PULSE_PERIOD1(one clk_in period)
    35. );

    36. wire set_en;
    37. wire up_en;
    38. wire led1_set;
    39. wire led2_up=s_data[0];
    40. key_board key_board_uut
    41. (
    42. .clk_in(clk_in),  //25mhz
    43. .key_clk_in(key_clk),  //replace key_clk
    44. .rst_n_in(rst_n_in),  //active with low
    45. .key_in(key1_set),  //keyboard in, high for normal, low for press
    46. .key_out(set_en),  //key_out will have a pulse when key_in be pressed
    47. .key_flag_out(led1_set),  //flag for key_out's change, floating if not use
    48. .key1_in(key2_up),  //keyboard in, high for normal, low for press
    49. .key1_out(up_en),  //key_out will have a pulse when key_in be pressed
    50. .key1_flag_out()  //flag for key_out's change, floating if not use
    51. );

    52. wire [7:0] h_set;
    53. wire [7:0] m_set;
    54. wire [7:0] s_set;
    55. clock_ctl clock_ctl_uut
    56. (
    57. .clk_in(clk_in),
    58. .rst_n_in(rst_n_in),
    59. .set_en(set_en),
    60. .h_set(h_set),
    61. .m_set(m_set),
    62. .s_set(s_set)
    63. );

    64. wire [7:0] h_data;
    65. wire [7:0] m_data;
    66. wire [7:0] s_data;
    67. Clock_cnt Clock_cnt_uut
    68. (
    69. .clk_in(clk_in),
    70. .rst_n_in(rst_n_in),
    71. .sec_clk(sec_clk),
    72. .up_en(up_en),
    73. .h_set(h_set),
    74. .m_set(m_set),
    75. .s_set(s_set),
    76. .h_data(h_data),
    77. .m_data(m_data),
    78. .s_data(s_data)
    79. );

    80. wire lcd_rst_n_out;
    81. wire lcd_ce_n_out;
    82. wire lcd_dc_out;
    83. wire lcd_bl_out;
    84. wire lcd_clk_out;
    85. wire lcd_data_out;
    86. LCD_nokia5110 LCD_nokia5110_uut
    87. (
    88. .clk_in(clk_in),  //clk_in = 25mhz
    89. .scan_clk_in(scan_clk),  //replace clk_div
    90. .rst_n_in(rst_n_in),  //rst_n_in, active low
    91. .data_in({h_data,m_data,s_data}),  //need to display
    92. .lcd_rst_n_out(lcd_rst_n_out),  //nokia5110 reset, active low
    93. .lcd_ce_n_out(lcd_ce_n_out),  //nokia5110 chip select, active low
    94. .lcd_dc_out(lcd_dc_out),  //nokia5110 data or command control
    95. .lcd_bl_out(lcd_bl_out),  //nokia5110 backlight
    96. .lcd_clk_out(lcd_clk_out),  //nokia5110 clock
    97. .lcd_data_out(lcd_data_out)  //nokia5110 data
    98. );

    99. endmodule
    复制代码
    Clock_div.v  时钟分频管理模块
    1. /**************************************************
    2. module: Clock_div
    3. author: wanganran
    4. description: clock divide, generate pulse and 50 percent clock_div
    5. input: clk_in,rst_n_in
    6. output: clk_div_50per_out,clk_div_pulse_out,clk_div_pulse_out1
    7. date: 2015.10.23
    8. **************************************************/
    9. module Clock_div
    10. (
    11. input clk_in,  //clk_in = 25mhz
    12. input rst_n_in,  //rst_n_in, active low
    13. output reg clk_div_50per_out,  //clock divide output, duty cycle is 50 percent
    14. output reg clk_div_pulse_out,  //clock divide output, duty cycle = 1/CLK_DIV_PULSE_PERIOD(one clk_in period)
    15. output reg clk_div_pulse_out1  //clock divide output, duty cycle = 1/CLK_DIV_PULSE_PERIOD1(one clk_in period)
    16. );

    17. parameter CLK_DIV_50PER_PERIOD=25000; //related with clk_div_50per_out's frequency
    18. parameter CLK_DIV_PULSE_PERIOD=250000; //related with clk_div_pulse_out's frequency
    19. parameter CLK_DIV_PULSE_PERIOD1=25000000; //related with clk_div_pulse_out1's frequency

    20. //clk_div_50per_out = clk_in/CLK_DIV_50PER_PERIOD, duty cycle is 50 percent
    21. //1000hz
    22. reg[24:0] cnt2=0;
    23. always@(posedge clk_in or negedge rst_n_in)
    24. begin
    25.         if(!rst_n_in)
    26.                 begin
    27.                         cnt2<=0;
    28.                         clk_div_50per_out<=0;
    29.                 end
    30.         else begin
    31.                 cnt2<=cnt2+1;  
    32.                 if(cnt2==(CLK_DIV_50PER_PERIOD-1)) cnt2<=0;
    33.                 if(cnt2<(CLK_DIV_50PER_PERIOD/2)) clk_div_50per_out<=0;
    34.                 else clk_div_50per_out<=1;
    35.         end
    36. end

    37. //clk_div_pulse_out = clk_in/CLK_DIV_PULSE_PERIOD, duty cycle is 1/CLK_DIV_PULSE_PERIOD(one clk_in period)
    38. //100hz
    39. reg[24:0] cnt1=0;
    40. always@(posedge clk_in or negedge rst_n_in)
    41.         begin
    42.                 if(!rst_n_in)
    43.                         begin
    44.                                 cnt1<=0;
    45.                                 clk_div_pulse_out<=0;
    46.                         end
    47.                 else if(cnt1==(CLK_DIV_PULSE_PERIOD-1))
    48.                                 begin
    49.                                         cnt1<=0;
    50.                                         clk_div_pulse_out<=1;
    51.                                 end
    52.                 else begin
    53.                                 cnt1<=cnt1+1;  
    54.                                 clk_div_pulse_out<=0;
    55.                         end
    56.         end

    57. //clk_div_pulse_out1 = clk_in/CLK_DIV_PULSE_PERIOD1, duty cycle is 1/CLK_DIV_PULSE_PERIOD1(one clk_in period)
    58. //1hz
    59. reg[24:0] cnt3=0;
    60. always@(posedge clk_in or negedge rst_n_in)
    61.         begin
    62.                 if(!rst_n_in)
    63.                         begin
    64.                                 cnt3<=0;
    65.                                 clk_div_pulse_out1<=0;
    66.                         end
    67.                 else if(cnt3==(CLK_DIV_PULSE_PERIOD1-1))
    68.                                 begin
    69.                                         cnt3<=0;
    70.                                         clk_div_pulse_out1<=1;
    71.                                 end
    72.                 else begin
    73.                                 cnt3<=cnt3+1;  
    74.                                 clk_div_pulse_out1<=0;
    75.                         end
    76.         end

    77. endmodule
    复制代码
    key_board.v  按键消抖控制模块
    1. /**************************************************
    2. module: key_board
    3. author: wanganran
    4. description: elimination buffeting of keystroke, key_out go low-high-low when key_in go high-low-high
    5. input: clk_in,rst_n_in,key_in
    6. output: key_out,key_flag_out
    7. date: 2015.10.23
    8. **************************************************/
    9. module key_board
    10. (
    11. input clk_in,  //25mhz
    12. input key_clk_in,  //replace key_clk
    13. input rst_n_in,  //active with low
    14. input key_in,  //keyboard in, high for normal, low for press
    15. output key_out,  //key_out will have a pulse when key_in be pressed
    16. output reg key_flag_out,  //flag for key_out's change, floating if not use

    17. input key1_in,  //keyboard in, high for normal, low for press
    18. output key1_out,  //key_out will have a pulse when key_in be pressed
    19. output reg key1_flag_out  //flag for key_out's change, floating if not use
    20. );

    21. parameter KEY_CLK_PERIOD=250000; //related with key_clk's frequency

    22. //key_clk = 100hz, duty cycle is 1/250000(one clk_in period)
    23. reg key_clk;
    24. reg[17:0] clk_cnt=0;
    25. always@(posedge clk_in or negedge rst_n_in)
    26.         begin
    27.                 if(!rst_n_in)
    28.                         begin
    29.                                 clk_cnt<=0;
    30.                                 key_clk<=0;
    31.                         end
    32.                 else if(clk_cnt==(KEY_CLK_PERIOD-1))
    33.                                 begin
    34.                                         clk_cnt<=0;
    35.                                         key_clk<=1;
    36.                                 end
    37.                 else begin
    38.                                 clk_cnt<=clk_cnt+1;  
    39.                                 key_clk<=0;
    40.                         end
    41.         end

    42. //delay to elimination buffeting of keystroke
    43. //every time the key was pressed,the key_out will have a pulse(one clk_in period)
    44. reg key_n_r1 = 0;
    45. reg key_n_r2 = 0;
    46. reg key_n_r3 = 0;
    47. reg key_n_r5 = 0;
    48. assign key_n = ~key_in;
    49. assign key_n_r4 = key_n_r2&key_n_r3;
    50. assign key_out = key_n_r4&(~key_n_r5);
    51. always@(posedge clk_in or negedge rst_n_in)
    52.         begin
    53.                 if(!rst_n_in)
    54.                         begin
    55.                                 key_n_r1<=0;
    56.                                 key_n_r2<=0;
    57.                                 key_n_r3<=0;
    58.                         end
    59.                 else begin
    60.                                 key_n_r1<=key_n;
    61.                                 key_n_r5<=key_n_r4;
    62.                                 if(key_clk_in)
    63.                                         begin
    64.                                                 key_n_r2<=key_n_r1;
    65.                                                 key_n_r3<=key_n_r2;
    66.                                         end
    67.                         end
    68.         end

    69. //key_flag_out turn over every time when key_out active
    70. //we can judge the key was pressed or not by check the key_flag_out
    71. reg key_flag_out = 0;
    72. always@(posedge clk_in or negedge rst_n_in)
    73.         begin
    74.                 if(!rst_n_in) key_flag_out <= 0;
    75.                 else if(key_out) key_flag_out <= ~key_flag_out;
    76.         end
    77.        
    78. //delay to elimination buffeting of keystroke
    79. //every time the key was pressed,the key_out will have a pulse(one clk_in period)
    80. reg key1_n_r1 = 0;
    81. reg key1_n_r2 = 0;
    82. reg key1_n_r3 = 0;
    83. reg key1_n_r5 = 0;
    84. assign key1_n = ~key1_in;
    85. assign key1_n_r4 = key1_n_r2&key1_n_r3;
    86. assign key1_out = key1_n_r4&(~key1_n_r5);
    87. always@(posedge clk_in or negedge rst_n_in)
    88.         begin
    89.                 if(!rst_n_in)
    90.                         begin
    91.                                 key1_n_r1<=0;
    92.                                 key1_n_r2<=0;
    93.                                 key1_n_r3<=0;
    94.                         end
    95.                 else begin
    96.                                 key1_n_r1<=key1_n;
    97.                                 key1_n_r5<=key1_n_r4;
    98.                                 if(key_clk_in)
    99.                                         begin
    100.                                                 key1_n_r2<=key1_n_r1;
    101.                                                 key1_n_r3<=key1_n_r2;
    102.                                         end
    103.                         end
    104.         end

    105. //key_flag_out turn over every time when key_out active
    106. //we can judge the key was pressed or not by check the key_flag_out
    107. reg key1_flag_out = 0;
    108. always@(posedge clk_in or negedge rst_n_in)
    109.         begin
    110.                 if(!rst_n_in) key1_flag_out <= 0;
    111.                 else if(key1_out) key1_flag_out <= ~key1_flag_out;
    112.         end
    113.        
    114. endmodule
    复制代码
    clock_ctl.v 模式控制模块
    1. /**************************************************
    2. module: clock_ctl
    3. author: wanganran
    4. description: digital clock mode controller
    5. input: clk_in,rst_n_in,set_en
    6. output: h_set,m_set,s_set
    7. date: 2015.10.23
    8. **************************************************/
    9. module clock_ctl
    10. (
    11. input clk_in,
    12. input rst_n_in,
    13. input set_en,
    14. output h_set,
    15. output m_set,
    16. output s_set
    17. );

    18. parameter[1:0] normal=2'b00,hour_set=2'b01,minute_set=2'b10,second_set=2'b11;

    19. reg h_set;
    20. reg m_set;
    21. reg s_set;
    22. reg[1:0] current_state,next_state;

    23. always@(posedge clk_in or negedge rst_n_in)
    24. begin
    25.         if(!rst_n_in) begin
    26.                                 current_state<=normal;
    27.                                 end
    28.         else current_state<=next_state;
    29. end

    30. always@(current_state or set_en)
    31. begin
    32.         case(current_state)
    33.         normal:    if(set_en)        next_state<=hour_set;
    34.                                 else                 next_state<=normal;
    35.         hour_set:  if(set_en)                next_state<=minute_set;
    36.                                 else                 next_state<=hour_set;
    37.         minute_set:if(set_en)                next_state<=second_set;
    38.                                 else                 next_state<=minute_set;
    39.         second_set:if(set_en)                next_state<=normal;
    40.                                 else                 next_state<=second_set;
    41.         endcase
    42. end

    43. always@(current_state)
    44. begin
    45.         case(current_state)
    46.         normal:                begin h_set<=0;m_set<=0;s_set<=0;end
    47.         hour_set:        begin h_set<=1;m_set<=0;s_set<=0;end
    48.         minute_set:        begin h_set<=0;m_set<=1;s_set<=0;end
    49.         second_set:        begin h_set<=0;m_set<=0;s_set<=1;end
    50.         endcase
    51. end

    52. endmodule
    复制代码
    Clock_cnt.v  时间调节模块
    1. /**************************************************
    2. module: Clock_cnt
    3. author: wanganran
    4. description: cpu of design,
    5. input: clk_in,rst_n_in,sec_clk,up_en,h_set,m_set,s_set,
    6. output: h_data,m_data,s_data
    7. date: 2015.10.23
    8. **************************************************/
    9. module Clock_cnt
    10. (
    11. input clk_in,
    12. input rst_n_in,
    13. input sec_clk,
    14. input up_en,
    15. input h_set,
    16. input m_set,
    17. input s_set,
    18. output [7:0] h_data,
    19. output [7:0] m_data,
    20. output [7:0] s_data
    21. );

    22. reg [7:0] hour=8'h08;  //reset display time
    23. reg [7:0] min=8'h30;  //reset display time
    24. reg [7:0] sec=8'h00;  //reset display time
    25. reg [2:0] ctl;

    26. assign h_data=ctl[2]?8'hbb:hour;
    27. assign m_data=ctl[1]?8'hbb:min;
    28. assign s_data=ctl[0]?8'hbb:sec;

    29. always@(posedge clk_in or negedge rst_n_in)
    30. begin
    31.         if(!rst_n_in)
    32.                 begin
    33.                         ctl<=3'd0;
    34.                         hour<=8'h08;
    35.                         min<=8'h30;
    36.                         sec<=8'h00;
    37.                 end
    38.         else
    39.                 begin
    40.                         if(h_set==0&&m_set==0&&s_set==0)//normal
    41.                                 begin
    42.                                         ctl<=3'd0;
    43.                                         if(sec_clk)
    44.                                                 begin
    45.                                                         if(sec==8'h59)//seconds counter
    46.                                                                 begin
    47.                                                                         sec<=8'h0;
    48.                                                                         if(min==8'h59)//minute counter
    49.                                                                                 begin
    50.                                                                                         min<=8'h0;
    51.                                                                                         if(hour==8'h23)//hour counter
    52.                                                                                                 hour<=8'h0;
    53.                                                                                         else                 //hour counter
    54.                                                                                                 begin
    55.                                                                                                         if(hour[3:0]==4'd9)
    56.                                                                                                                 begin
    57.                                                                                                                         hour[3:0]<=4'd0;
    58.                                                                                                                         hour[7:4]<=hour[7:4]+4'd1;
    59.                                                                                                                 end
    60.                                                                                                         else hour[3:0]<=hour[3:0]+4'd1;
    61.                                                                                                 end
    62.                                                                                 end
    63.                                                                         else begin//minute counter
    64.                                                                                         if(min[3:0]==4'd9)
    65.                                                                                                 begin
    66.                                                                                                         min[3:0]<=4'd0;
    67.                                                                                                         min[7:4]<=min[7:4]+4'd1;
    68.                                                                                                 end
    69.                                                                                         else min[3:0]<=min[3:0]+4'd1;
    70.                                                                                 end
    71.                                                                 end
    72.                                                         else
    73.                                                                 begin //seconds counter
    74.                                                                         if(sec[3:0]==4'd9)
    75.                                                                                 begin
    76.                                                                                         sec[3:0]<=4'd0;
    77.                                                                                         sec[7:4]<=sec[7:4]+4'd1;
    78.                                                                                 end
    79.                                                                         else sec[3:0]<=sec[3:0]+4'd1;
    80.                                                                 end
    81.                                                 end
    82.                                 end
    83.                         else if(h_set==1&&m_set==0&&s_set==0) //hour set
    84.                                 begin
    85.                                         if(up_en)                                 //up_en down
    86.                                                 begin
    87.                                                         ctl<=3'd0;
    88.                                                         if(hour==8'h23) hour<=8'h0;
    89.                                                         else begin  
    90.                                                                 if(hour[3:0]==4'd9)
    91.                                                                         begin
    92.                                                                                 hour[3:0]<=4'd0;
    93.                                                                                 hour[7:4]<=hour[7:4]+4'd1;
    94.                                                                         end
    95.                                                                 else hour[3:0]<=hour[3:0]+4'd1;
    96.                                                         end
    97.                                                 end
    98.                                         else if(sec_clk)
    99.                                                 begin
    100.                                                         ctl[2]<=~ctl[2];
    101.                                                         ctl[1:0]<=2'b00;
    102.                                                 end
    103.                                 end
    104.                         else if(h_set==0&&m_set==1&&s_set==0)
    105.                                 begin
    106.                                         if(up_en)
    107.                                                 begin
    108.                                                         ctl<=3'd0;
    109.                                                         if(min==8'h59) min<=8'h0;//minute set
    110.                                                         else begin  //minute set
    111.                                                                         if(min[3:0]==4'd9)
    112.                                                                                 begin
    113.                                                                                         min[3:0]<=4'd0;
    114.                                                                                         min[7:4]<=min[7:4]+4'd1;
    115.                                                                                 end
    116.                                                                         else min[3:0]<=min[3:0]+4'd1;
    117.                                                                 end
    118.                                                 end
    119.                                         else if(sec_clk)
    120.                                                 begin
    121.                                                         ctl[2]<=0;
    122.                                                         ctl[1]<=~ctl[1];
    123.                                                         ctl[0]<=0;
    124.                                                 end
    125.                                 end
    126.                         else if(h_set==0&&m_set==0&&s_set==1)
    127.                                 begin
    128.                                         if(up_en)
    129.                                                 begin
    130.                                                         ctl<=3'd0;
    131.                                                         if(sec==8'h59) sec<=8'h0;//second set
    132.                                                         else begin  //second set
    133.                                                                         if(sec[3:0]==4'd9)
    134.                                                                                 begin
    135.                                                                                         sec[3:0]<=4'd0;
    136.                                                                                         sec[7:4]<=sec[7:4]+4'd1;
    137.                                                                                 end
    138.                                                                         else sec[3:0]<=sec[3:0]+4'd1;
    139.                                                                 end
    140.                                                 end                                                          
    141.                                         else if(sec_clk)
    142.                                                         begin
    143.                                                                 ctl[2]<=0;
    144.                                                                 ctl[1]<=0;
    145.                                                                 ctl[0]<=~ctl[0];
    146.                                                         end
    147.                                 end
    148.                 end
    149. end

    150. endmodule
    复制代码
    LCD_nokia5110.v  Nokia5110液晶显示模块
    1. /**************************************************
    2. module: LCD_nokia5110
    3. author: wanganran
    4. description: drive Nokia5110 lcd display with fpga/cpld
    5.                         -ECBC 2015
    6.                         -10/23 23:30
    7. input: clk_in,rst_n_in,data_in
    8. output: rclk_out,sclk_out,sdio_out
    9. date: 2015.10.23
    10. **************************************************/
    11. module LCD_nokia5110
    12. (
    13. input clk_in,  //clk_in = 25mhz
    14. input scan_clk_in,  //replace clk_div
    15. input rst_n_in,  //rst_n_in, active low
    16. input [23:0] data_in,  //need to display
    17. output lcd_rst_n_out,  //nokia5110 reset, active low
    18. output reg lcd_ce_n_out,  //nokia5110 chip select, active low
    19. output reg lcd_dc_out,  //nokia5110 data or command control
    20. output lcd_bl_out,  //nokia5110 backlight
    21. output lcd_clk_out,  //nokia5110 clock
    22. output reg lcd_data_out  //nokia5110 data
    23. );

    24. parameter CLK_DIV_PERIOD=20; //related with clk_div's frequency
    25. parameter DELAY_PERIOD=10000;  //related with delay time and refresh frequency

    26. parameter CLK_L=2'd0;
    27. parameter CLK_H=2'd1;
    28. parameter CLK_RISING_DEGE=2'd2;
    29. parameter CLK_FALLING_DEGE=2'd3;

    30. parameter IDLE=3'd0;
    31. parameter SHIFT=3'd1;
    32. parameter CLEAR=3'd2;
    33. parameter SETXY=3'd3;
    34. parameter DISPLAY=3'd4;
    35. parameter DELAY=3'd5;

    36. parameter LOW =1'b0;
    37. parameter HIGH =1'b1;
    38. parameter CMD =1'b0;
    39. parameter DATA =1'b1;

    40. assign lcd_rst_n_out = 1;  //active low level, set 1 for normal
    41. assign lcd_bl_out = 1;  //backlight active high level
    42. assign lcd_clk_out = clk_div; //////////////////////////////////////scan_clk_in;

    43. //initial for memory register
    44. reg [47:0] mem [91:0];
    45. reg [47:0] temp;
    46. initial
    47.         begin
    48.                 mem[0]= {8'h00, 8'h00, 8'h56, 8'h36, 8'h00, 8'h00};   // 0 ;
    49.                 mem[1]= {8'h00, 8'h00, 8'h00, 8'h2f, 8'h00, 8'h00};   // 1  !  
    50.                 mem[2]= {8'h00, 8'h00, 8'h07, 8'h00, 8'h07, 8'h00};   // 2  
    51.                 mem[3]= {8'h00, 8'h14, 8'h7f, 8'h14, 8'h7f, 8'h14};   // 3  #
    52.                 mem[4]= {8'h00, 8'h24, 8'h2a, 8'h7f, 8'h2a, 8'h12};   // 4  $
    53.                 mem[5]= {8'h00, 8'h62, 8'h64, 8'h08, 8'h13, 8'h23};   // 5  %
    54.                 mem[6]= {8'h00, 8'h36, 8'h49, 8'h55, 8'h22, 8'h50};   // 6  &
    55.                 mem[7]= {8'h00, 8'h00, 8'h05, 8'h03, 8'h00, 8'h00};   // 7  '
    56.                 mem[8]= {8'h00, 8'h00, 8'h1c, 8'h22, 8'h41, 8'h00};   // 8  {
    57.                 mem[9]= {8'h00, 8'h00, 8'h41, 8'h22, 8'h1c, 8'h00};   // 9  )
    58.                 mem[10]= {8'h00, 8'h14, 8'h08, 8'h3E, 8'h08, 8'h14};   // 10 *
    59.                 mem[11]= {8'h00, 8'h08, 8'h08, 8'h3E, 8'h08, 8'h08};   // 11 +
    60.                 mem[12]= {8'h00, 8'h00, 8'h00, 8'hA0, 8'h60, 8'h00};   // 12 ,
    61.                 mem[13]= {8'h00, 8'h08, 8'h08, 8'h08, 8'h08, 8'h08};   // 13 -
    62.                 mem[14]= {8'h00, 8'h00, 8'h60, 8'h60, 8'h00, 8'h00};   // 14 .
    63.                 mem[15]= {8'h00, 8'h20, 8'h10, 8'h08, 8'h04, 8'h02};   // 15 /
    64.                 mem[16]= {8'h00, 8'h3E, 8'h51, 8'h49, 8'h45, 8'h3E};   // 16 0
    65.                 mem[17]= {8'h00, 8'h00, 8'h42, 8'h7F, 8'h40, 8'h00};   // 17 1
    66.                 mem[18]= {8'h00, 8'h42, 8'h61, 8'h51, 8'h49, 8'h46};   // 18 2
    67.                 mem[19]= {8'h00, 8'h21, 8'h41, 8'h45, 8'h4B, 8'h31};   // 19 3
    68.                 mem[20]= {8'h00, 8'h18, 8'h14, 8'h12, 8'h7F, 8'h10};   // 20 4
    69.                 mem[21]= {8'h00, 8'h27, 8'h45, 8'h45, 8'h45, 8'h39};   // 21 5
    70.                 mem[22]= {8'h00, 8'h3C, 8'h4A, 8'h49, 8'h49, 8'h30};   // 22 6
    71.                 mem[23]= {8'h00, 8'h01, 8'h71, 8'h09, 8'h05, 8'h03};   // 23 7
    72.                 mem[24]= {8'h00, 8'h36, 8'h49, 8'h49, 8'h49, 8'h36};   // 24 8
    73.                 mem[25]= {8'h00, 8'h06, 8'h49, 8'h49, 8'h29, 8'h1E};   // 25 9
    74.                 mem[26]= {8'h00, 8'h00, 8'h36, 8'h36, 8'h00, 8'h00};   // 26 :
    75.                 mem[27]= {8'h00, 8'h00, 8'h00, 8'h00, 8'h00, 8'h00};   // 27  sp
    76.                 mem[28]= {8'h00, 8'h08, 8'h14, 8'h22, 8'h41, 8'h00};   // 28 <
    77.                 mem[29]= {8'h00, 8'h14, 8'h14, 8'h14, 8'h14, 8'h14};   // 29 =
    78.                 mem[30]= {8'h00, 8'h00, 8'h41, 8'h22, 8'h14, 8'h08};   // 30 >
    79.                 mem[31]= {8'h00, 8'h02, 8'h01, 8'h51, 8'h09, 8'h06};   // 31 ?
    80.                 mem[32]= {8'h00, 8'h32, 8'h49, 8'h59, 8'h51, 8'h3E};   // 32 @
    81.                 mem[33]= {8'h00, 8'h7C, 8'h12, 8'h11, 8'h12, 8'h7C};   // 33 A
    82.                 mem[34]= {8'h00, 8'h7F, 8'h49, 8'h49, 8'h49, 8'h36};   // 34 B
    83.                 mem[35]= {8'h00, 8'h3E, 8'h41, 8'h41, 8'h41, 8'h22};   // 35 C
    84.                 mem[36]= {8'h00, 8'h7F, 8'h41, 8'h41, 8'h22, 8'h1C};   // 36 D
    85.                 mem[37]= {8'h00, 8'h7F, 8'h49, 8'h49, 8'h49, 8'h41};   // 37 E
    86.                 mem[38]= {8'h00, 8'h7F, 8'h09, 8'h09, 8'h09, 8'h01};   // 38 F
    87.                 mem[39]= {8'h00, 8'h3E, 8'h41, 8'h49, 8'h49, 8'h7A};   // 39 G
    88.                 mem[40]= {8'h00, 8'h7F, 8'h08, 8'h08, 8'h08, 8'h7F};   // 40 H
    89.                 mem[41]= {8'h00, 8'h00, 8'h41, 8'h7F, 8'h41, 8'h00};   // 41 I
    90.                 mem[42]= {8'h00, 8'h20, 8'h40, 8'h41, 8'h3F, 8'h01};   // 42 J
    91.                 mem[43]= {8'h00, 8'h7F, 8'h08, 8'h14, 8'h22, 8'h41};   // 43 K
    92.                 mem[44]= {8'h00, 8'h7F, 8'h40, 8'h40, 8'h40, 8'h40};   // 44 L
    93.                 mem[45]= {8'h00, 8'h7F, 8'h02, 8'h0C, 8'h02, 8'h7F};   // 45 M
    94.                 mem[46]= {8'h00, 8'h7F, 8'h04, 8'h08, 8'h10, 8'h7F};   // 46 N
    95.                 mem[47]= {8'h00, 8'h3E, 8'h41, 8'h41, 8'h41, 8'h3E};   // 47 O
    96.                 mem[48]= {8'h00, 8'h7F, 8'h09, 8'h09, 8'h09, 8'h06};   // 48 P
    97.                 mem[49]= {8'h00, 8'h3E, 8'h41, 8'h51, 8'h21, 8'h5E};   // 49 Q
    98.                 mem[50]= {8'h00, 8'h7F, 8'h09, 8'h19, 8'h29, 8'h46};   // 50 R
    99.                 mem[51]= {8'h00, 8'h46, 8'h49, 8'h49, 8'h49, 8'h31};   // 51 S
    100.                 mem[52]= {8'h00, 8'h01, 8'h01, 8'h7F, 8'h01, 8'h01};   // 52 T
    101.                 mem[53]= {8'h00, 8'h3F, 8'h40, 8'h40, 8'h40, 8'h3F};   // 53 U
    102.                 mem[54]= {8'h00, 8'h1F, 8'h20, 8'h40, 8'h20, 8'h1F};   // 54 V
    103.                 mem[55]= {8'h00, 8'h3F, 8'h40, 8'h38, 8'h40, 8'h3F};   // 55 W
    104.                 mem[56]= {8'h00, 8'h63, 8'h14, 8'h08, 8'h14, 8'h63};   // 56 X
    105.                 mem[57]= {8'h00, 8'h07, 8'h08, 8'h70, 8'h08, 8'h07};   // 57 Y
    106.                 mem[58]= {8'h00, 8'h61, 8'h51, 8'h49, 8'h45, 8'h43};   // 58 Z
    107.                 mem[59]= {8'h00, 8'h00, 8'h7F, 8'h41, 8'h41, 8'h00};   // 59 [
    108.                 mem[60]= {8'h00, 8'h55, 8'h2A, 8'h55, 8'h2A, 8'h55};   // 60 .
    109.                 mem[61]= {8'h00, 8'h00, 8'h41, 8'h41, 8'h7F, 8'h00};   // 61 ]
    110.                 mem[62]= {8'h00, 8'h04, 8'h02, 8'h01, 8'h02, 8'h04};   // 62 ^
    111.                 mem[63]= {8'h00, 8'h40, 8'h40, 8'h40, 8'h40, 8'h40};   // 63 _
    112.                 mem[64]= {8'h00, 8'h00, 8'h01, 8'h02, 8'h04, 8'h00};   // 64 '
    113.                 mem[65]= {8'h00, 8'h20, 8'h54, 8'h54, 8'h54, 8'h78};   // 65 a
    114.                 mem[66]= {8'h00, 8'h7F, 8'h48, 8'h44, 8'h44, 8'h38};   // 66 b
    115.                 mem[67]= {8'h00, 8'h38, 8'h44, 8'h44, 8'h44, 8'h20};   // 67 c
    116.                 mem[68]= {8'h00, 8'h38, 8'h44, 8'h44, 8'h48, 8'h7F};   // 68 d
    117.                 mem[69]= {8'h00, 8'h38, 8'h54, 8'h54, 8'h54, 8'h18};   // 69 e
    118.                 mem[70]= {8'h00, 8'h08, 8'h7E, 8'h09, 8'h01, 8'h02};   // 70 f
    119.                 mem[71]= {8'h00, 8'h18, 8'hA4, 8'hA4, 8'hA4, 8'h7C};   // 71 g
    120.                 mem[72]= {8'h00, 8'h7F, 8'h08, 8'h04, 8'h04, 8'h78};   // 72 h
    121.                 mem[73]= {8'h00, 8'h00, 8'h44, 8'h7D, 8'h40, 8'h00};   // 73 i
    122.                 mem[74]= {8'h00, 8'h40, 8'h80, 8'h84, 8'h7D, 8'h00};   // 74 j
    123.                 mem[75]= {8'h00, 8'h7F, 8'h10, 8'h28, 8'h44, 8'h00};   // 75 k
    124.                 mem[76]= {8'h00, 8'h00, 8'h41, 8'h7F, 8'h40, 8'h00};   // 76 l
    125.                 mem[77]= {8'h00, 8'h7C, 8'h04, 8'h18, 8'h04, 8'h78};   // 77 m
    126.                 mem[78]= {8'h00, 8'h7C, 8'h08, 8'h04, 8'h04, 8'h78};   // 78 n
    127.                 mem[79]= {8'h00, 8'h38, 8'h44, 8'h44, 8'h44, 8'h38};   // 79 o
    128.                 mem[80]= {8'h00, 8'hFC, 8'h24, 8'h24, 8'h24, 8'h18};   // 80 p
    129.                 mem[81]= {8'h00, 8'h18, 8'h24, 8'h24, 8'h18, 8'hFC};   // 81 q
    130.                 mem[82]= {8'h00, 8'h7C, 8'h08, 8'h04, 8'h04, 8'h08};   // 82 r
    131.                 mem[83]= {8'h00, 8'h48, 8'h54, 8'h54, 8'h54, 8'h20};   // 83 s
    132.                 mem[84]= {8'h00, 8'h04, 8'h3F, 8'h44, 8'h40, 8'h20};   // 84 t
    133.                 mem[85]= {8'h00, 8'h3C, 8'h40, 8'h40, 8'h20, 8'h7C};   // 85 u
    134.                 mem[86]= {8'h00, 8'h1C, 8'h20, 8'h40, 8'h20, 8'h1C};   // 86 v
    135.                 mem[87]= {8'h00, 8'h3C, 8'h40, 8'h30, 8'h40, 8'h3C};   // 87 w
    136.                 mem[88]= {8'h00, 8'h44, 8'h28, 8'h10, 8'h28, 8'h44};   // 88 x
    137.                 mem[89]= {8'h00, 8'h1C, 8'hA0, 8'hA0, 8'hA0, 8'h7C};   // 89 y
    138.                 mem[90]= {8'h00, 8'h44, 8'h64, 8'h54, 8'h4C, 8'h44};   // 90 z
    139.                 mem[91]= {8'h14, 8'h14, 8'h14, 8'h14, 8'h14, 8'h14};   // 91 horiz lines
    140.         end

    141. //clk_div = clk_in/CLK_DIV_PERIOD = 500khz, 50% is high voltage
    142. reg clk_div;
    143. reg[15:0] clk_cnt=0;
    144. always@(posedge clk_in or negedge rst_n_in)
    145. begin
    146.         if(!rst_n_in) clk_cnt<=0;
    147.         else begin
    148.                 clk_cnt<=clk_cnt+1;  
    149.                 if(clk_cnt==(CLK_DIV_PERIOD-1)) clk_cnt<=0;
    150.                 if(clk_cnt<(CLK_DIV_PERIOD/2)) clk_div<=0;
    151.                 else clk_div<=1;
    152.         end
    153. end

    154. //divide clk_div 4 state, RISING and FALLING state is keeped one cycle of clk_in, like a pulse.
    155. reg[1:0] clk_div_state=CLK_L;  
    156. always@(posedge clk_in or negedge rst_n_in)
    157. begin
    158.         if(!rst_n_in) clk_div_state<=CLK_L;
    159.     else
    160.                 case(clk_div_state)
    161.                         CLK_L: begin
    162.                                         if (clk_div) clk_div_state<=CLK_RISING_DEGE;  ////////////////////////////////
    163.                                         else clk_div_state<=CLK_L;
    164.                                 end
    165.                         CLK_RISING_DEGE :clk_div_state<=CLK_H;  
    166.                         CLK_H:begin                 
    167.                                         if (!clk_div) clk_div_state<=CLK_FALLING_DEGE;////////////////////////////////
    168.                                         else clk_div_state<=CLK_H;
    169.                                 end
    170.                         CLK_FALLING_DEGE:clk_div_state<=CLK_L;  
    171.                         default;
    172.                 endcase
    173. end

    174. reg shift_flag = 0;
    175. reg[6:0] x_reg;
    176. reg[2:0] y_reg;   
    177. reg[7:0] char_reg;
    178. reg[8:0] temp_cnt;
    179. reg[7:0] data_reg;
    180. reg[2:0] data_state=IDLE;
    181. reg[2:0] data_state_back;
    182. reg[7:0] data_state_cnt=0;  
    183. reg[3:0] shift_cnt=0;
    184. reg[25:0] delay_cnt=0;  
    185. //Finite State Machine,
    186. always@(posedge clk_in or negedge rst_n_in)      
    187. begin
    188.         if(!rst_n_in)
    189.                 begin
    190.                         data_state<=IDLE;
    191.                         data_state_cnt<=0;
    192.                         shift_flag <= 0;
    193.                         lcd_ce_n_out<=HIGH;
    194.                 end
    195.     else
    196.                 case (data_state)
    197.                         IDLE: begin
    198.                                         lcd_ce_n_out<=HIGH;
    199.                                         data_state_cnt<=data_state_cnt+1;
    200.                                         case(data_state_cnt)
    201.                                                 0: begin data_reg<=8'h21;lcd_dc_out<=CMD;data_state<=SHIFT;data_state_back<=IDLE; end
    202.                                                 1: begin data_reg<=8'hc8;lcd_dc_out<=CMD;data_state<=SHIFT;data_state_back<=IDLE; end
    203.                                                 2: begin data_reg<=8'h06;lcd_dc_out<=CMD;data_state<=SHIFT;data_state_back<=IDLE; end
    204.                                                 3: begin data_reg<=8'h13;lcd_dc_out<=CMD;data_state<=SHIFT;data_state_back<=IDLE; end
    205.                                                 4: begin data_reg<=8'h20;lcd_dc_out<=CMD;data_state<=SHIFT;data_state_back<=IDLE; end
    206.                                                 5: begin data_reg<=8'h0c;lcd_dc_out<=CMD;data_state<=SHIFT;data_state_back<=IDLE; end
    207.                                                 6: begin data_state<=CLEAR;data_state_back<=CLEAR; end
    208.                                                
    209.                                                 7: begin data_state<=SETXY;data_state_back<=SETXY;x_reg<=7'b0000010;y_reg<=3'b001; end
    210.                                                 8: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=37; end  //E
    211.                                                 9: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=35; end  //C
    212.                                                 10: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=34; end  //B
    213.                                                 11: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=35; end  //C
    214.                                                
    215.                                                 12: begin data_state<=SETXY;data_state_back<=SETXY;x_reg<=7'b0000010;y_reg<=3'b010; end
    216.                                                 13: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=87; end  //w
    217.                                                 14: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=65; end  //a
    218.                                                 15: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=78; end  //n
    219.                                                 16: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=71; end  //g
    220.                                                 17: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=27; end  //
    221.                                                 18: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=65; end  //a
    222.                                                 19: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=78; end  //n
    223.                                                 20: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=82; end  //r
    224.                                                 21: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=65; end  //a
    225.                                                 22: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=78; end  //n
    226.                                                
    227.                                                 23: begin data_state<=SETXY;data_state_back<=SETXY;x_reg<=7'b0000010;y_reg<=3'b100; end
    228.                                                 24: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=data_in[23:20]+16; end  //hour
    229.                                                 25: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=data_in[19:16]+16; end  //hour
    230.                                                 26: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=26; end
    231.                                                 27: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=data_in[15:12]+16; end  //min
    232.                                                 28: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=data_in[11:8]+16; end  //min
    233.                                                 29: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=26; end
    234.                                                 30: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=data_in[7:4]+16; end  //sec
    235.                                                 31: begin data_state<=DISPLAY;data_state_back<=DISPLAY;char_reg<=data_in[3:0]+16; end  //sec

    236.                                                 32: begin data_state_cnt<=23; end
    237.                                                 default;
    238.                                         endcase
    239.                                 end
    240.                                
    241.                         SHIFT: begin
    242.                                         if(!shift_flag)
    243.                                                 begin
    244.                                                         if (clk_div_state==CLK_FALLING_DEGE)  
    245.                                                                 begin
    246.                                                                         if (shift_cnt==8)  
    247.                                                                                 begin
    248.                                                                                         shift_cnt<=0;
    249.                                                                                         data_state<=data_state_back;
    250.                                                                                 end
    251.                                                                         else begin
    252.                                                                                         lcd_ce_n_out<=LOW;
    253.                                                                                         lcd_data_out<=data_reg[7];   
    254.                                                                                         shift_flag <= 1;
    255.                                                                                 end
    256.                                                                 end
    257.                                                 end
    258.                                         else
    259.                                                 begin
    260.                                                         if (clk_div_state==CLK_RISING_DEGE)   
    261.                                                                 begin  
    262.                                                                         data_reg<={data_reg[6:0], data_reg[7]};  
    263.                                                                         shift_cnt<=shift_cnt+1;
    264.                                                                         shift_flag <= 0;
    265.                                                                 end
    266.                                                 end
    267.                                 end

    268.                         CLEAR: begin            
    269.                                         data_reg<=8'h00;
    270.                                         temp_cnt<=temp_cnt+1;
    271.                                         lcd_ce_n_out<=HIGH;
    272.                                         lcd_dc_out<=DATA;
    273.                                         if (temp_cnt==504)
    274.                                                 begin
    275.                                                         temp_cnt<=0;
    276.                                                         data_state<=IDLE;
    277.                                                 end
    278.                                         else data_state<=SHIFT;
    279.                                 end
    280.                                
    281.                         SETXY: begin
    282.                                         temp_cnt<=temp_cnt+1;
    283.                                         lcd_ce_n_out<=HIGH;
    284.                                         lcd_dc_out<=CMD;
    285.                                         case (temp_cnt)
    286.                                                 0 : begin data_reg<=(8'h80 | x_reg); data_state<=SHIFT; end
    287.                                                 1 : begin data_reg<=(8'h40 | y_reg); data_state<=SHIFT; end
    288.                                                 2 : begin data_state<=IDLE; temp_cnt<=0; end
    289.                                                 default;
    290.                                         endcase
    291.                                 end

    292.                         DISPLAY: begin
    293.                                                 temp_cnt<=temp_cnt+1;
    294.                                                 lcd_ce_n_out<=HIGH;
    295.                                                 lcd_dc_out<=DATA;
    296.                                                 if (temp_cnt==6)
    297.                                                         begin
    298.                                                                 data_state<=IDLE;
    299.                                                                 temp_cnt<=0;
    300.                                                         end
    301.                                                 else
    302.                                                         begin
    303.                                                                 temp=mem[char_reg];
    304.                                                                 case (temp_cnt)
    305.                                                                         0 :  data_reg<=temp[47:40];
    306.                                                                         1 :  data_reg<=temp[39:32];
    307.                                                                         2 :  data_reg<=temp[31:24];
    308.                                                                         3 :  data_reg<=temp[23:16];
    309.                                                                         4 :  data_reg<=temp[15:8];
    310.                                                                         5 :  data_reg<=temp[7:0];
    311.                                                                         default;
    312.                                                                 endcase
    313.                                                                 data_state<=SHIFT;
    314.                                                         end
    315.                                         end

    316.                         DELAY: begin
    317.                                         if(delay_cnt==DELAY_PERIOD)
    318.                                                 begin
    319.                                                         data_state<=IDLE;
    320.                                                         delay_cnt<=0;
    321.                                                 end
    322.                                         else delay_cnt<=delay_cnt+1;
    323.                                 end
    324.                                           
    325.                         default;
    326.                 endcase
    327. end

    328. endmodule
    复制代码
    实际编译分配管脚信息如下:
    2015-11-23 17-12-58.png
    硬件连线图.png
    编译加载后按照上面硬件连接,就OK了。









    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-3-29 12:36 , Processed in 0.119688 second(s), 16 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.