格安FPGA評価ボードで格安LCD【1602A】を制御する


1. はじめに

 前回の記事で紹介した格安中華製FPGA評価ボードを使って、今度は電子工作でおなじみのこのLCD(Liquid Crystal Display)を制御してみます。型番は【1602A】というらしいです。いつもならArduinoなどの開発環境で専用ライブラリを導入するだけでカンタンに取り扱えたこのLCDを、少しややこしいですが、トレーニングのためFPGAベースで駆動させてみるのが今回の目的です。(LCDはAmazonで安く買えます。Aliexpressならもっと安いですが届くのに時間がかかります)

2. LCD【1602A】の仕様

 とりあえず、LCDの大まかな仕様を知りたい......。というわけで、データシートを探すと当然のようにありました!適宜ダウンロードしてください。細かい英文字が目にチカチカしますが、必要な箇所だけ拾い読む感じでゆっくりといきます。
 LCDの信号線(ピン)は全部で16あります。ダウンロード先のデータシートから転載のピンアサイン図を以下に示します。

 見てのとおり、No.7~14の8個のピン(DB0~DB7)は、8bit分のデータを受け取るためのデータバスになっています。つまり、表示したい文字(キャラクタ)の8bit ASCIIコードを、制御側(今回ではFPGAボード)が、制御対象であるLCD側に信号として送ることで文字の表示を制御できるといった仕組みです。
 LCDにはピンヘッダを半田付けしています。それをメス-メス ジャンパワイヤでFPGAボードのピンヘッダと結線して、今回の実験の回路を構成します。

3. FPGAのピンアサイン・回路構成

 電源周りのVss, Vdd, Vo, BLA, BLK を除くLCDの全てのピン(制御用信号線)を、それぞれ以下のようにVHDLで記述し定義しました。
 ・ RS ---> "lcd_rs"
 ・ R/W ---> "lcd_rw"
 ・ E ---> "lcd_e"
 ・DB0~DB7 ---> "data[0]~data[7]"

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity lcdtest is
port ( clk    : in std_logic;                            --clock i/p
       lcd_rw : out std_logic;                           --read & write control
       lcd_e  : out std_logic;                           --enable control
       lcd_rs : out std_logic;                           --data or command control
       data   : out std_logic_vector(7 downto 0)  );     --data line
end lcdtest;

 FPGAのピンアサインは図の赤枠に示すとおりです(これ通りでなくても適切に設定すれば動きますが、一応例として載せておきます)。なお、FPGAボードにあらかじめ載っている水晶?振動子(50MHz)をクロック入力として用いるので、今回使用するFPGAボード回路図の仕様に従って、VHDL内で宣言した "clk" には、INPUTとして既知の"PIN_17"を割り当てています。

 以下が回路図です。こちらのサイトが参考になりました。一部抜粋して、ここに載せます。
 設定したピンアサインと実際の配線が一致するようにします。この回路図に従い、LCDバックライトの調整のための可変抵抗を別途ブレッドボード上で構成しました。
 このLCD【1602A】は+5V駆動なので、FPGAボードのVcc=+3.3Vとはレベルが異なる点に注意してください(最初、FPGAボードのVccから引っ張ってきた3.3Vでも動くだろうと高をくくってたら1時間くらいハマりました)。別途+5Vの電源(直列した乾電池など)で対応するのが手っ取り早くていいかと思います。

4. LCDに"Hello! "と表示するテストVHDLコード(全文)

lcdtest.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity lcdtest is
port ( clk    : in std_logic;                          --clock i/p
       lcd_rw : out std_logic;                         --read & write control
       lcd_e  : out std_logic;                         --enable control
       lcd_rs : out std_logic;                         --data or command control
       data   : out std_logic_vector(7 downto 0));     --data line
end lcdtest;

architecture Behavioral of lcdtest is 
constant N: integer :=5+7; 
type arr is array (1 to N) of std_logic_vector(7 downto 0); 
constant datas : arr := (x"38",x"0c",x"04",x"01",x"C0",  x"48",x"65",x"6C",x"6C",x"6F",x"21",x"20");


begin
lcd_rw <= '0'; 
process(clk)
    variable i : integer := 0;
    variable j : integer := 1;

    begin
    if ( clk'event and clk = '1' ) then
        if i <= 1000000 then
            i := i + 1;
            lcd_e <= '1';
            data <= datas(j)(7 downto 0);
        elsif 1000000 < i and i < 2000000 then
            i := i + 1;
            lcd_e <= '0';
        elsif i = 2000000 then
            j := j + 1;
            i := 0;
        end if;

        if j <= 5  then
            lcd_rs <= '0';
        elsif j > 5   then
            lcd_rs <= '1';
        end if;

        if j = 5+7 then 
            j := 5;
        end if;

    end if;

end process;
end Behavioral;

x"48",x"65",x"6C",x"6C",x"6F",x"21",x"20"の16進表記の並びで、
"H", "e", "l", "l", "o", "!", " " の計7文字を表しています。

5. 実験結果


文字列"Hello! "がFPGAによりあの格安LCDに表示されています!!完了です!

6. まとめ

 格安FPGA評価ボードを用いて、格安LCDの導入を行なうことができました。
 今後はより実践的な内容で勉強しながら記事を書いていきたいと思います。