1赞

11回答

5收藏

小脚丫Step FPGA Starter Kit 上手指南

   关闭

回答|共 11 个

倒序浏览

11#

鸿鹄部落

发表于 2015-11-23 16:54:21 | 只看该作者

分享到:
实验案例-按键消抖


程序源码如下:
  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
复制代码
仿真结果如下图所示:


从仿真的波形观察按键前后的抖动没有触发key_out信号,整个按键过程中key_out信号只触发一次,最终实现消抖。
实际编译分配管脚信息如下:

编译加载按动KEY1,因为key_outLED1)信号为脉冲,眼睛分辨不出,我们观看key_flag_outLED2)的闪烁变化,OK


12#

鸿鹄部落

发表于 2015-11-23 17:34:42 | 只看该作者

下面为基于小脚丫FPGA开发板和Nokia5110液晶显示屏的数字时钟设计
框架如下:

数字时钟功能介绍:
按键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
复制代码
实际编译分配管脚信息如下:


编译加载后按照上面硬件连接,就OK了。









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

本版积分规则

关闭

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