tinygoと74HC595を使用したキャラクタ液晶表示
初めに
マイコンを使用したものを作るときに、状態など表示させたいときにキャラクタ液晶を使うことが多いと思います。しかし、Seeed Xiaoのような小型のマイコンはピン数に制限があり、キャラクタ液晶のように多くのピン数を使うと液晶制御以外何もできなくなります。そこで、LCDの制御で利用するピン数を少なくするために74HC595を使用した液晶表示回路と制御プログラムの作成に取り組んでみました。
使用部品と回路について
使用部品
今回の回路には表1に示す部品を使用しました。
使用部品 | 名称 | 備考 |
---|---|---|
マイコン | Seeeduino Xiao | |
LCD | SD1602HULB-XA-G-G | 16文字x2行 |
IC | 74HC595 | シフトレジスタ(シリアルイン-パラレルアウト) |
抵抗 | 200Ω | バックライト用 |
半固定抵抗 | 20kΩ | 明るさ調整用 |
回路について
回路図を下に示します。
今回の回路に74HC595を使用しています。74HC595はシリアル入力からパラレル出力に変換できるシフトレジスタ回路のロジックICです。私も出力が多く必要なときに、よく利用しています。Enableピンだけは、LCDのレジスタ等の書き込みで使用するので別のピンにして制御するようにしました。
また、LCDのデータは4ビットモードで使用するようにしています。
使用するマイコンとプログラムについて
今回使用するマイコンはSeeed Xiaoを使用します。また、プログラム言語としてtinygoを使用します。もし、tinygoの開発環境がわからない時は、前回公開したものを参考にしてください。
今回のディレクトリは下の図のようになります。
まず、始めに作業用のフォルダを作成し、Visual Studio Codeからフォルダを開いてください。今回はLCDとしています。
次に自作モジュールを使うので作業用のフォルダの中に各モジュールをフォルダを作成します。ShiftOutが74HC595の制御モジュール用、Lcd_74hc959がキャラクタ液晶用のフォルダです。その中に各モジュールのプログラムを作成します。ShiftOut.goは74HC595の制御プログラムで、lcd_74hc595.goとregister.goがLCD制御関係のプログラムとレジスタの定義ファイルになります。作業用のディレクトリにあるmain.goが動作テストプログラムです。
最後に自作モジュールで作成して、プログラムを行うので下に示すコマンドで、go.modファイルを作成します。最後のLCDはフォルダ名なので、作成したフォルダに合わせて変更してください。
go.modの作成
go mod init LCD go mod tidy
各プログラムは次のようになります。
ShiftOut.go(74HC595制御プログラム)
package ShiftOut
import (
"machine"
)
type ShiftOut struct {
ser machine.Pin // データ入力ピン
rclk machine.Pin // ラッチ
srclk machine.Pin // シフトレジスタクロック
}
// New -> 74HC595 初期化関数
/* (74HC595)
Serial Data -> ser
RCK -> rclk
Shift register Clock -> srclk
*/
func New(ser machine.Pin, rclk machine.Pin, srclk machine.Pin) ShiftOut {
/* 構造体の宣言 */
shft := ShiftOut{}
/* 構造体に格納 */
shft.ser = ser
shft.rclk = rclk
shft.srclk = srclk
/* 各ピンの設定 */
shft.ser.Configure(machine.PinConfig{Mode: machine.PinOutput})
shft.rclk.Configure(machine.PinConfig{Mode: machine.PinOutput})
shft.srclk.Configure(machine.PinConfig{Mode: machine.PinOutput})
return shft
}
// OutPutData
/* 8bitデータ出力関数 */
/* OutPutData(出力データ) */
func (shft *ShiftOut) OutPutData(outdata uint8) {
// データ出力
shft.rclk.Low() // 送信中はラッチをLowに設定
/* 出力データ設定処理 */
for i := 0; i < 8; i++ {
// 出力データの確認
if (outdata & (1 << i)) != 0x00 {
shft.ser.High() // 1 -> High
} else {
shft.ser.Low() // 0 -> Low
}
// データ書き込み
shft.srclk.High()
shft.srclk.Low()
}
shft.rclk.High() // 送信中はラッチをLowに設定
}
lcd_74hc595.go(LCD制御プログラム)
package Lcd_74hc595
import (
"LCD/ShiftOut"
"machine"
"time"
)
type Lcd struct {
shft ShiftOut.ShiftOut
enable machine.Pin
col uint8 // 列数
row uint8 // 行数
}
func New(col uint8,row uint8, shft ShiftOut.ShiftOut, en machine.Pin) Lcd {
lcd := Lcd{}
lcd.shft = shft
lcd.enable = en
lcd.col = col
lcd.row = row
return lcd
}
// lcd初期化関数
func (l *Lcd) Init() {
Command(l.shft, l.enable, 0x03)
time.Sleep(40 * time.Millisecond)
Command(l.shft, l.enable, 0x03)
time.Sleep(5 * time.Millisecond)
Command(l.shft, l.enable, 0x03)
time.Sleep(5 * time.Millisecond)
Command(l.shft, l.enable, 0x02)
time.Sleep(5 * time.Millisecond)
Command(l.shft, l.enable,LCD_FUNCTIONSET | LCD_4BITMODE | LCD_2LINE | LCD_5x8DOTS)
Command(l.shft, l.enable,LCD_DISPLAYCONTROL | LCD_DISPLAYOFF)
Command(l.shft, l.enable,LCD_CLEARDISPLAY)
time.Sleep(40 * time.Millisecond)
Command(l.shft, l.enable,LCD_ENTRYMODESET | LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT)
Command(l.shft, l.enable, LCD_DISPLAYCONTROL | LCD_DISPLAYON)
time.Sleep(40 * time.Millisecond)
}
/* 液晶に1文字出力 */
func (l *Lcd) Print(s string) {
for _, c := range s {
outputchar(l.shft, l.enable, uint8(c))
}
}
/* 液晶クリア */
func (l *Lcd) Clear() {
Command(l.shft, l.enable,LCD_CLEARDISPLAY)
}
/* ホームへ移動 */
func (l *Lcd) Home() {
Command(l.shft, l.enable,LCD_RETURNHOME)
}
/* 表示位置指定*/
func (l *Lcd) Locate(col uint8 ,row uint8) {
var offset uint8
if row >= (l.row - 1) {
offset = 0x40
} else {
offset = 0x00
}
Command(l.shft, l.enable,LCD_SETDDRAMADDR | (offset + col))
}
// Enable
func pluseEnable(en machine.Pin) {
en.Low()
time.Sleep(1 * time.Microsecond)
en.High()
time.Sleep(1 * time.Microsecond)
en.Low()
time.Sleep(1 * time.Microsecond)
}
// コマンド処理
func Command(s ShiftOut.ShiftOut, en machine.Pin, data uint8) {
s.OutPutData(rs_low + (data>>4)&0x0f)
pluseEnable(en)
s.OutPutData(rs_low + (data)&0x0f)
pluseEnable(en)
}
// 表示処理
func outputchar(s ShiftOut.ShiftOut, en machine.Pin, data uint8) {
s.OutPutData(rs_high + (data>>4)&0x0f)
pluseEnable(en)
s.OutPutData(rs_high + (data)&0x0f)
pluseEnable(en)
}
register.go(LCDレジスタ定義ファイル)
package Lcd_74hc595
const (
rs_low = 0x00
rs_high = 0x10
LCD_CLEARDISPLAY = 0x01
LCD_RETURNHOME = 0x02
LCD_ENTRYMODESET = 0x04
LCD_DISPLAYCONTROL = 0x08
LCD_CURSORSHIFT = 0x10
LCD_FUNCTIONSET = 0x20
LCD_SETCGRAMADDR = 0x40
LCD_SETDDRAMADDR = 0x80
LCD_ENTRYRIGHT = 0x00
LCD_ENTRYLEFT = 0x02
LCD_ENTRYSHIFTINCREMENT = 0x01
LCD_ENTRYSHIFTDECREMENT = 0x00
LCD_DISPLAYON = 0x04
LCD_DISPLAYOFF = 0x00
LCD_CURSORON = 0x02
LCD_CURSOROFF = 0x00
LCD_BLINKON = 0x01
LCD_BLINKOFF = 0x00
LCD_DISPLAYMOVE = 0x08
LCD_CURSORMOVE = 0x00
LCD_MOVERIGHT = 0x04
LCD_MOVELEFT = 0x00
LCD_8BITMODE = 0x10
LCD_4BITMODE = 0x00
LCD_2LINE = 0x08
LCD_1LINE = 0x00
LCD_5x10DOTS = 0x04
LCD_5x8DOTS = 0x00
)
main.go(サンプルプログラム)
package main
import (
"LCD/Lcd_74hc595"
"LCD/ShiftOut"
"machine"
)
func main() {
// Enableピンの設定
enable := machine.D6
enable.Configure(machine.PinConfig{Mode: machine.PinOutput})
// シフトレジスタのの設定
// Ser -> D9 RCLK-> D8 SCLK->D7
shout := ShiftOut.New(machine.D9, machine.D8, machine.D7)
lcd := Lcd_74hc595.New(16, 2, shout, enable)
lcd.Init() // LCD初期化
lcd.Home() // LCDのカーソルをHome(col=0,row=0)に設定
lcd.Print("Hello World") // 文字出力
lcd.Locate(0, 1) // LCDのカーソルをHome(col=0,row=1)に設定
lcd.Print("Hello TinyGo!")
/* 無限ループ */
for {
}
}
最後に
74HC595を使用したキャラクタLCDの制御に取り組んでみました。キャラクタLCDはマイコン関係ではよく利用する部品だと思います。この投稿がみなさんの何かの参考になればいいかなぁと思っています。また、tinygoのプログラムにも興味を持っていただけたらうれしいです。
今回は自作モジュールの作成して、活用したり、レシーバを使ったりしているので、プログラムが少し難しいかと思います。他のサイトでGolangについて、調べながらやって見てください。また、Micropython用のプログラムを作成も使用と思っています。完成したら紹介します。
投稿者の人気記事
-
keiske-hongyo
さんが
2021/12/06
に
編集
をしました。
(メッセージ: 初版)
-
keiske-hongyo
さんが
2021/12/06
に
編集
をしました。
-
keiske-hongyo
さんが
2021/12/07
に
編集
をしました。
-
uchan
さんが
2021/12/25
に送った
編集リクエスト
が受理されました。
(メッセージ: 誤字修正)
-
uchan
さんが
2021/12/26
に
編集
をしました。
(メッセージ: 誤字修正)
-
keiske-hongyo
さんが
2021/12/26
に
編集
をしました。
-
keiske-hongyo
さんが
2022/01/02
に
編集
をしました。
(メッセージ: 回路図の修正(電圧を表記))
-
keiske-hongyo
さんが
2022/01/02
に
編集
をしました。
-
keiske-hongyo
さんが
2022/01/02
に
編集
をしました。
-
keiske-hongyo
さんが
2022/02/12
に
編集
をしました。
-
keiske-hongyo
さんが
2022/11/05
に
編集
をしました。
ログインしてコメントを投稿する