Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Homepage
シャープ製メモリ液晶直接駆動用ライブラリ¶

秋月電子などで販売されている、シャープ製のモノクロメモリ液晶を
直接駆動させるためのライブラリとデモプログラムです。
図形や文字列を比較的簡単に表示させることが可能です。 また、メモリに余裕があれば日本語(全角文字)も描画可能です。
文字描画のアルゴリズムは、こちらのページで公開されていた
日本語ビットマップフォント表示アルゴリズムを改変して使用しています。
松浦光洋様、素晴らしいアルゴリズムを公開していただきありがとうございます。
現在ソースコードの公開は停止されている模様です。
また、ビットマプフォントにはM+ BITMAP FONTSで公開されている
Mplus-gothic-medium-R-normal 12pxを使用しています。
本体に搭載されているメモリ(RAM)のサイズをご確認ください!
このライブラリでは、ライブラリを通して描かれた全画素の情報ををchar型の一次元配列として記憶します。
故に、小さなRAMしか搭載していないものではOutOfMemoryになり、うまく動作しません。
内部画素記憶配列のサイズは、((表示幅[px] / 8) * 表示高さ[px])[byte]です。
表示幅400px、表示高さ240pxの場合は 12Kbyte(12,000byte) の領域を要します。
表示幅128px、表示高さ128pxの場合は 2Kbyte(2,048byte)
文字列を扱う場合はさらにメモリ使用量が増えるので、表示幅400px、表示高さ240pxで使用する場合は
参考値として16KB以上のメモリ(RAM)を搭載した製品でお使いください。
mbed LPC1114FN28ではもちろんのことながら動作しませんでした・・・
青mbedでも場合によってはちょっと厳しいかも・・・?NUCLEO F401クラスであれば余裕です。
使用できる液晶製品¶
LS027B7DH01Aと同一の駆動方式であれば駆動可能です。
対応済みと思われる製品(テストはLS027B7DH01Aで行っています)
LS012B7DD01とLS013B7DH06は駆動方式が異なるため使用できません。
直接結線して駆動することを前提としてコードを書いているので、
間にSRAMやEEPROMなどを挟んだり、4線式SPIの使用を前提としたものでは動作しません。
結線方法¶
端子一覧¶

液晶を表示面側から見たとき、右側の端子が1番、左側の端子が10番になります。
データシートには逆っぽく書いてますが、実際コレで大丈夫です。
参考:http://l52secondary.blog.fc2.com/blog-entry-18.html
というかデータシートの書き方がわかりにくすぎ。さすが目の付け所が・・・。
画像は秋月電子の変換基板を使用していますが、コネクタ直接接続でも並び順は一緒です。
一番簡単な結線¶
一番簡単な結線は、vSCK, vSI, vCSと電源+とGNDの5本線を結線する方法です。

もし、プログラム側で
SHMLCD_J mlcd(p26, p25, p24);
とした場合は、
1番端子(SCLK)とp26を接続、2番端子(SI)とp25を接続、3番端子(SCS)とp24を結線し、
5,6,7の端子を全部ショート(つなげて)させて、電源+(mbedの3v3や5V)に接続
8,9,10の端子を全部ショート(つなげて)させて、GND(mbedのGND)に接続。
外部信号を使う結線¶
外部信号を使う結線は下記画像の通りです。
外部信号を使っても使わなくても表示機能自体に変化はありません。
dispOFF関数とかが使えるか使えないかの差です。

この場合、プログラム側では5つの引数のコンストラクタを使用します。
プログラム側で
SHMLCD_J mlcd(p26, p25, p24, p23, p22);
とした場合は、
1番端子(SCLK)とp26を接続、2番端子(SI)とp25を接続、3番端子(SCS)とp24を結線し、
4番端子(EXTCOMIN)とp23を接続、5番端子(DISP)とp22を接続、
6,7,8をの端子を全部ショート(つなげて)させて、電源+(mbedの3v3や5V)に接続
9,10の端子を全部ショート(つなげて)させて、GND(mbedのGND)に接続。
外部から液晶の表示を付けたり消したりしたいなら、外部信号結線を使ってください。
それ以外なら簡単結線で問題ありません。
使用準備¶
このライブラリはSPIポートを占拠しません。
DigitalOutができるピンであればどれでも使用可能です。
前述の一番簡単な結線をした場合、以下のような宣言でSHMLCD_Jクラスの使用準備(インスタンス化)ができます。
#include "SH_MLCD_J.h" //SHMLCD_Jクラスをこれから使うからinclude(読み込む) SHMLCD_J mlcd(p26, p25, p24); //mlcdの名前は自由、ピン番号は各自環境に合わせて変更
実際にプログラムとして書いてみると、
main.cpp
#include "mbed.h"
#include "SH_MLCD_J.h"
SHMLCD_J mlcd(p26, p25, p24); //←mlcdという名前で使用準備(インスタンス化)
int main(){
mlcd.init(400, 240); //←液晶の初期化命令
mlcd.pixel(5, 5); //←座標(5, 5)に点を打つ
}
このようになります。
init関数について¶
init関数は、液晶を使い始める前に必ず1回だけ呼ぶ必要があります。 そして、呼び出す際には液晶のサイズを指定します。
mlcd.init(400, 240); //←液晶の初期化命令
指定する数値は使用する液晶のサイズによって数値が変わります。
LS010B7DH01を使う場合は
幅128ピクセル、高さ128ピクセルの表示領域なので、
mlcd.init(128, 128); //←液晶の初期化命令
このようになります。
ちなみに、init関数は戻り値として「液晶の初期化に成功したがどうか」を返します。
初期化に成功したら true 、失敗したら false を返します。
成功失敗で処理を分けたい場合は、以下のようにして問題を回避してください。
bool success = mlcd.init(128, 128); //←液晶の初期化命令(bool型のsuccess変数に結果が入る)
if(success == true){
//初期化に成功したときの処理
}false{
//初期化に失敗したときの処理
}
図形描画関数について¶
SH_MLCD_Jクラスは、さまざまなグラフィック描画関数を備えています。
- pixel関数:指定した座標に1ピクセルの点を描きます
- drawLine関数:指定した座標から指定された座標まで線を引きます
- drawRect関数、drawRect2関数:指定された座標、サイズで四角形を描きます
- fillRect関数、fill2Point関数:指定された座標、サイズで塗りつぶされた四角形を描きます
- drawCircle関数:指定された中心座標に、指定された半径の円を描きます
- fillCircle関数:指定された中心座標に、指定された半径の塗りつぶされた円を描きます
- drawChar関数:指定された1文字を、指定された座標に描きます
- writeString関数、ws関数:指定された文字列を、指定された座標に描きます
引数:modeについて¶
いずれの関数も引数の中にmodeというものが存在します。
modeには、描画モードを指定します。
- SHMLCD_J_BLACK:黒く描画します
- SHMLCD_J_ERASE:白く描画します
- SHMLCD_J_INVERT:画素を反転させます(fillCircleではうまく動作しません)
引数:immidiateについて¶
いずれの関数も引数の中にimmidiateというものが存在します。
immidiateには、即時描画を行うかどうかをtrueかfalseで指定します。
例えばpixel関数で1個打点したあと、immidiateがtrueであればすぐに液晶に反映されます。
immidiateがfalseの場合、内部画素記憶配列のみを更新し、液晶には反映しません。
1行だけの反映であれば大した時間はかかりませんが、反映する行が増えれば増えるほど
処理の時間がかかってしまいますので、書きたい情報を全部内部画素記憶配列に書き込んでから
一気にドバっと反映するほうが効率的で処理時間の短縮が見込めます。
なので、文字や四角形や格子模様などを複数行広範囲にわたって書き込む場合はimmidiateをfalseにして
すべての描画処理が完了したあとにwriteArrayN関数やwriteArrayA関数を使用して
ドバっと更新するほうがお得です。
ちなみに、各関数のimmidiateのデフォルト値はtrueです。
引数を省略した場合は即時描画されてしまいますのでご注意ください。
サンプル¶
描画パターンは何千通りもあるので、各自実際にどのような描画になるのか試してみてください。
mbed LPC1768でのサンプル¶
main.cpp
#include "mbed.h"
#include "SH_MLCD_J.h"
SHMLCD_J mlcd(p26, p25, p24); //インスタンス化
int main(){
wait(20.0); //結線完了までの待ち時間(不要であれば削除)
//初期化(引数にはデータシートに書いてある表示横幅と表示高さを指定する)
mlcd.init(400, 240);
//四角形(即時描画)
mlcd.drawRect(15, 15, 20, 20, SHMLCD_J_BLACK, true);
mlcd.fill2Point(105, 15, 125, 35, SHMLCD_J_BLACK, true);
//円(あとで描画):第5引数がfalseだと即時描画しない
mlcd.drawCircle(25, 55, 10, SHMLCD_J_BLACK, false);
mlcd.fillCircle(55, 55, 10, SHMLCD_J_BLACK, false);
//小さい文字(あとで描画):第5引数がfalseだと即時描画しない
char str1[] = "small text! 小さい文字は余裕。\n改行も有効です。タブは無理。";
mlcd.ws(str1, 10, 80, SHMLCD_J_BLACK, false);
//大きい文字(即時描画):第4引数にズーム倍率(整数)で倍角可能
char str2[] = "Large Text! 2倍角も余裕。";
mlcd.ws(str2, 10, 160, 2, SHMLCD_J_BLACK, true);
wait(3.0); //3秒待つ
//表示画素全部更新(ここで円と小さい文字が描画されます)
mlcd.writeArrayA();
wait(10.0); //10秒待つ
mlcd.cls(); //表示クリア(内部記憶配列はクリアされない)
//表示画素全部更新(さっき消したものが再現される)
mlcd.writeArrayA();
wait(10.0); //10秒待つ
mlcd.cls(); //表示クリア
mlcd.cla(); //内部記憶配列もクリア
//表示画素全部更新(内部記憶配列を消したので真っ白になる)
mlcd.writeArrayA();
//プログラムが終わらないための処理
for(;;);
}
NUCLEOボード用のサンプル¶
main.cpp
#include "mbed.h"
#include "SH_MLCD_J.h"
SHMLCD_J mlcd(D7, D6, D5, D4, D3); //SHMLCD_Jインスタンス化(D7, D6, D5, D4, D3の5ピンを使用)
DigitalIn btn(USER_BUTTON); //青ボタン
int main(){
//初期化(引数にはデータシートに書いてある表示横幅と表示高さを指定する)
mlcd.init(400, 240);
//青いボタンが押されるまで待ち続ける
while(btn);
delay(1.0); //1秒待つ
//Nucleoの文字を3倍角で描画(即時描画)
mlcd.ws("ST Nucleo Board", 0, 0, 3);
wait(5.0); //5秒待つ
//液晶の表示をオフにする(画面が消える)
mlcd.dispOFF();
//青いボタンが押されるまで待ち続ける
while(btn);
delay(1.0); //1秒待つ
//液晶の表示をオンにする(画面が点灯する)
mlcd.dispON();
wait(5.0); //5秒待つ
//小さい文字(あとで描画):第5引数がfalseだと即時描画しない
char str1[] = "small text! 小さい文字は余裕。\n改行も有効です。タブは無理。";
mlcd.ws(str1, 10, 80, SHMLCD_J_BLACK, false);
//大きい文字(即時描画):第4引数にズーム倍率(整数)で倍角可能
char str2[] = "Large Text! 2倍角も余裕。";
mlcd.ws(str2, 10, 160, 2, SHMLCD_J_BLACK, true);
wait(10.0); //10秒待つ
//表示画素全部更新(ここで小さい文字が描画されます)
mlcd.writeArrayA();
wait(3.0); //3秒待つ
//表示をクリア
mlcd.cls();
//内部配列もクリア
mlcd.cla();
//設定された表示幅と高さを取得
int width_size = mlcd.getWidth();
int height_size = mlcd.getHeight();
//グリッドを表示
//垂直線を等間隔にXOR表示(描画はあとで):第4引数は描画モード
//描画モード(fillCircleはSHMLCD_J_INVERTが使えません):
// SHMLCD_J_BLACK (0): 黒で描画します
// SHMLCD_J_ERASE (1): 白で描画します
// SHMLCD_J_INVERT (-1): 画素を反転(XOR)させます(白なら黒、黒なら白)
for(int x=10; x<width_size; x+=20){
mlcd.drawLine(x, 0, x, height_size-1, SHMLCD_J_INVERT, false);
}
//水平線を等間隔にXOR表示(描画はあとで):第4引数は描画モード
for(int y=10; y<height_size; y+=20){
mlcd.drawLine(0, y, width_size-1, y, SHMLCD_J_INVERT, false);
}
//表示画素特定部分だけ更新:ライン80からライン160まで更新
mlcd.writeArrayN(80, 160);
wait(3.0); //3秒待つ
//表示画素全部更新
mlcd.writeArrayA();
//プログラムが終わらないための処理
for(;;);
}
全関数一覧¶
このページでは紹介していない関数もありますので、使用してみたい関数を見つけて
動くかどうかを試してみてください。
Import library
Public Member Functions |
|
| SHMLCD_J (PinName vSCK, PinName vSI, PinName vCS, PinName vCOM, PinName vDISP) | |
|
コンストラクタ:SHMLCD_Jクラスのインスタンスを作成します
|
|
| SHMLCD_J (DigitalOut *vSCK, DigitalOut *vSI, DigitalOut *vCS, DigitalOut *vCOM, DigitalOut *vDISP) | |
|
コンストラクタ:SHMLCD_Jクラスのインスタンスを作成します
|
|
| SHMLCD_J (PinName vSCK, PinName vSI, PinName vCS) | |
|
コンストラクタ:SHMLCD_Jクラスのインスタンスを作成します(COM端子とDISP端子は使用しません)
|
|
| SHMLCD_J (DigitalOut *vSCK, DigitalOut *vSI, DigitalOut *vCS) | |
|
コンストラクタ:SHMLCD_Jクラスのインスタンスを作成します(COM端子とDISP端子は使用しません)
|
|
| ~SHMLCD_J () | |
|
デストラクタ:内部配列と使用した変数を削除します(ユーザーが呼ぶ必要はありません)
|
|
| bool | init (unsigned short dispWidth, unsigned short dispHeight) |
|
初期化:使用する配列や端子の状態を初期化します
|
|
| unsigned short | getWidth () |
|
初期化時に指定した表示ピクセル幅を返す
|
|
| unsigned short | getHeight () |
|
初期化時に指定した表示ピクセル高さを返す
|
|
| void | clear () |
|
液晶の表示をクリアする:内部画素記憶配列はクリアされない
|
|
| void | cls () |
|
液晶の表示をクリアする:内部画素記憶配列はクリアされない(
clear()
のエイリアス)
|
|
| void | clearArray () |
|
内部画素記憶配列をクリアする:表示はクリアされない
|
|
| void | cla () |
|
内部画素記憶配列をクリアする:表示はクリアされない(
clearArray()
のエイリアス)
|
|
| void | dispON () |
|
DISP端子をONにする:外部DISP信号を使用しない場合は何も起きない
|
|
| void | dispOFF () |
|
DISP端子をOFFにする:外部DISP信号を使用しない場合は何も起きない
|
|
| void | invertCOM () |
|
液晶寿命を延ばすためにCOM信号を反転させる
|
|
| void | regCOMTimer (float tickTime=0.25) |
|
液晶寿命を延ばすためのCOM信号反転をタイマーに登録して自動的に行う
|
|
| void | deregCOMTimer () |
|
液晶寿命を延ばすためのCOM信号反転のタイマーを解除する
|
|
| void | updateArray1 (unsigned char ln, const char *data) |
|
内部画素記憶配列の特定の行にデータを上書きする
|
|
| void | updateArrayN (unsigned char sn, unsigned char en, const char *data) |
|
内部画素記憶配列の特定の範囲にデータを上書きする
|
|
| void | updateArrayA (const char *data) |
|
内部画素記憶配列を全て上書きする
|
|
| void | writeArray1 (unsigned char ln) |
|
内部画素記憶配列の特定の行をメモリ液晶に表示する
|
|
| void | writeArrayN (unsigned char sn, unsigned char en) |
|
内部画素記憶配列の特定の範囲をメモリ液晶に表示する
|
|
| void | writeArrayA () |
|
内部画素記憶配列を全てメモリ液晶に表示する
|
|
| void | write1 (unsigned char ln, const char *data) |
|
データをメモリ液晶の特定行に表示する(内部画素記憶配列を介さない)
|
|
| void | writeN (unsigned char sn, unsigned char en, const char *data) |
|
データをメモリ液晶の特定の範囲に表示する(内部画素記憶配列を介さない)
|
|
| void | writeA (const char *data) |
|
データをメモリ液晶全域に表示する(内部画素記憶配列を介さない)
|
|
| void | pixel (unsigned short x, unsigned short y, signed char mode=SHMLCD_J_BLACK, bool immidiate=true) |
|
メモリ液晶の特定の座標に1ピクセルのドットを表示する
|
|
| void | drawLine (unsigned short fromX, unsigned short fromY, unsigned short toX, unsigned short toY, signed char mode=SHMLCD_J_BLACK, bool immidiate=true) |
|
メモリ液晶に線を表示する
|
|
| void | drawRect (unsigned short left, unsigned short top, unsigned short width, unsigned short height, signed char mode=SHMLCD_J_BLACK, bool immidiate=true) |
|
メモリ液晶に四角形を表示する
|
|
| void | drawRect2 (unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, signed char mode=SHMLCD_J_BLACK, bool immidiate=true) |
|
メモリ液晶に四角形を表示する(対角点指定)
|
|
| void | fillRect (unsigned short left, unsigned short top, unsigned short width, unsigned short height, signed char mode=SHMLCD_J_BLACK, bool immidiate=true) |
|
メモリ液晶に塗りつぶされた四角形を表示する
|
|
| void | fill2Point (unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, signed char mode=SHMLCD_J_BLACK, bool immidiate=true) |
|
メモリ液晶に塗りつぶされた四角形を表示する(対角点指定)
|
|
| void | drawCircle (unsigned short centerX, unsigned short centerY, unsigned short r, signed char mode=SHMLCD_J_BLACK, bool immidiate=true) |
|
メモリ液晶に円を表示する
|
|
| void | fillCircle (unsigned short centerX, unsigned short centerY, unsigned short r, signed char mode=SHMLCD_J_BLACK, bool immidiate=true) |
|
メモリ液晶に塗りつぶされた円を表示する
|
|
| signed char | drawChar (const char *s, unsigned short x, unsigned short y, unsigned char zoom, signed char mode=SHMLCD_J_BLACK, bool immidiate=true) |
|
メモリ液晶に文字を表示する
|
|
| signed char | writeString (const char *str, unsigned short x, unsigned short y, unsigned char zoom, signed char mode=SHMLCD_J_BLACK, bool immidiate=true) |
|
メモリ液晶に文字列を表示する
|
|
| signed char | writeString (const char *str, unsigned short x, unsigned short y, signed char mode=SHMLCD_J_BLACK, bool immidiate=true) |
|
メモリ液晶に文字列を表示する
|
|
| signed char | ws (const char *str, unsigned short x, unsigned short y, unsigned char zoom, signed char mode=SHMLCD_J_BLACK, bool immidiate=true) |
|
メモリ液晶に文字列を表示する(writeStringのエイリアス)
|
|
| signed char | ws (const char *str, unsigned short x, unsigned short y, signed char mode=SHMLCD_J_BLACK, bool immidiate=true) |
|
メモリ液晶に文字列を表示する(writeStringのエイリアス)
|
|
COM反転信号について¶
COM反転は、液晶の寿命を延ばすために(焼き付き防止?)人間に見えない速度で液晶を明滅させる仕組みです。
COM反転信号はCOM反転を行うタイミングを液晶に伝達するもので、外部信号と内部信号の2種類があります。
このライブラリでは呼ばれたコンストラクタによって処理を変えており、
引数が3つのコンストラクタで呼ばれたらCOM反転は内部信号を使用します。
引数が5つのコンストラクタで呼ばれたらCOM反転は外部信号を使用します。
(ただし、引数が5つでもDigitalOutができないピンであれば内部信号に切り替わる)
引数が3つのコンストラクタを呼ぶ場合は、EXTCOMの端子をVSS(GND)に接続し 引数が5つのコンストラクタを呼ぶ場合は、EXTCOMの端子をVDD(3.3-5V)に接続してください。
COM反転信号はTickerを使って自動的に送出される仕組みになっていますが
init関数を呼ぶまではタイマーは作動しません。ユーザーがderegTimer関数でタイマーを解除した場合も、
regTimer関数で再度タイマーを開始するまでは止まったままになります。
また、int main()が終了した場合もSH_MLCD_Jクラスのインスタンスそのものが削除されて
COM反転信号が止まりますので、プログラムの終了を意図的に遅延させるか、プログラム終了後は
速やかに液晶を取り外してください。
質問など¶
質問などあればこのページに議題を立ててわかりやすく簡潔に記載してください。
このページに書いただけでは私が気付かない可能性がありますので、返答が遅い場合は
このブログのmbedカテゴリの記事(どれでもいいです)に何かコメントを書いてください。
ここまでまとめるのに5時間。もう疲れました。