🤖

[FPGA]Tang Primer 20kで7セグを光らせる

2024/10/09に公開

最近FPGAを弄り始めました。Lチカの次の段階として7セグを光らせてみたので記録に残しておきたいと思います。
Lチカに関してはこちらの方の記事が大変分かりやすいです。
(※ 本記事では先の記事に書かれているようなツールの使い方等はスキップしています。)

はじめに

必要なモノ

  • Tang Primer 20K
  • ブレッドボード
  • 7セグメントディスプレイ
  • ジャンパーワイヤ × 8本

7セグとは

7セグとは7セグメントディスプレイの略称で、↓ のようにデジタルに10進法のアラビア数字を表示するための装置のこと。

Wikipedia[1]より抜粋
最近ではLEDが使われることが多いため、7セグメントLEDとも呼ばれています。

7セグのピン配置

ピンの配置は製品ごとに異なる(カモ)なので、購入した製品のデータシートを確認するのが一番良いですが、凡その製品は次のようになっている(と思います)

英数字割り当て 対応関係
ブログ記事[2]より抜粋 ブログ記事[2:1]より抜粋

アノードコモン・カソードコモン

7セグはLEDが8個搭載されているためアノードとカソードの端子で合わせて16個ほど必要ですが、実際には10本しか出ていません。アノードかカソードの端子をひとまとめにすることで必要端子数を減らして光らせることが可能になっています。
この時、アノードの端子をまとめたものをアノードコモン、カソードの端子をまとめたものをカソードコモンと呼称しています。

アノード・カソードについて

LEDでは陽極(+側)をアノード、陰極(-側)をカソードと呼称し、アノードからカソードの方向へしか電流が流れません。
FPGAボードでは、アノード側に3.3VピンまたはGPIOのHIGH設定ピンを接続し、カソード側にGNDピンまたはGPIOのLOW設定ピンを接続することで光らせることができます。

カウントダウンタイマー(10s)の実装

配線

正面から 横から

Floor Planner

以下のように設定しています。
割と適当に選んでぶっ刺しているので、もう少し綺麗に対応付けはできると思います…

コード

module seven_segment(
    input Clock,
    output reg [6:0] segments
);

    parameter count_value = 26_499_999; // define 1 second

    reg [24:0] count_value_reg; // 25bit register, count 1 second
    reg [3:0] digit; // 4bit register, displaying digit

    always @(posedge Clock) begin
        if (count_value_reg <= count_value) begin
            count_value_reg <= count_value_reg + 1'b1;
        end
        else begin
            count_value_reg <= 23'b0;
            digit <= digit + 1'b1;
        end

        case (digit)
            4'd0: segments = 7'b0001000; // 0
            4'd1: segments = 7'b0111110; // 1
            4'd2: segments = 7'b0010001; // 2
            4'd3: segments = 7'b0010100; // 3
            4'd4: segments = 7'b0100110; // 4
            4'd5: segments = 7'b1000100; // 5
            4'd6: segments = 7'b1000000; // 6
            4'd7: segments = 7'b0001110; // 7
            4'd8: segments = 7'b0000000; // 8
            4'd9: segments = 7'b0000100; // 9
            4'd10: digit <= 4'd0; // initialize digit
            default: segments = 7'b1111111; // 0
        endcase
    end

endmodule

segments = 7'b0010001; // 2に関してですが、意味合い的には

segments[0] = 0
segments[1] = 0
segments[2] = 1
:
:
segmnets[6] = 1

と同義です。上の桁から順にインデクスが振られているようです。

実行結果

0 ~ 9 まで凡そ1秒で切り替わりました!


制限引っかからないように画質死ぬほど下げてます…

脚注
  1. https://ja.wikipedia.org/wiki/7セグメントディスプレイ ↩︎

  2. https://pc.watch.impress.co.jp/docs/2008/1120/musashino019.htm ↩︎ ↩︎

  3. https://monorepi.jp/archives/2998 ↩︎

Discussion