FPGA sample - 如何使用七段顯示器

在範例中,會使用一個 12 位元計數器,每一秒會加一,再把計數器的值使用七段顯示器,把它顯示出來.

整個範例的方塊圖如下:

範例方塊可以分成:
  • 1 second timer : 使用一個 50_000_000 的計數器, 因為輸入時脈為 50MHz, 計數到 50_000_000 就剛好 1 second.
  • 12 bits counter : 每一秒將計數器加一.
  • 7 segment led : 把 12 bits counter 的值, 轉成七段顯示器的控制碼.
  • 7 bits counter : 用來選擇那一個七段顯示器顯示 12 bits counter 的值. 使用視覺暫留的原理,讓數值看起來是一起顯示的.
1 second timer 的程式碼 :
  1. reg[31:0] T1secTimer; // value of 1 second timer
  2.  
  3. //-----------------------------------------------------------
  4. // function : 1 sec timer
  5. // input : clk (clock) 50MHz
  6. // : rst_n (reset)
  7. // output : none
  8. //-----------------------------------------------------------
  9. always @ (posedge clk or negedge rst_n)
  10. if(!rst_n)
  11. T1secTimer <= 31'd0; // reset state
  12. else if(T1secTimer >= 31'd50_000_000)
  13. T1secTimer <= 31'd0; // 1 second timer timeout
  14. else
  15. T1secTimer <= T1secTimer+1'b1;
  16. wire timer_1s = (T1secTimer == 31'd50_000_000);
12 bits counter 的程式碼 :
  1. reg[11:0] counter;
  2.  
  3. //-----------------------------------------------------------
  4. // function : counter by 1 second
  5. // input : clk (clock) 50MHz
  6. // : rst_n (reset)
  7. // output : none
  8. //-----------------------------------------------------------
  9. always @ (posedge clk or negedge rst_n)
  10. if(!rst_n)
  11. counter <= 12'd0; // reset state
  12. else if(timer_1s)
  13. counter <= counter+1'b1;
  14. else ;
  15.  
7 segment led decoder 的程式碼 :
  1. reg[3:0] SegLedData;
  2. //-----------------------------------------------------------
  3. // function : display byte of counter
  4. // input : clk (clock) 50MHz
  5. // : rst_n (reset)
  6. // output : none
  7. //-----------------------------------------------------------
  8. always @ (posedge clk or negedge rst_n)
  9. if(!rst_n)
  10. SegLedData <= 4'd0;
  11. else begin
  12. case(T1secTimer[8:7])
  13. 2'b00: // display nibble #0 of counter
  14. begin
  15. seg_cs <= 3'b100;
  16. SegLedData <= counter[3:0];
  17. end
  18.  
  19. 2'b01: // display nibble #1 of counter
  20. begin
  21. seg_cs <= 3'b010;
  22. SegLedData <= counter[7:4];
  23. end
  24.  
  25. 2'b10: // display nibble #2 of counter
  26. begin
  27. seg_cs <= 3'b001;
  28. SegLedData <= counter[11:8];
  29. end
  30.  
  31. default: ;
  32. endcase
  33. end
  34.  
  35. //-------------------------------------------------
  36. // bit assign : DP.G.F.E.D.C.B.A
  37. // 0 : On / 1 : Off
  38. //-------------------------------------------------
  39. parameter SEG_NUM0 = 8'hC0, //c0,
  40. SEG_NUM1 = 8'hF9, //f9,
  41. SEG_NUM2 = 8'hA4, //a4,
  42. SEG_NUM3 = 8'hB0, //b0,
  43. SEG_NUM4 = 8'h99, //99,
  44. SEG_NUM5 = 8'h92, //92,
  45. SEG_NUM6 = 8'h82, //82,
  46. SEG_NUM7 = 8'hF8, //F8,
  47. SEG_NUM8 = 8'h80, //80,
  48. SEG_NUM9 = 8'h90, //90,
  49. SEG_NUMA = 8'h88, //88,
  50. SEG_NUMB = 8'h83, //83,
  51. SEG_NUMC = 8'hC6, //c6,
  52. SEG_NUMD = 8'hA1, //a1,
  53. SEG_NUME = 8'h86, //86,
  54. SEG_NUMF = 8'h8E; //8e;
  55.  
  56. //-----------------------------------------------------------
  57. // function : display nibble of counter
  58. // input :
  59. // output : none
  60. //-----------------------------------------------------------
  61. always @(SegLedData) begin
  62. case(SegLedData)
  63. 4'h0: seg_data <= SEG_NUM0;
  64. 4'h1: seg_data <= SEG_NUM1;
  65. 4'h2: seg_data <= SEG_NUM2;
  66. 4'h3: seg_data <= SEG_NUM3;
  67. 4'h4: seg_data <= SEG_NUM4;
  68. 4'h5: seg_data <= SEG_NUM5;
  69. 4'h6: seg_data <= SEG_NUM6;
  70. 4'h7: seg_data <= SEG_NUM7;
  71. 4'h8: seg_data <= SEG_NUM8;
  72. 4'h9: seg_data <= SEG_NUM9;
  73. 4'ha: seg_data <= SEG_NUMA;
  74. 4'hb: seg_data <= SEG_NUMB;
  75. 4'hc: seg_data <= SEG_NUMC;
  76. 4'hd: seg_data <= SEG_NUMD;
  77. 4'he: seg_data <= SEG_NUME;
  78. 4'hf: seg_data <= SEG_NUMF;
  79. default: ;
  80. endcase
  81. end
模組的輸入/輸出接腳

依據使用的開發板,設計模組的輸入/輸出接腳.

範例程式位於 Github 的 FPGA-led-sample






 



留言

這個網誌中的熱門文章

EC 所需知識 - SMBUS

EC 所需知識 - KBC

EC 所需知識 - LPC