USB-IO LCD を 4ビット転送モードで動作

『マイコンと表示器をつなぐ10の方法』(CQ出版社)を見ていて、
LCD に 4ビット転送モードがあるのを知った。
そこで、ActiveBasic のプログラムと Ruby スクリプトを 4ビット転送モード用に変更した。
4ビット転送モードで動作させ、文字が表示できることを確認した。
画像

動作環境



  • Windows XP
  • テクノキット 汎用USB-I/Oキット USBIOV8/K
  • 秋月のシリアル制御液晶表示モジュールキットについていたLCD
  • 26P フラットケーブル
  • USBケーブル(ストレート)
  • 「USB-IO LCD接続」で作成した LCD 接続用基板
  • 電源・グランド接続用ミノムシクリップ
  • ActiveBasic 4.24.00
  • ruby 1.8.6 mswin32
  • vbausbio.dll

準備


まず、必要に応じ、以下を用意しておく。

以下を実行しておく

  • プログラムリストの展開
  • ActiveBasic の展開
  • ruby-1.8.6-i386-mswin32.zip の展開
  • 制御用のスクリプトを置くディレクトリに vbausbio.dll を置く
  • コマンドプロンプト(DOS窓)で制御用のスクリプトを置くディレクトリに移動(例: cd c:\tmp)

ActiveBasic プログラムの 4ビット転送モード化


プログラムリストの LCD4 のコード(『手作りUSB機器』 133 ページのリスト 3-1)を使った。

出力部分の関数化


4ビット転送モードでは転送を複数回に分けて行う。
そこで、前準備として出力部分を関数化した。

以下の関数を追加した。

Sub Output(Data As Byte, RS As Byte)
if RS = 1 Then
if (P1sav and LCD_RS_BIT) = 0 Then
P1sav = P1sav or LCD_RS_BIT
uio_out(1, P1sav, 0)
Endif
Else
if (P1sav and LCD_RS_BIT) <>0 Then
P1sav = P1sav and (not LCD_RS_BIT)
uio_out(1, P1sav, 0)
Endif
Endif

uio_out(0, Data, 1)
End Sub

関数 CmdOut を以下のように変更した。

Sub CmdOut(Cmd As Byte)
Output(Cmd, 0)
End Sub

関数 DatOut を以下のように変更した。

Sub DatOut(Dat As Byte)

if Dat = &h0C Then
ClearLCD()
Elseif Dat < &h20 Then
LocateYX(1,0)
Else
Output(Dat, 1)
Endif
End Sub

ActiveBasic プログラムの 4ビット転送モード化


4ビット転送モード化のため、さきほどの変更に加え以下の変更を加えた。

以下の関数を追加した。

Sub Output(Data As Byte, RS As Byte)
Output8(Data and &hF0, RS)
Output8((Data << 4) and &hF0, RS)
End Sub


関数 Output の関数名を以下のように Output8 に変更した。

Sub Output8(Data As Byte, RS As Byte)


関数 init を以下のように変更した。

sub init()
P1sav = (P1sav and ( not LCD_RS_BIT)) or LCD_E_BIT
'RS_BIT = 0, E_BIT = 1
uio_out(1, P1sav, 0)

uio_out(0, &h30, 1) 'Function Set 8Bit data, 1/8 duty, 5x7 matrix
Sleep(5)
uio_out(0, &h30, 1)
uio_out(0, &h30, 1)
uio_out(0, &h20, 1) ' 4bit mode
uio_out(0, &h20, 1) : uio_out(0, &h80, 1) 'function set
uio_out(0, &h00, 1) : uio_out(0, &h80, 1) 'display OFF, cursor OFF, blink OFF
uio_out(0, &h00, 1) : uio_out(0, &h10, 1) 'display clear
uio_out(0, &h00, 1) : uio_out(0, &h60, 1) 'entry mode. incriment address, no shift
uio_out(0, &h00, 1) : uio_out(0, &he0, 1) 'display ON, cursor ON
End Sub

4ビット転送モードにした後は、データの出力は二つに分け、上位4ビットのみで出力する。
(今考えるとこの部分も関数化すべきだった)

三度目の「uio_out(0, &h30, 1)」の後は、 4.1ms 以上待つ必要があるようだが、
特に何もしなくても動作した。
USB-IO の出力があまり速くないので何もしなくても大丈夫なのだろう。

動作確認


フラットケーブルに電源とグランドを入れていないので、
LCD 基板の電源とグランドを USB-IO の電源とグランドに接続してから動作させた。

lcd4.exe を起動後、テキストボックスに文字を入力した。
画像

「表示」を押すと、LCD に文字が表示された。
ただし、「USB-IO LCD Rubyからの制御」で書いたように、
折り返し処理の調整を行っていないので、2行目以降が3行目に表示されてしまっている。
画像

ActiveBasic に関して迷ったこと


いくつか ActiveBasic に関して迷ってしまった。

  • 起動方法を忘れてしまった。スタートメニューに見当たらない。インストールディレクトリの ProjectEditor.exe を起動し、プロジェクトを開いた。
  • BASIC のビット AND, シフト演算は?それぞれ「And」、「<<」だった。
  • 一行に複数命令を書くには?「:」で良いようだ。

Ruby スクリプトも4ビット転送モード化


「USB-IO LCD Rubyからの制御」で書いた、ruby スクリプトも 4ビット転送化してみた。
(本当は、こちらをはじめに 4ビット化した…)

require 'dl/import'

module USB_IO
extend DL::Importable
dlload "vbausbio.dll"
extern "long uio_out(long, long, long)"
end

class LCD
RS_BIT = 0x02
E_BIT = 0x01

def initialize
@p1_save = 0xff

@p1_save = (@p1_save & ~RS_BIT) | E_BIT
USB_IO.uio_out(1, @p1_save, 0)

USB_IO.uio_out(0, 0x30, 1)
#sleep(5)
sleep(0.005)
USB_IO.uio_out(0, 0x30, 1)
USB_IO.uio_out(0, 0x30, 1)
USB_IO.uio_out(0, 0x20, 1)

USB_IO.uio_out(0, 0x20, 1); USB_IO.uio_out(0, 0x80, 1)
USB_IO.uio_out(0, 0x00, 1); USB_IO.uio_out(0, 0x80, 1)
USB_IO.uio_out(0, 0x00, 1); USB_IO.uio_out(0, 0x10, 1)
USB_IO.uio_out(0, 0x00, 1); USB_IO.uio_out(0, 0x60, 1)
USB_IO.uio_out(0, 0x00, 1); USB_IO.uio_out(0, 0xe0, 1)
end

def cmd_out(cmd)
uio_out4(cmd, false)
end

def locate_xy(ypos, xpos)
pos = (ypos * 0x40 + xpos) & 0x7f
cmd_out(pos + 0x80)
end

def clear
cmd_out(0x01)
end

def data_out(data)
if data == 0x0c
clear
elsif data < 0x20
locate_xy(1, 0)
else
uio_out4(data, true)
end
end

def message_out(mes)
mes.each_byte {|c| data_out(c)}
end

def uio_out(data, rs)
if rs
if (@p1_save & RS_BIT) == 0
@p1_save = @p1_save | RS_BIT
USB_IO.uio_out(1, @p1_save, 0)
end
else
if (@p1_save & RS_BIT) != 0
@p1_save = @p1_save & ~RS_BIT
USB_IO.uio_out(1, @p1_save, 0)
end
end

USB_IO.uio_out(0, data, 1)
end

def uio_out4(data, rs)
uio_out(data & 0xf0, rs)
uio_out((data << 4) & 0xf0, rs)
end
end

lcd = LCD.new
if ARGV.size > 0
lcd.message_out(ARGV.shift)
else
lcd.message_out("01234567890123456789\n01234567890123456789")
#lcd.message_out("0123456789")
end

まとめ


ActiveBasic のプログラムと Ruby スクリプトを4ビット転送モード用に変更した。
4ビット転送モードで動作させ、文字が表示できることを確認した。

この記事へのコメント

この記事へのトラックバック