| ホーム | 私の電子工作作品集 |
[ 初公開日:2025年2月16日 ] |
私のオリジナル作品として、ホームページ上に "174. グラフィック液晶表示 万年カレンダー" を公開してから、早いもので丁度 10 年程が経ちました。
おかげさまで評判もまずまずで、現在までに、多くの方々にそのクローンを作製して頂いています。 今回の作品は、一見、前作とほぼ同等機能のようにも見えますが、詳細なところでは随所で機能アップを施しており、また、回路構成もまったく一新させています。 前作では PIC とグラフィック液晶(SG12864A)とのインタフェース線が、何と 14 本も必要でしたが、今回作では I2C インタフェースを使用するため、有機 EL (OLED) モジュールとのインタフェースは、たったの2本だけで済んでしまいます。 そのため使用した PIC も、前作では 28 ピンの PIC16F886 でしたが、今回作では半分の 14 ピンの PIC16F1705 としました。 14 ピン PIC には PIC16F ファミリにもありますが、今回 PIC16F1 ファミリを採用したのは、 本機のようなカレンダーのプログラム規模(大きさ)になると、どうしてもサブルーチン等のネストが深くなってしまい、 PIC16F ファミリではスタックメモリをオーバーフローさせる(私の場合)ことが、しばしば起こります。 スタックメモリのサイズは、PIC16F ファミリでは 8 レベル分しか存在しませんが、PIC16F1 ファミリでは2倍の 16 レベル分が存在するために、その分余裕があって私には安心してプログラム作成に取り組むことができます。 また、プログラムメモリについても PIC16F1705 では PIC16F886 と同じ 8K ワードが存在しているので、その点でも十分な余裕があります。 もちろん、スタックメモリやプログラムメモリのサイズの問題だけではなく、両者ではアーキテクチャが異なっていて、 PIC16F1 ファミリでは便利な命令が多く追加されています。
また、万年カレンダーとしての基本的なクロック源には、前作では超高精度クリスタルモジュール( KTXO-18S )を使用していましたが、今回作では最近の私のホームページ上ではお馴染みの、リアルタイムクロックモジュール( DS3231 For PI )(改造が必要)を使用し、 バックアップ用の電池も搭載して、停電中も時刻の継続を確保しています。 他に、前作では据え置き型専用としての使用を想定して製作をしましたが、今回作の本機では携帯性も持たせるために、バッテリー(18650 リチウムイオン電池)駆動としています。 そして、そのためのリチウムイオン電池の充電機能も持たせるように考慮がしてあります。 |
![]() |
|
*注. 入力ポート RA0, RA1, RA4, RA5, RC5 は、内部プルアップ機能を ON にして使用。 また、SLEEP 中には それらのポート に状態変化割り込み機能を使用。 |
上回路図内には、有機 EL ディスプレイ(OLED)( SSD1306 )モジュールの電源 VCC に、トランジスタ 2SA1015Y が挿入されていますが、実はこのトランジスタは不要でした。 そのことが分かったのは、回路図通りのハードウエアが完成した後の、
プログラム作成に着手してからのことだったので、結果、そのままにしてあります。 当初の考えでは、もちろん、PIC から SSD1306 の VCC をコントロールするためで、本機がスリープモードに入ったときに、省エネのために SSD1306 の VCC も OFF にして、ディスプレイ表示をさせないようにするのが目的でした。 しかし、プログラム作成を進めて行く内の SSD1306 のデータシートを調べている過程で、PIC からコマンドを送ることによって SSD1306 をスリープさせることも可能で、結果、その消費電流を抑えることができる ― ということが分かりました。 したがって、もしも本機のクローンを作製される方は上述のように、トランジスタ 2SA1015Y は不要なため挿入を省略することができます。 PIC のポート RC2 の先に接続されている抵抗 3.3 KΩと 2SA1015Y を取り外し、 SSD1306 の VCC を本機の VCC と直結してください。 本機のプログラムでは、電源の POWER スイッチを ON に操作した直後に、PIC のポート RC2 を Low にして 2SA1015Y が ON するようにしていますが、ポート RC2 の先に何も接続されていなくても何ら問題はありません。 プログラムでは、その後のポート RC2 に対する操作は一切ありません。 |
| 回路図 (PerpetualCalendarII.CE3) | ページトップ |
上回路図を見ていただくと分かるように、本機では3つのモジュール(黄色に塗りつぶしたもの)を使用しています。 そして、それらは私にとっては初めて使用するモジュールも含まれているため、私が感じた問題点やその他のことなどを交えて、次に順に挙げていきます。
● 有機 EL ディスプレイ(OLED)( SSD1306 )モジュール 前回製作した "174. グラフィック液晶表示 万年カレンダー" では、作品名のように、横 128 x 縦 64 ドットのグラフィック液晶(SG12864A)を使用しましたが、本機では、有機 EL (OLED) を用いた I2C 制御の 128 x 64 グラフィックディスプレイモジュールを使用しました。 後者のモジュールには SSD1306 という制御チップが使われていて、前者とは制御方法がまったく異なっています。 このモジュールについては、私がアマゾンの中華モールなるものの存在を知ってから初期の 2020 年 8 月ごろに、複数種類の異なった OLED モジュールとともに購入したものの中の一つで、現在まで4年以上眠らせたままになっていましたが、 ようやく本機で日の目を見ることになりました。 カタログ写真を見ていると、発光色としては、白色、青色、上2列黄色で下6列青色、の3種類のモジュールが存在するようですが、私は白色のモジュールを選択購入しました。
外観は上写真のようなものですが、実際のサイズはかなり小さなもので 0.96 インチと商品説明には書かれており、写真左側の中央に位置する横長の長方形スクリーン部分のサイズは、実測で約 24.5 x 13.5 mm 程のものです。 実際に表示をさせてみても小さ過ぎる感が強く、実用的にはもっと大きな表示器を選択した方が良いと思います(しかし、価格もそれなりに高価になりますが ・・・)。 今回はこの OLED( SSD1306 )モジュールを使用することも、私にとっては目的の一つなのでこのまま製作を進めます。 価格的には、安価に販売をしているアマゾン内のショップ等では、私が購入をした当時とあまり変わっていないようで、現在でも 500 円少々程度で購入が可能なようです。 ちなみに、"秋月電子" でも大きな差はなく 580 円(2024 年 11 月現在)となっています。 本機のようなお遊びとしての製作物では、お手頃価格?かと思います。 また、このモジュールについても、Arduino や Raspberry Pi 用には各種のライブラリが存在しているようですが、本機のように PIC(特にアセンブラ言語)を使用した場合には、既成のライブラリの存在はまったく期待することはできません。 したがって、プログラム面においてはすべてを自分自身で作成することになります。 ● リアルタイムクロックモジュール( DS3231 For PI ) 本機 "有機 EL ディスプレイ(OLED) 表示 万年カレンダー II" のクロック源には、既に公開済みの "199. 多機能携帯デジタル時計" や、"200. 6桁ニキシー管時計 III(IN-17)" で使用した RTC モジュールと同じ "DS3231 For PI" を使用しました。 "DS3231 For PI" についての詳細は、前者 "199. 多機能携帯デジタル時計" の リアルタイムクロックモジュール( DS3231 For PI ) で述べているので、そちらを参照して頂くとして本ページでは、 外観写真と回路図だけを次に再掲しておきます。
また、今回、本機で使用した RTC モジュール個体では、簡単には交換ができないバックアップ用のコイン電池の電圧が、約 2.7 V 程度しかありませんでした。 そのためにも、いつでもコイン電池の交換ができるように変更することと、 上右図の赤線で示した SQW 信号の外部取り出しのための改造が必要になります。 その具体的な改造方法を、既に、後者 "200. 6桁ニキシー管時計 III(IN-17)" の、リアルタイムクロックモジュール( DS3231 For PI ) で詳述しているので、そちらを参照してください。 (注意-1) 改造を行う場合には十分に注意をして行ってください。 今回の改造では恥ずかしながら、私は大失敗をしてしまいました。 改造中にはまったく気が付かなかったのですが、改造が終了した時点で改めてモジュール基板の上面を眺めてみると、 抵抗が1つ剥がれて無くなっていました。 正常な状態では左上の写真のように、IC の左横に奥側から手前に向かって、2個のチップ抵抗と1個のチップコンデンサが並んでいるのですが、一番奥側の 4.3 KΩチップ抵抗、すなわち、SCL 用のプルアップ抵抗が無くなってしまいました。 改造作業中のいつの時点で剥がれてしまったのかは分からないのですが、恐らく 5P のピンソケットをモジュール基板から外している途中で、熱の加わったチップ抵抗もハンダが融けて剥がれてしまったのではないか、と想像をしています。 しかも、かなり小さなチップ抵抗なので、どこへ紛失をしてしまったのかテーブル上を眺めてみても、そこら辺りには見当たりません。 日頃私は、ほとんどチップ部品を使用するようなことはないので、したがって、4.3 KΩチップ抵抗の持ち合わせもありません。 仕方がないので、値の近い 4.7 KΩ 1/6 W カーボン抵抗を、メイン基板側の裏側でモジュール基板の近くに、訳あり ― ということが分かるように、わざと目立つように取り付けておくことにしました。 (注意-2) そしてもう一つ、大々失敗をしてしまったことをついで(?)に白状しておきます。 当初、プリント基板(1) の左上に位置する DS3231 For PI の配線を、 パターン図(誤り) のように作製をしてしまい、何の疑いもなくデバッグ中には通電をしてしまいました。 当然ですが、DS3231 For PI は動作をするわけもなく、クロックパルスが出力されることもなくダンマリ状態です。 POWER スイッチを何度も入れたり切ったりを繰り返しながら、その誤配線に気が付くまでの間、 電源の+−を逆接続の状態で少なくとも延べ数分間、という長時間を通電していたことになります。 漸く誤配線だったことに気が付いて、思わず青ざめました。 DS3231 For PI が壊れてしまったことを半分覚悟しながら、仕方なく重い腰を上げて、プリント基板(1)( DS3231 For PI )の誤配線を正規に直した後、再度、POWER スイッチを入れてみました。 その結果、クロックパルスが出力されたことには、感動を覚えずにはいられませんでした。 電源の+−逆接続 ― という IC にとっては最も過酷と思われる状態は、一体どれほどのダメージを与えるものなのでしょうか。 おかげさまで、その後、現在に至っても DS3231 For PI は、問題なくクロックパルスを出力し続けています。 今回は、私のうっかりミスで、誤配線による電源の+−逆接続を起こしてしまいました。 大いに反省です。 ● TP4056 リチウムイオン電池充電モジュール 本機を使用するための電源として、商用AC電源からスイッチングACアダプタ等を介した方法を採るか、それ以外の電池等の電源とするかを決めるにあたって、本機を据え置き型として使用する場合には当然前者の方が良いのですが、 本機では携帯性を持たすために後者としました。 そして本機では、18650 リチウムイオン電池を採用することにしました。 18650 リチウムイオン電池を使用する場合に、私は生セルタイプを使用することが多くなるため、電池を充電することはもちろんのこと、使用時に過放電(2.4V)、過電流から保護するように、安全面からも "TP4056 リチウムイオン電池充電モジュール" なるものが必須となります。 "TP4056 リチウムイオン電池充電モジュール" として、私は以前には、Micro USB タイプ のモジュールを使用していましたが、最近になって、タイプ C の USB コネクタを使用したモジュールを入手する機会を得たので、 本機では後者のモジュールを使用しました。 前者で使用している USB コネクタは使用時の外力には弱く、容易にモジュール基板から剥がれてしまうことも予測されますが、後者のモジュールでは、USB コネクタがスルーホールでがっちりと取り付けられているため、 使用時に破損させてしまう心配がありません。
タイプ C の USB コネクタを使用したモジュールは、アマゾン等を覗いてみると、Micro USB タイプのモジュールに比べて、かなり高価で販売されているショップを多く見かけますが、私は Temu で安価なショップを見つけたので購入をしてみました。 ちなみに、2024 年 6 月現在において 15 個セットで 445 円でした。 1個当たり 30 円弱ですが、アマゾン等で販売している他のショップでは、これほどの安価な充電モジュールを見かけたことはありません。 願わくは、不良品が混在していないように!と祈るばかりです。 なお、"TP4056 リチウムイオン電池充電モジュール" の機能等については、"197. 18650 リチウムイオン電池充電器" の TP4056 リチウムイオン電池充電モジュール で詳述しているので、そちらを参照してください。 また、上写真のように両者を見比べてみると、購入ショップが異なるためかメーカーも恐らく異なっているらしく、両者では微妙に使用部品の配置や回路構成なども、若干ですが異なっている様子が窺えます。 |
| ページトップ |
以下は外観6面写真です。
|
| ページトップ |
| 機能概要のトップに戻る |
┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ │○│ │○│ │○│ │○│ │○│ └─┘ └─┘ └─┘ └─┘ └─┘ SIGNAL ZERO DOWN UP MODE /CANCEL /BACK /MAINTE /TMODE /SET MODE スイッチ ..... NORMAL モード / LARGE モードの切り替え MODE スイッチ 長押し ..... SET モードに移行(3秒以上の長押し) (SET スイッチ) UP スイッチ ..... カレンダーめくり機能(1か月前に進める) ( LARGE モード中は無視) UP スイッチ 長押し ..... 24時間表示 / 12時間表示の切り替え(3秒以上の長押し) (TMODE スイッチ) DOWN スイッチ ..... カレンダーめくり機能(1か月後に進める) ( LARGE モード中は無視) DOWN スイッチ 長押し ..... メンテナンス機能に移行(3秒以上の長押し) (MAINTE スイッチ) (カレンダーめくり機能中はカレンダーめくり機能) ZERO スイッチ ..... 毎正時プラス・マイナス5分以内を 00分00秒に設定 (5分以外では無視) SIGNAL スイッチ ..... 毎時の時報音出力を ON/OFF 制御
| 機能概要のトップに戻る |
┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ │○│ │○│ │○│ │○│ │○│ └─┘ └─┘ └─┘ └─┘ └─┘ SIGNAL ZERO DOWN UP MODE /CANCEL /BACK /MAINTE /TMODE /SET SET スイッチ ..... ブリンク位置のポインタを + 1 BACK スイッチ ..... ブリンク位置のポインタを - 1 UP スイッチ ..... ブリンク位置の値を + 1 UP スイッチ 長押し ..... ブリンク位置の値を + 1 早送り DOWN スイッチ ..... ブリンク位置の値を - 1 DOWN スイッチ 長押し ..... ブリンク位置の値を - 1 早送り (秒選択時に) SET スイッチ ..... SET モードを終了し、NORMAL / LARGE モードに戻る CANCEL スイッチ ..... SET モードを中断し、NORMAL / LARGE モードに戻る
| 機能概要のトップに戻る |
┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ │○│ │○│ │○│ │○│ │○│ └─┘ └─┘ └─┘ └─┘ └─┘ SIGNAL ZERO DOWN UP MODE /CANCEL /BACK /MAINTE /TMODE /SET SET スイッチ ..... OLED コントラスト / スリープまでの移行時間 の選択 UP スイッチ ..... ブリンク位置の値を + 1 UP スイッチ 長押し ..... ブリンク位置の値を + 1 早送り UP スイッチ + DOWN スイッチ ..... ブリンク位置の値をデフォルト値に設定 DOWN スイッチ ..... ブリンク位置の値を - 1 DOWN スイッチ 長押し ..... ブリンク位置の値を - 1 早送り DOWN スイッチ + UP スイッチ ..... ブリンク位置の値をデフォルト値に設定 BACK スイッチ ..... メンテナンス機能を終了し、NORMAL / LARGE モードに戻る CANCEL スイッチ ..... メンテナンス機能を中断し、NORMAL / LARGE モードに戻る
| 機能概要のトップに戻る | ページトップ | |
本ページの冒頭でも述べたように、本機では PIC16F1705 を採用してプログラム開発を行いました。 プログラムメモリやスタックメモリのサイズも十分にあって、まず、スタックメモリをオーバーフローさせるような心配も少なく、
PIC16F ファミリとは異なるアーキテクチャのもとに追加された便利な命令等を多用して、私にとっては快適にプログラミングを楽しむことができました。 とはいうものの、本機のプログラムが完成するまでには2か月以上が掛かってしまいました。 後述する OLED モジュール ( SSD1306 ) 制御サブルーチンの開発や、メインのプログラムの細部にも多くの機能を追加をしたことで、 全体として多くの時間も要することになりました。 現在、プログラムメモリは、Page 0、Page 1、Page 2、Page 3 の全4ページの内、Page 2 の部分がまるまる空いており、今後も本機に取り入れたい機能の拡張を計るつもりではいますが、少々疲れたのでここでひとまず休憩を入れたいと思います。 身体を休めてから機能の追加を行って、改めてその部分を公開し直したいと思います。 ● 本機で使用した PIC16F1705 のメモリの使用状況 本機のプログラム全体を理解する上で、データメモリの内の特殊機能レジスタ (SFR) には、どのレジスタにアクセスをしているかとか、プログラムメモリの使用状況がどのようになっているか、などの情報が事前に分かっていると、 他の人はもちろんのこと、作者の自分自身でも数か月以上が経ってしまったときには、非常に役に立つと思います。 プログラム規模が大きくなればなるほどそれらの情報が役立つものとして、最近の私作の規模が大きいプログラムでは記録に残しておくようにしています。
次の TABLE 3-2、TABLE 3-3 は、Microchip Technology Inc. 社の PIC16F1705 データシートから、データメモリの内の一部分を抜粋したもので、私がプログラムで一度でもアクセスをしたレジスタについて、それらがよく分かるように彩色を施しました。 黄色や青色に塗ったレジスタが 特殊機能レジスタ (SFR) で、これらの内で青色のものは、High-Endurance フラッシュメモリにアクセスをするときに、必要になるレジスタ群です。 また、薄緑色のレジスタ群は特殊機能レジスタ (SFR) ではなく、 一般の変数など、ユーザが自由に使用できる 汎用レジスタ(GPR) を表しています。
| プログラムのトップに戻る |
次表は、本機(プログラムバージョン: Ver. 1.05 現在)における PIC のプログラムメモリの使用状況を、各処理別に分けたメモリ分布(割り付け)をページごとに表したもので、 今後にプログラム更新があれば、使用メモリの割り付けアドレス等には多少の変動は起こると思いますが、各ページ内における各処理の順番等の構成については、今のところ変更するつもりはないので、プログラム全体を把握する上では参考になるものと思います。 今後の予定としては、現在、Page 2 の部分がまるまる空いているので、そこに追加機能のプログラムを収容するつもりですが、そのプログラムへの導入部分がメインプログラムの処理に必要となるため、 Page 0 の若いアドレスに位置しているメインプログラムのサイズが増大して、以降の各処理のアドレスにも変動が起こり得ます。
| プログラムのトップに戻る | 現在、"SSD1306" をキーワードとしてネット検索をしてみると、随分とたくさんの候補がヒットしますが、その殆どが Arduino や Raspberry Pi 関連のもので、私のような PIC 人間にはとても残念であり、また、肩身の狭いような思いもします。 上述の 本機で使用した各モジュール の 有機 EL ディスプレイ(OLED)( SSD1306 )モジュール の項でも触れましたが、私のように本モジュールを使用するのが初めての者が、 利用できるような PIC 用の既成のライブラリの存在は、まず期待することができません。 しかも、私のように特にアセンブラ言語を使用したプログラミングを行う者にとっては尚更で、最近ではネット検索をしてみても初めからあきらめムードですが、結果は、やはり自分が求めているような情報を得ることはなかなか難しいようです。 それでも、唯一、私が参考にさせて頂いたサイトを見つけたので、ここにお礼も兼ねてご紹介をさせて頂きます。 "JR3TGS' Homebrewing Place" さんの "有機EL (OLED)をPICマイコンで制御" というページです。 お世話になり、ありがとうございました。
◎ グラフィック ディスプレイ データ RAM (GDDRAM) の構成
GDDRAM は、表示されるビット パターンを保持するビット マップ スタティック RAM で、下図の赤枠で囲まれた部分がスクリーン全体のメモリ配置図です。 そのサイズは 128 x 64 ビットで、RAM は PAGE0 から PAGE7 までの 8 つのページに分割され、各ページは SEG0 から SEG127 までの 128 のセグメントで構成されています。 そして、赤枠内の小さな各1マスずつが各1ビットを表し、例えば、薄緑色に塗りつぶした縦列の 8 ビット部分が、各ページ内の各セグメントの1バイトを表しています。 また、その1バイト内の、データ ビット D0 は最上行で、データ ビット D7 は最下行に配置されます。
なお、次項のディスプレイ(OLED) の画面レイアウト以降の説明や、後述する OLED モジュール ( SSD1306 ) 制御サブルーチン 等のプログラムでは、これらのページ、セグメントという構成する単位を、 ページは同様に ページ Page ですが、セグメントは カラム Column という単位で扱っています。 | プログラムのトップに戻る |
◎ ディスプレイ(OLED) の画面レイアウト
本機の画面レイアウトについては、前作の "174. グラフィック液晶表示 万年カレンダー" とほとんど同様としました。 しかし、横 128 x 縦 64 ドットという構成は、前作で使用したグラフィック液晶(SG12864A)と同様ですが、今回使用する OLED (SSD1306) とではその制御方法がまったく異なっています。 ・ NORMAL モード画面 1行目(Page 0)には、年月 "xxxx/xx" 、" "/"am"/"pm" の種別、および時分秒 "xx:xx:xx" を表示するエリアです。 2行目(Page 1)は、 曜日の表示エリアです。 3行目(Page 2)から8行目(Page 7)までが、カレンダーの各日にちが表示されるエリアです。 また、最下行の8行目(Page 7)は、行頭から6文字目以降はカレンダーの日にち表示がされることはないので、画面右下の赤細線枠で囲んだ部分を、 いろいろなメッセージをユーザに伝えるための、メッセージエリアとして使用しています。 なお、1行目(Page 0)と、その他の2行目(Page 1)から8行目(Page 7)までとの、文字フォントを表示しているビット位置に注目をして見比べてください。 Page 0 では bit 0 〜 bit 6 の位置に表示をしていますが、 その他の Page 1 〜 Page 7 では bit 1 〜 bit 7 の位置に表示をしています。 ![]() ・ LARGE モード画面 文字サイズを NORMAL モード画面に比べて、縦横2倍(面積4倍)のサイズで表示します。 したがって、次図に示すように文字表示には1行に 2 Page 分を必要とし、行間には 1 Page 分を割り付けました。 当然ながら日にちの表示は、 NORMAL モード画面のように7曜カレンダーで表示することはできません。 この LARGE モード画面で表示しているときに SET モード機能に移行したときなどには、下図中の Page 2 と Page 5 の行間の空白行をなくして、Page 3, 4 と Page 6, 7 を上方に移動させて表示をし、最下行(Page 7)にメッセージエリアを確保します。 ![]() | Excel ファイル (PerpetualCalendarII_parts.xls) | | プログラムのトップに戻る |
◎ ドライバ IC SSD1306 の I2C インタフェース制御方法
下図 Figure 8-7 は、SSD1306 データシートから抜粋した I2C-bus data format ですが、同図は分かりづらい書き方がしてあって、少々理解するのに苦しみます。 まず、S - Start Condition に続いて Slave Address を送り、その次には Control byte を送るのですが、これから送るデータ群が Command byte なのか Data byte なのかを、D/C# (Data / Command Selection) bit で決めます。 Command byte を送りたい場合には "0" を指定 し、Data byte を送りたい場合には "1" を指定 します。 そして、一度に複数の Command byte または Data byte を送りたい場合には、Co (Continuation) bit に "0" を指定 することによって、以降、何バイトでも連続して送ることができますが、 "1" を指定 した場合には、1バイトの Command byte または Data byte を送ることしかできません。 そして、最後に P - Stop Condition を送って終了させます。 Figure 8-7 では、S - Start Condition から P - Stop Condition までの間に2個の Control byte が現れていますが、1個目に Co=1 指定をした場合は良いのですが Co=0 指定をした場合には、2個目が Control byte なのか Command byte(または Data byte)なのかを、判別する術はないはずですから同図のような送り方には注意が必要だと思います。 図中の1個目の Control byte で m ≧ 0 words という意味 は、Co=1 指定をした場合に 成り立つことで、Co=1 指定 の Control byte + 1バイトの Command byte または Data byte をペア(1 word)として、複数のワードを送ることが可能 ― という意味で、また、図中の2個目の Control byte 後の Data byte で n ≧ 0 bytes という意味 は、2個目の Control byte に Co=0 指定をした場合には、複数バイトの Command byte または Data byte を送ることが可能 ― という意味である、と解釈をしました。 実際には、これらの複数の Control byte を使用した動作確認を私はしていません。 後述する OLED モジュール ( SSD1306 ) 制御サブルーチン では、どのサブルーチンも S - Start Condition から P - Stop Condition までの間には、単純に1つの Control byte だけを使用して I2C インタフェースを制御しています。
例えば、次のリスト例のように、ディスプレイの ON/OFF 制御を行う SSD1306_DispOnOff サブルーチン では、Control byte に Co=1, D/C#=0 を指定して、その後に1バイトの Command byte (h'af' または h'ae') を送っています。 ;========================================================================== ; OLED ( SSD1306 ) の Display ON/OFF 制御 ;========================================================================== ;入力レジスタ: W reg: コマンドデータ h'af':ON / h'ae':OFF ;使用レジスタ: pattern: ワーク SSD1306_DispOnOff movwf pattern ;ワークに一時退避 call i2c_start ;スタートコンディション movlw SSD1306_Addr << 1 ;スレーブアドレス call i2c_byte_send ;1 バイト送信 movlw h'80' ;Control byte Co=1, D/C#=0 call i2c_byte_send ;1 バイト送信 movf pattern,W ;コマンドデータを復帰 call i2c_byte_send ;1 バイト送信 call i2c_stop ;ストップコンディション returnまた、次のコントラスト制御を行う SSD1306_Contrast サブルーチン では、Control byte に Co=0, D/C#=0 を指定して、その後に2バイトの Command byte (h'81' と h'00' 〜 h'ff' のどれか) を送っています。 (この例では2バイトだけを送っていますが、Co=0 指定では 何バイトでも送ることが可能) ;========================================================================== ; OLED ( SSD1306 ) の コントラスト制御 ;========================================================================== ;入力レジスタ: W reg: コマンドデータ h'00'- h'ff' ;使用レジスタ: pattern: ワーク SSD1306_Contrast movwf pattern ;ワークに一時退避 call i2c_start ;スタートコンディション movlw SSD1306_Addr << 1 ;スレーブアドレス call i2c_byte_send ;1 バイト送信 movlw h'00' ;Control byte Co=0, D/C#=0 call i2c_byte_send ;1 バイト送信 movlw h'81' ;Set Contrast Control call i2c_byte_send ;1 バイト送信 movf pattern,W ;コマンドデータを復帰 call i2c_byte_send ;1 バイト送信 call i2c_stop ;ストップコンディション return上に挙げた2つの例では、どちらも D/C#=0 指定で Command byte を送っていますが、D/C#=1 を指定すれば、同様に Data byte を送ることができます。 そして、Command byte を送った場合には、SSD1306 を制御するためのコマンドとして解釈されますが、Data byte を送った場合には、ディスプレイの表示データとして GDDRAM へ書き込まれます。 なお、コマンドには多くの種類が用意されていて、詳細は SSD1306 データシートの 9 COMMAND TABLE (P 28/59) をご覧ください。 | プログラムのトップに戻る |
◎ ディスプレイ RAM (GDDRAM) のアドレス指定モード
GDDRAM のアドレス指定モードには、下図に示す Figure 10-1 ページ アドレス指定モード、Figure 10-3 水平アドレス指定モード、Figure 10-4 垂直アドレス指定モード の3種類があります。(これらの図は SSD1306 データシート から抜粋)
上図 ページ アドレス指定モード では、ディスプレイ RAM へ1バイトデータを書き込んだ後、カラム アドレス ポインタが自動的に1増加します。 カラム アドレス ポインタがカラム終了アドレスに達すると、カラム アドレス ポインタはカラム開始アドレスにリセットされますが、ページ アドレス ポインタは変更されません。 次のページのディスプレイ RAM にアクセスするには、新しいページ アドレスとカラム アドレスを設定する必要があります。 実際に ページ アドレス指定モード を使用した例として、次項の緑色リストの SSD1306_FontPos サブルーチン を参照してみてください。
上図 水平 アドレス指定モード では、ディスプレイ RAM へ1バイトデータを書き込んだ後、カラム アドレス ポインタが自動的に1増加します。 カラム アドレス ポインタがカラム終了アドレスに達すると、カラム アドレス ポインタはカラム開始アドレスにリセットされ、ページ アドレス ポインタが 1 増加します。 カラム アドレス ポインタとページ アドレス ポインタの両方が終了アドレスに達すると、それぞれのポインタは、カラム開始アドレスとページ開始アドレスにリセットされます。 実際に 水平 アドレス指定モード を使用した例として、次項の緑色リストの SSD1306_Clear サブルーチン を参照してみてください。
上図 垂直 アドレス指定モード では、ディスプレイ RAM へ1バイトデータを書き込んだ後、ページ アドレス ポインタが自動的に1増加します。 ページ アドレス ポインタがページ終了アドレスに達すると、ページ アドレス ポインタはページ開始アドレスにリセットされ、カラム アドレス ポインタが 1 増加します。 カラム アドレス ポインタとページ アドレス ポインタの両方が終了アドレスに達すると、それぞれのポインタは、カラム開始アドレスとページ開始アドレスにリセットされます。 実際に 垂直 アドレス指定モード を使用した例として、次項の緑色リストの SSD1306_Line_V サブルーチン を参照してみてください。 なお、上に挙げた3つのサブルーチン例では、それぞれ複数の Command byte を送っていますが、それらの Command byte の意味を理解するには、SSD1306 データシートの 9 COMMAND TABLE (P 28/59)、および 10 COMMAND DESCRIPTIONS (P 34/59) を、 熟読してください(当然ながら英文ですが・・・)。 | プログラムのトップに戻る |
◎ OLED モジュール ( SSD1306 ) 制御サブルーチン
次に示す緑色リストのサブルーチン群は、SSD1306 データシートの 9 COMMAND TABLE (P 28/59) の中から、本機 "201. 有機 EL ディスプレイ(OLED) 表示 万年カレンダー II" の、 プログラムを作成するために必要となるコマンドに限ってを、いくつか選択してサブルーチン集として私がまとめ上げたものです。 このサブルーチン集を動作させるためには、他にも、次リストの冒頭部分のコメントで述べているように、I2C インタフェース用の外部ルーチン (I2C_XS.sub) や、外部テーブル (Font5x7.tbl) 等が必要になりますが、 それらは 現在の最新プログラムバージョン に収録をしてありますので、そちらを参照してみてください。 ;<使用外部ルーチン> ;(i2c_start, i2c_stop, i2c_byte_send, i2c_ack, i2c_nack) : : ;<使用テーブル> ;font5x7_data_tbl(外部テーブル: Font5x7.tbl) ;font10x14_data_tblなお、I2C インタフェース用の外部ルーチン (I2C_XS.sub) については、"189. ドットマトリクス 8 x 8 LED 表示時計 II ( MAX7219 版)" の リアルタイムクロックモジュールのプログラミング でもリストを示して触れているので、そちらも参照してみてください。 また、文字フォント(10 x 14)データテーブル(font10x14_data_tbl)については、そのサイズが大きくなるために、本機で必要となるフォントデータだけを作成して、本機のソースプログラム (PerpetualCalendarII.asm) 中の、プログラムメモリ (Page 3) 部分に収録がしてあるので、"font10x14_data_tbl" または "(Page 3)" で検索をしてください。 ;========================================================================== ; OLED モジュール ( SSD1306 ) 制御サブルーチン ;========================================================================== ;<使用外部ルーチン> ;(i2c_start, i2c_stop, i2c_byte_send, i2c_ack, i2c_nack) ;<使用レジスタ> ;pagex ;表示開始ページ ;end_pagex ;表示終了ページ ;column ;表示開始カラム ;end_column ;表示終了カラム ;pattern ;水平ビット位置,垂直パターン,ワーク ;echr_flg ;表示文字の機能拡張フラグ ; ;oled_lpcnt ;ループカウンタ ;<使用テーブル> ;font5x7_data_tbl(外部テーブル: Font5x7.tbl) ;font10x14_data_tbl ;========================================================================== ; 定数の定義 ;========================================================================== SSD1306_Addr equ h'3c' ;OLED モジュール ( SSD1306 ) のスレーブアドレス ;========================================================================== ; マクロ命令定義 ;========================================================================== ; OLED_FontPos_M マクロ ;フォントの表示開始位置指定 OLED_FontPos_M macro @col,@row movlw @col ; movwf column ;表示カラム movlw @row ; movwf pagex ;表示ページ call SSD1306_FontPos ;表示開始位置指定 endm ; OLED_DispStr_M マクロ ;キャラクタ (横:6 x 縦:8) 文字列の表示 OLED_DispStr_M macro @str_adr,@x #if @x != 0 movlw high @str_adr ;文字列の先頭 high アドレス movwf FSR0H ; movlw low @str_adr ;文字列の先頭 low アドレス movwf FSR0L ; #endif call SSD1306_DispStr ;文字列データ1行表示 endm ; OLED_DispStr2_M マクロ ;キャラクタ (横:12 x 縦:16) 文字列の表示 OLED_DispStr2_M macro @str_adr,@x #if @x != 0 movlw high @str_adr ;文字列の先頭 high アドレス movwf FSR0H ; movlw low @str_adr ;文字列の先頭 low アドレス movwf FSR0L ; #endif call SSD1306_DispStr2 ;文字列データ1行表示 endm ; OLED_Line_H_M マクロ ;水平線表示 OLED_Line_H_M macro @col_st,@col_sp,@row,@ptn movlw @col_st ; movwf column ;表示開始カラム movlw @col_sp ; movwf end_column ;表示終了カラム movlw @row ; movwf pagex ;表示ページ movlw @ptn ; movwf pattern ;ビット位置 call SSD1306_Line_H ;モジュールの水平線表示 endm ; OLED_Line_V_M マクロ ;垂直線表示 OLED_Line_V_M macro @col,@row_st,@row_sp,@ptn movlw @col ; movwf column ;表示カラム movlw @row_st ; movwf pagex ;表示開始ページ movlw @row_sp ; movwf end_pagex ;表示終了ページ movlw @ptn ; movwf pattern ;垂直パターン call SSD1306_Line_V ;モジュールの垂直線表示 endm ;========================================================================== ; フォントの表示開始位置指定 ;========================================================================== ;入力レジスタ: pagex: 表示ページ ; column: 表示カラム SSD1306_FontPos call i2c_start ;スタートコンディション movlw SSD1306_Addr << 1 ;スレーブアドレス call i2c_byte_send ;1 バイト送信 movlw h'00' ;Control byte Co=0, D/C#=0 call i2c_byte_send ;1 バイト送信 movlw h'20' ;Set Memory Addressing Mode call i2c_byte_send ;1 バイト送信 movlw h'02' ;Page Addressing Mode call i2c_byte_send ;1 バイト送信 movf pagex,W addlw h'b0' ;Set Page Start Addrss for Page Addressing Mode call i2c_byte_send ;1 バイト送信(ページ開始アドレスの設定) movf column,W andlw h'0f' ;Set Lower Column Start Address for Page Addressing Mode call i2c_byte_send ;1 バイト送信(カラム開始アドレスの下位ニブル) swapf column,W andlw h'0f' addlw h'10' ;Set Higher Column Start Address for Page Addressing Mode call i2c_byte_send ;1 バイト送信(カラム開始アドレスの上位ニブル) call i2c_stop ;ストップコンディション return ;========================================================================== ; キャラクタ (横:6 x 縦:8) 文字の表示 ;========================================================================== ;入力レジスタ: W reg: 表示する文字コード (h'20'〜h'df') ; echr_flg: 表示文字の機能拡張フラグ ;(Ver.1.01にて追加) ; bit7: ビット反転表示指示 ; bit6: 1 bit 左(下)ずらし指示 ;使用レジスタ: oled_lpcnt, pattern, FSR1H:FSR1L ;使用テーブル: font5x7_data_tbl(外部テーブル: Font5x7.tbl) SSD1306_DispChr movwf FSR1L ;表示する文字コード clrf FSR1H movlw h'20' ;h'20'がテーブルの先頭位置 subwf FSR1L,F movf FSR1L,W ;W に一時退避 lslf FSR1L,F ;x2 rlf FSR1H,F lslf FSR1L,F ;x4 rlf FSR1H,F addwf FSR1L,F ;x5 ... 退避した W を足す clrw addwfc FSR1H,F ;C フラグを足す movlw low font5x7_data_tbl ;フォントテーブルデータの先頭 low アドレス addwf FSR1L,F ; movlw high font5x7_data_tbl ;フォントテーブルデータの先頭 high アドレス addwfc FSR1H,F ; ; call i2c_start ;スタートコンディション movlw SSD1306_Addr << 1 ;スレーブアドレス call i2c_byte_send ;1 バイト送信 movlw h'40' ;Control byte Co=0, D/C#=1 call i2c_byte_send ;1 バイト送信 movlw 5 ; movwf oled_lpcnt ;ループカウンタ dspchr1 call oledtbl_read ;テーブルデータの読み出し movwf pattern ;ワークに一時退避 movlp high $ ;この場所の high アドレス btfss echr_flg,7 ;ビット反転表示指示 か? goto dspchr2 ;No movlw h'7f' xorwf pattern,F ;ビット反転 dspchr2 btfsc echr_flg,6 ;1 bit 左(下)ずらし指示 か? lslf pattern,F ;Yes movf pattern,W ;ワーク call i2c_byte_send ;1 バイト送信 addfsr FSR1,1 ;間接アドレス FSR1H:FSR1L + 1 decfsz oled_lpcnt,F ;ループカウンタ - 1 = 0 か? goto dspchr1 ;No clrw ;文字間 h'00' 1 バイト追加 btfsc echr_flg,7 ;ビット反転表示指示 か? movlw h'7f' ;Yes. ビット反転 btfss echr_flg,6 ;1 bit 左(下)ずらし指示 か? goto dspchr3 ;No movwf pattern ;ワーク lslf pattern,W ; dspchr3 call i2c_byte_send ;1 バイト送信 call i2c_stop ;ストップコンディション return ;========================================================================== ; キャラクタ (横:6 x 縦:8) 文字列の表示 ;========================================================================== ;入力レジスタ: FSR0H:FSR0L: 文字列の先頭アドレス ;<使用例> movlw high title_msg ;文字列の先頭 high アドレス ; movwf FSR0H ; ; movlw low title_msg ;文字列の先頭 low アドレス ; movwf FSR0L ; ; call SSD1306_DispStr ;文字列データ1行表示 ; : ;title_msg dt "Perpetual Calendar",0 SSD1306_DispStr dspstr1 call str_read ;文字列データの読み出し movlp high $ ;この場所の high アドレス addfsr FSR0,1 ;間接アドレス FSR0H:FSR0L + 1 addlw 0 btfsc STATUS,Z ;文字列の終了(h'00') か? goto dspstr2 ;Yes call SSD1306_DispChr ;OLED へデータを1文字出力 goto dspstr1 dspstr2 return ; テーブルデータの1文字読み出し str_read movf FSR0H,W ;読み出すデータの high アドレス movwf PCLATH movf FSR0L,W ;読み出すデータの low アドレス movwf PCL ;========================================================================== ; キャラクタ (横:12 x 縦:16) 文字の表示 ;========================================================================== ;入力レジスタ: W: 表示する文字コード (h'2f'(/), h'30'(0) 〜 h'39'(9), h'3a'(:)) ; echr_flg: 表示文字の機能拡張フラグ ;(Ver.1.01にて追加) ; bit7: ビット反転表示指示 ;使用レジスタ: oled_lpcnt, pattern, FSR1H:FSR1L ;使用テーブル: font10x14_data_tbl SSD1306_DispChr2 movwf FSR1L ;表示する文字コード clrf FSR1H movlw h'2f' ;h'2f'がテーブルの先頭位置 subwf FSR1L,F lslf FSR1L,F ;x2 rlf FSR1H,F lslf FSR1L,F ;x4 rlf FSR1H,F movf FSR1L,W ;W に一時退避 lslf FSR1L,F ;x8 rlf FSR1H,F lslf FSR1L,F ;x16 rlf FSR1H,F addwf FSR1L,F ;x20 ... 退避した W を足す clrw addwfc FSR1H,F ;C フラグを足す movlw low font10x14_data_tbl ;フォントテーブルデータの先頭 low アドレス addwf FSR1L,F ; movlw high font10x14_data_tbl ;フォントテーブルデータの先頭 high アドレス addwfc FSR1H,F ; SSD1306_DispChr2s call dsp2chr0 ;文字の上位半分の表示 ; incf pagex,F ;文字の下位半分の表示位置 call SSD1306_FontPos ;フォントの表示開始位置指定 dsp2chr0 call i2c_start ;スタートコンディション movlw SSD1306_Addr << 1 ;スレーブアドレス call i2c_byte_send ;1 バイト送信 movlw h'40' ;Control byte Co=0, D/C#=1 call i2c_byte_send ;1 バイト送信 clrw ;文字間 h'00' 1 バイト追加 btfsc echr_flg,7 ;ビット反転表示指示 か? movlw h'ff' ;Yes. ビット反転 call i2c_byte_send ;1 バイト送信 movlw 10 ; movwf oled_lpcnt ;ループカウンタ dsp2chr1 call oledtbl_read ;テーブルデータの読み出し movwf pattern ;ワークに一時退避 movlp high $ ;この場所の high アドレス btfss echr_flg,7 ;ビット反転表示指示 か? goto dsp2chr2 ;No movlw h'ff' xorwf pattern,F ;ビット反転 dsp2chr2 movf pattern,W ;ワーク call i2c_byte_send ;1 バイト送信 addfsr FSR1,1 ;間接アドレス FSR1H:FSR1L + 1 decfsz oled_lpcnt,F ;ループカウンタ - 1 = 0 か? goto dsp2chr1 ;No clrw ;文字間 h'00' 1 バイト追加 btfsc echr_flg,7 ;ビット反転表示指示 か? movlw h'ff' ;Yes. ビット反転 call i2c_byte_send ;1 バイト送信 call i2c_stop ;ストップコンディション return ;========================================================================== ; キャラクタ (横:12 x 縦:16) 文字列の表示 ;========================================================================== ;入力レジスタ: FSR0H:FSR0L: 文字列の先頭アドレス ;<使用例> movlw high date_msg ;文字列の先頭 high アドレス ; movwf FSR0H ; ; movlw low date_msg ;文字列の先頭 low アドレス ; movwf FSR0L ; ; call SSD1306_DispStr2 ;文字列データ1行表示 ; : ;date_msg dt "2024/12/02",0 SSD1306_DispStr2 dsp2str1 call str_read ;文字列データの読み出し movlp high $ ;この場所の high アドレス addfsr FSR0,1 ;間接アドレス FSR0H:FSR0L + 1 addlw 0 btfsc STATUS,Z ;文字列の終了(h'00') か? goto dsp2str2 ;Yes call SSD1306_DispChr2 ;OLED へデータを1文字出力 decf pagex,F ;文字の上位半分の表示位置に戻す movlw 12 addwf column,F ;カラム位置の更新 call SSD1306_FontPos ;次文字の表示位置 goto dsp2str1 dsp2str2 return ;========================================================================== ; OLED ( SSD1306 ) モジュールの水平線表示 ;========================================================================== ;入力レジスタ: pagex: 表示ページ ; column: 表示開始カラム ; end_column: 表示終了カラム ; pattern: ビット位置: h'01', h'02', h'04', h'08', h'10', h'20', h'40', h'80' ;使用レジスタ: oled_lpcnt: ループカウンタ SSD1306_Line_H call SSD1306_FontPos ;表示開始位置の指定 movf column,W ;表示開始カラム subwf end_column,W ;表示終了カラム addlw 1 movwf oled_lpcnt ;ループカウンタ ; call i2c_start ;スタートコンディション movlw SSD1306_Addr << 1 ;スレーブアドレス call i2c_byte_send ;1 バイト送信 movlw h'40' ;Control byte Co=0, D/C#=1 call i2c_byte_send ;1 バイト送信 oled_lh1 movf pattern,W ; call i2c_byte_send ;1 バイト送信 decfsz oled_lpcnt,F ;ループカウンタ - 1 = 0 か? goto oled_lh1 ;No call i2c_stop ;ストップコンディション return ;========================================================================== ; OLED ( SSD1306 ) モジュールの垂直線表示 ;========================================================================== ;入力レジスタ: pagex: 表示開始ページ ; end_pagex: 表示終了ページ ; column: 表示カラム ; pattern: 垂直パターン: h'00' 〜 h'ff' ;使用レジスタ: oled_lpcnt: ループカウンタ SSD1306_Line_V call i2c_start ;スタートコンディション movlw SSD1306_Addr << 1 ;スレーブアドレス call i2c_byte_send ;1 バイト送信 movlw h'00' ;Control byte Co=0, D/C#=0 call i2c_byte_send ;1 バイト送信 movlw h'20' ;Set Memory Addressing Mode call i2c_byte_send ;1 バイト送信 movlw h'01' ;Vertical Addressing Mode call i2c_byte_send ;1 バイト送信 movlw h'21' ;Set Column Address カラムアドレスの設定 call i2c_byte_send ;1 バイト送信 movf column,W ;Column start address, range: 0-127 call i2c_byte_send ;1 バイト送信 movf column,W ;Column end address, range: 0-127 call i2c_byte_send ;1 バイト送信 movlw h'22' ;Set Page Address ページアドレスの設定 call i2c_byte_send ;1 バイト送信 movf pagex,W ;Page start Address, range: 0-7 call i2c_byte_send ;1 バイト送信 movf end_pagex,W ;Page end Address, range: 0-7 call i2c_byte_send ;1 バイト送信 call i2c_stop ;ストップコンディション ; movf pagex,W ;表示開始ページ subwf end_pagex,W ;表示終了ページ addlw 1 movwf oled_lpcnt ;ループカウンタ call i2c_start ;スタートコンディション movlw SSD1306_Addr << 1 ;スレーブアドレス call i2c_byte_send ;1 バイト送信 movlw h'40' ;Control byte Co=0, D/C#=1 call i2c_byte_send ;1 バイト送信 oled_lv1 movf pattern,W ; call i2c_byte_send ;1 バイト送信 decfsz oled_lpcnt,F ;ループカウンタ - 1 = 0 か? goto oled_lv1 ;No call i2c_stop ;ストップコンディション return ;========================================================================== ; OLED ( SSD1306 ) モジュールの画面消去 ;========================================================================== ;使用レジスタ: oled_lpcnt, FSR1H:FSR1L SSD1306_Clear movlw high ssd1306_clear_table ;テーブルデータの先頭 high アドレス movwf FSR1H ; movlw low ssd1306_clear_table ;テーブルデータの先頭 low アドレス movwf FSR1L ; movlw ssd1306_clear_table_end - ssd1306_clear_table movwf oled_lpcnt ;ループカウンタ call oledini00 ;(SSD1306_Init 内) ; call i2c_start ;スタートコンディション movlw SSD1306_Addr << 1 ;スレーブアドレス call i2c_byte_send ;1 バイト送信 movlw h'40' ;Control byte Co=0, D/C#=1 call i2c_byte_send ;1 バイト送信 movlw high (128 * 8) ;128culomn * 8page movwf FSR1H movlw low (128 * 8) movwf FSR1L ;ループカウンタ oledclr01 clrw ;h'00' call i2c_byte_send ;1 バイト送信 addfsr FSR1,-1 ;ループカウンタ - 1 movf FSR1H,W ; iorwf FSR1L,W ; btfss STATUS,Z ;FSR1H = FSR1L = h'00' か? goto oledclr01 ;No call i2c_stop ;ストップコンディション return ;-------------------------------------------------------------------------- ; OLED ( SSD1306 ) の画面消去用コマンドデータ・テーブル ssd1306_clear_table dt SSD1306_Addr << 1 ;スレーブアドレス dt h'00' ;Control byte Co=0, D/C#=0 dt h'20' ;Set Memory Addressing Mode dt h'00' ;Horizontal Addressing Mode dt h'21' ;Set Column Address カラムアドレスの設定 dt 0 ;Column start address, range: 0-127 dt 127 ;Column end address, range: 0-127 dt h'22' ;Set Page Address ページアドレスの設定 dt 0 ;Page start Address, range: 0-7 dt 7 ;Page end Address, range: 0-7 ssd1306_clear_table_end ;========================================================================== ; OLED ( SSD1306 ) モジュールの初期設定 ;========================================================================== ;使用レジスタ: oled_lpcnt, FSR1H:FSR1L SSD1306_Init movlw high ssd1306_init_table ;テーブルデータの先頭 high アドレス movwf FSR1H ; movlw low ssd1306_init_table ;テーブルデータの先頭 low アドレス movwf FSR1L ; movlw ssd1306_init_table_end - ssd1306_init_table movwf oled_lpcnt ;ループカウンタ oledini00 call i2c_start ;スタートコンディション oledini01 call oledtbl_read ;テーブルデータの読み出し call i2c_byte_send ;1 バイト送信 addfsr FSR1,1 ;間接アドレス FSR1H:FSR1L + 1 decfsz oled_lpcnt,F ;ループカウンタ - 1 = 0 か? goto oledini01 ;No call i2c_stop ;ストップコンディション return ; テーブルデータの1文字読み出し oledtbl_read movf FSR1H,W ;読み出すデータの high アドレス movwf PCLATH movf FSR1L,W ;読み出すデータの low アドレス movwf PCL ;-------------------------------------------------------------------------- ; OLED ( SSD1306 ) の初期設定用コマンドデータ・テーブル ssd1306_init_table dt SSD1306_Addr << 1 ;スレーブアドレス dt h'00' ;Control byte Co=0, D/C#=0 dt h'a8' ;Set Multiplex Ratio dt h'3f' ;h'00'- h'3f' ; dt h'd3' ;Set Display Offset dt h'00' ;h'00'- h'3f' ; dt h'40' ;h'40'- h'7f' ;Set Display Start Line dt h'a1' ;h'a0'/ h'a1' ;Set Segment Re-map, 左右反転 dt h'c8' ;h'c0'/ h'c8' ;Set COM Output Scan Direction, 上下反転 dt h'da' ;Set COM Pins Hardware Configuration dt h'12' ;h'02'- h'32' ; dt h'81' ;Set Contrast Control dt h'7f' ;h'00'- h'ff' ;コントラスト dt h'a4' ;h'a4'/ h'a5' ;Disable Entire Display On dt h'a6' ;h'a6'/ h'a7' ;Set Normal Display, 白黒反転 dt h'd5' ;Set Osc Frequency dt h'80' ;h'00'- h'ff' ; dt h'8d' ;Enable Charge Pump Regulator dt h'14' ;h'04'/ h'14' ; dt h'af' ;h'ae'/ h'af' ;Display On, h'ae':OFF / h'af':ON ssd1306_init_table_end ;========================================================================== ; OLED ( SSD1306 ) の Display ON/OFF 制御 ;========================================================================== ;入力レジスタ: W reg: コマンドデータ h'af':ON / h'ae':OFF ;使用レジスタ: pattern: ワーク SSD1306_DispOnOff movwf pattern ;ワークに一時退避 call i2c_start ;スタートコンディション movlw SSD1306_Addr << 1 ;スレーブアドレス call i2c_byte_send ;1 バイト送信 movlw h'80' ;Control byte Co=1, D/C#=0 call i2c_byte_send ;1 バイト送信 movf pattern,W ;コマンドデータを復帰 call i2c_byte_send ;1 バイト送信 call i2c_stop ;ストップコンディション return ;========================================================================== ; OLED ( SSD1306 ) の コントラスト制御 ;========================================================================== ;入力レジスタ: W reg: コマンドデータ h'00'- h'ff' ;使用レジスタ: pattern: ワーク SSD1306_Contrast movwf pattern ;ワークに一時退避 call i2c_start ;スタートコンディション movlw SSD1306_Addr << 1 ;スレーブアドレス call i2c_byte_send ;1 バイト送信 movlw h'00' ;Control byte Co=0, D/C#=0 call i2c_byte_send ;1 バイト送信 movlw h'81' ;Set Contrast Control call i2c_byte_send ;1 バイト送信 movf pattern,W ;コマンドデータを復帰 call i2c_byte_send ;1 バイト送信 call i2c_stop ;ストップコンディション return ;=============================================================== end ====== | プログラムのトップに戻る |
◎ OLED モジュール ( SSD1306 ) 制御サブルーチンの使用例
前項の OLED モジュール ( SSD1306 ) 制御サブルーチンを、実際に使用した例を次に示します。 本機が NORMAL モード、または LARGE モードのときに、MODE / SET スイッチ を3秒間以上押し続けると、"ピッ" とブザー音とともに、 ディスプレイ画面右下のメッセージエリアに、" SET MODE " と文字列のビット反転表示がされますが、そのときに使用される SET モードメッセージの表示 (setmode_display) サブルーチン の例を取り上げてみました。 ; SET モードメッセージの表示 setmode_display OLED_FontPos_M 4+6*10,7 ;表示開始位置の指定 movlw h'c0' ;h'c0': ビット反転表示とビットずらし指示 movwf echr_flg ; OLED_DispStr_M setmode_msg,1 ;メッセージ文字列の表示 bcf echr_flg,7 ;ビット反転表示指示解除 return setmode_msg dt " SET MODE ",0このように、数行の命令群でサブルーチンを書くことができます。 この例では OLED_FontPos_M と OLED_DispStr_M の、2つのマクロ命令を使用しているためで、これらのマクロ命令は、MPLAB X IDE v5.35 を実行するとアセンブラ MPASM によって、次リストのようにマクロ展開(LINE 欄が M 表記の行)が行われます。 LOC OBJECT CODE LINE SOURCE TEXT VALUE 02276 02277 ; SET モードメッセージの表示 02278 0521 02279 setmode_display 02280 OLED_FontPos_M 4+6*10,7 ;表示開始位置の指定 0521 3040 M movlw 4+6*10 ; 0522 00E3 M movwf column ;表示カラム 0523 3007 M movlw 7 ; 0524 00E1 M movwf pagex ;表示ページ 0525 2??? M call SSD1306_FontPos ;表示開始位置指定 0526 30C0 02281 movlw h'c0' ;h'c0': ビット反転表示とビットずらし指示 0527 00E6 02282 movwf echr_flg ; 02283 OLED_DispStr_M setmode_msg,1 ;メッセージ文字列の表示 M #if 1 != 0 0528 30?? M movlw high setmode_msg ;文字列の先頭 high アドレス 0529 0085 M movwf FSR0H ; 052A 30?? M movlw low setmode_msg ;文字列の先頭 low アドレス 052B 0084 M movwf FSR0L ; M #endif 052C 2??? M call SSD1306_DispStr ;文字列データ1行表示 052D 13E6 02284 bcf echr_flg,7 ;ビット反転表示指示解除 052E 0008 02285 return 02286 052F 3420 3453 3445 02287 setmode_msg dt " SET MODE ",0 3454 3420 344D 344F 3444 3445 3420 3400 022881つ目の OLED_FontPos_M マクロ命令 で、メッセージ文字列の表示開始位置を指定した後、ビット反転表示指示とビットずらし指示をしながら、2つ目の OLED_DispStr_M マクロ命令 で、メッセージ文字列の1行分を表示しています。 これらのマクロ命令では、実際には、それぞれに決められている引数を各変数に引き渡した後、フォントの表示開始位置指定 (SSD1306_FontPos) サブルーチン や、キャラクタ (横:6 x 縦:8) 文字列の表示 (SSD1306_DispStr) サブルーチン が実行されます。 なお、SSD1306_DispStr サブルーチン内では、キャラクタ (横:6 x 縦:8) 文字の表示 (SSD1306_DispChr) サブルーチン が、文字列の文字数だけ繰り返し CALL されています。 ここに示した SET モードメッセージの表示 (setmode_display) サブルーチン の使用例を理解するためには、前項で示した緑色リストの OLED モジュール ( SSD1306 ) 制御サブルーチン 内に書かれてある、OLED_FontPos_M マクロ、OLED_DispStr_M マクロ、SSD1306_FontPos サブルーチン、SSD1306_DispChr サブルーチン、SSD1306_DispStr サブルーチンを理解する必要があります。 | プログラムのトップに戻る | 下に示したリストは、本機のソースプログラムファイル (PerpetualCalendarII.asm) を入力として、MPLAB X IDE v5.35 を実行したときに、アセンブラ MPASM によって、実際に吐き出されたアセンブルリスト (PerpetualCalendarII.lst) の、 ほんの一部分だけを抜粋したリストですが、随所に文字化けを起こしているのが確認できます。 本機のソースプログラム内では、3本のサブルーチンファイルを include していますが、その内の OLED モジュール制御サブルーチンファイル (OLED_SSD1306.sub) 部分 だけと、そのファイル内で定義されているマクロ命令を、ソースプログラム内で使用して アセンブラ MPASM によって展開された部分 だけが、文字化けを起こしています。 下のリストでは、OLED_SSD1306.sub ファイルを include して、その中の冒頭部分、OLED_FontPos_M マクロ、SSD1306_FontPos サブルーチンと、そして、実際に OLED_FontPos_M マクロを使用している部分の一例だけを抜粋してあります。 (現在の最新プログラムバージョン には、参考として全リストを収録してあります) 私は以前から、各種のプログラムファイルやサブルーチンファイルを作成するのに、メモ帳を愛用していますが、それらを 単体ファイルとして見た場合には、メモ帳はもちろん Microsoft Edge などのブラウザで閲覧した場合にも、何ら文字化けを起こすことはなく ごく普通に見えています。 ところが、MPASM によってソースプログラム内に include され、アセンブルリストになると文字化けを起こしてしまいます。 これは MPASM 自体に問題があるのでしょうか? それとも、OLED モジュール制御サブルーチンファイル (OLED_SSD1306.sub) 内に、化けるような異常なコードが含まれているのでしょうか? 下のリスト内で実際に文字化けを起こしているのは、コメント部分に書かれている漢字部分(2バイト文字)だけなので、生成されるオブジェクトファイルには実害はないと思いますが、アセンブルリストを見たときには気持ちが良いものではありません。 : : : 00856 include C:\Data\Project\PIC\_sub\OLED_SSD1306.sub 00001 ;***** OLED_SSD1306.sub *************************************************** 00002 ; 00003 ; OLED 繝「繧ク繝・繝シ繝ォ ( SSD1306 ) 蛻カ蠕。繧オ繝悶Ν繝シ繝√Φ 00004 ; 00005 ; (SSD1306_FontPos, SSD1306_DispChr, SSD1306_DispStr, ) 00006 ; ( SSD1306_DispChr2, SSD1306_DispStr2,) 00007 ; (SSD1306_Line_H, SSD1306_Line_V, SSD1306_Clear, SSD1306_Init,) 00008 ; (SSD1306_DispOnOff, SSD1306_Contrast) 00009 ; 00010 ; Copyright (C) 2024 by M.Yamamoto. All rights reserved. 00011 ; 00012 ; Homepage URL: https://xyama.sakura.ne.jp/hp/PerpetualCalendarII.html 00013 ; 00014 ; ( coding: Ver. 0.00 2024/11/20 by M.Yamamoto ) 00015 ; coding: Ver. 1.00 2024/12/02 蝓コ譛ャ繧オ繝悶Ν繝シ繝√Φ縺ョ菴懈・ 00016 ; update: Ver. 1.01 2024/12/05 SSD1306_DispChr,SSD1306_DispChr2縺ョ讖溯・諡。蠑オ 00017 ; update: Ver. 1.02 2024/12/18 SSD1306_FontPos繧貞、画峩 00018 ; update: Ver. 1.03 2024/12/21 SSD1306_DispChr2繧貞、画峩 00019 ; update: Ver. 1.04 2024/12/28 SSD1306_DispOnOff,SSD1306_Contrast繧定ソス蜉 00020 ; bugfix: 00021 ; 00022 ;******************************************************* PicAsm 0269 ****** 00023 00024 ;<菴ソ逕ィ螟夜Κ繝ォ繝シ繝√Φ> 00025 00026 ;(i2c_start, i2c_stop, i2c_byte_send, i2c_ack, i2c_nack) 00027 00028 ;<菴ソ逕ィ繝ャ繧ク繧ケ繧ソ> 00029 00030 ;pagex ;陦ィ遉コ髢句ァ九・繝シ繧ク 00031 ;end_pagex ;陦ィ遉コ邨ゆコ・・繝シ繧ク 00032 ;column ;陦ィ遉コ髢句ァ九き繝ゥ繝 00033 ;end_column ;陦ィ遉コ邨ゆコ・き繝ゥ繝 00034 ;pattern ;豌エ蟷ウ繝薙ャ繝井ス咲スョ,蝙ら峩繝代ち繝シ繝ウ,繝ッ繝シ繧ッ 00035 ;echr_flg ;陦ィ遉コ譁・ュ励・讖溯・諡。蠑オ繝輔Λ繧ー 00036 ; 00037 ;oled_lpcnt ;繝ォ繝シ繝励き繧ヲ繝ウ繧ソ 00038 00039 ;<菴ソ逕ィ繝・・繝悶Ν> 00040 00041 ;font5x7_data_tbl・亥、夜Κ繝・・繝悶Ν: Font5x7.tbl・・ 00042 ;font10x14_data_tbl 00043 00044 ;========================================================================== 00045 ; 螳壽焚縺ョ螳夂セゥ 00046 ;========================================================================== 00047 0000003C 00048 SSD1306_Addr equ h'3c' ;OLED 繝「繧ク繝・繝シ繝ォ ( SSD1306 ) 縺ョ繧ケ繝ャ繝シ繝悶い繝峨 Ξ繧ケ 00049 00050 ;========================================================================== 00051 ; 繝槭け繝ュ蜻ス莉、螳夂セゥ 00052 ;========================================================================== 00053 00054 ; OLED_FontPos_M 繝槭け繝ュ ;繝輔か繝ウ繝医・陦ィ遉コ髢句ァ倶ス咲スョ謖・ョ・ 00055 00056 OLED_FontPos_M macro @col,@row 00057 movlw @col ; 00058 movwf column ;陦ィ遉コ繧ォ繝ゥ繝 00059 movlw @row ; 00060 movwf pagex ;陦ィ遉コ繝壹・繧ク 00061 call SSD1306_FontPos ;陦ィ遉コ髢句ァ倶ス咲スョ謖・ョ・ 00062 endm 00063 : : : 00115 00116 ;========================================================================== 00117 ; 繝輔か繝ウ繝医・陦ィ遉コ髢句ァ倶ス咲スョ謖・ョ・ 00118 ;========================================================================== 00119 00120 ;蜈・蜉帙Ξ繧ク繧ケ繧ソ: pagex: 陦ィ遉コ繝壹・繧ク 00121 ; column: 陦ィ遉コ繧ォ繝ゥ繝 00122 00CB 00123 SSD1306_FontPos 00CB 2??? 00124 call i2c_start ;繧ケ繧ソ繝シ繝医さ繝ウ繝・ぅ繧キ繝ァ繝ウ 00CC 3078 00125 movlw SSD1306_Addr << 1 ;繧ケ繝ャ繝シ繝悶い繝峨Ξ繧ケ 00CD 2??? 00126 call i2c_byte_send ;1 繝舌う繝磯∽ソ。 00CE 3000 00127 movlw h'00' ;Control byte Co=0, D/C#=0 00CF 2??? 00128 call i2c_byte_send ;1 繝舌う繝磯∽ソ。 00D0 3020 00129 movlw h'20' ;Set Memory Addressing Mode 00D1 2??? 00130 call i2c_byte_send ;1 繝舌う繝磯∽ソ。 00D2 3002 00131 movlw h'02' ;Page Addressing Mode 00D3 2??? 00132 call i2c_byte_send ;1 繝舌う繝磯∽ソ。 00133 00D4 0861 00134 movf pagex,W 00D5 3EB0 00135 addlw h'b0' ;Set Page Start Addrss for Page Addressing Mode 00D6 2??? 00136 call i2c_byte_send ;1 繝舌う繝磯∽ソ。・医・繝シ繧ク髢句ァ九い繝峨Ξ繧ケ縺ョ險ュ螳 夲シ・ 00D7 0863 00137 movf column,W 00D8 390F 00138 andlw h'0f' ;Set Lower Column Start Address for Page Addressing Mode 00D9 2??? 00139 call i2c_byte_send ;1 繝舌う繝磯∽ソ。・医き繝ゥ繝髢句ァ九い繝峨Ξ繧ケ縺ョ荳倶ス 阪ル繝悶Ν・・ 00DA 0E63 00140 swapf column,W 00DB 390F 00141 andlw h'0f' 00DC 3E10 00142 addlw h'10' ;Set Higher Column Start Address for Page Addressing Mod e 00DD 2??? 00143 call i2c_byte_send ;1 繝舌う繝磯∽ソ。・医き繝ゥ繝髢句ァ九い繝峨Ξ繧ケ縺ョ荳贋ス 阪ル繝悶Ν・・ 00DE 2??? 00144 call i2c_stop ;繧ケ繝医ャ繝励さ繝ウ繝・ぅ繧キ繝ァ繝ウ 00DF 0008 00145 return 00146 : : : 02276 02277 ; SET モードメッセージの表示 02278 0521 02279 setmode_display 02280 OLED_FontPos_M 4+6*10,7 ;表示開始位置の指定 0521 3040 M movlw 4+6*10 ; 0522 00E3 M movwf column ;陦ィ遉コ繧ォ繝ゥ繝 0523 3007 M movlw 7 ; 0524 00E1 M movwf pagex ;陦ィ遉コ繝壹・繧ク 0525 2??? M call SSD1306_FontPos ;陦ィ遉コ髢句ァ倶ス咲スョ謖・ョ・ 0526 30C0 02281 movlw h'c0' ;h'c0': ビット反転表示とビットずらし指示 0527 00E6 02282 movwf echr_flg ; 02283 OLED_DispStr_M setmode_msg,1 ;メッセージ文字列の表示 M #if 1 != 0 0528 30?? M movlw high setmode_msg ;譁・ュ怜・縺ョ蜈磯ュ high 繧「繝峨Ξ繧ケ 0529 0085 M movwf FSR0H ; 052A 30?? M movlw low setmode_msg ;譁・ュ怜・縺ョ蜈磯ュ low 繧「繝峨Ξ繧ケ 052B 0084 M movwf FSR0L ; M #endif 052C 2??? M call SSD1306_DispStr ;譁・ュ怜・繝・・繧ソ・題。瑚。ィ遉コ 052D 13E6 02284 bcf echr_flg,7 ;ビット反転表示指示解除 052E 0008 02285 return 02286 052F 3420 3453 3445 02287 setmode_msg dt " SET MODE ",0 3454 3420 344D 344F 3444 3445 3420 3400 02288 : : :このように、OLED モジュール制御サブルーチンファイル (OLED_SSD1306.sub) を include した場合だけに起こる現象で、他の2ファイルを include した場合には至って正常で、まったく文字化けなどは起きていません。 やはり、同ファイル内に異常なコードが含まれている ― としか思えないのですが ・・・ * (その後、サーバ上にアップロードした (OLED_SSD1306.sub) を、Microsoft Edge で閲覧した場合にも文字化けを起こすことが分かりました。) そこで、この項をお読みになった方々にお願いがあります。 ファイル内に異常なコードが含まれているような場合に、どの文字が異常なのか、それを発見するにはどのようにすれば判るのか ― もしも、ご存じでしたらぜひともご教授ください。 (メールアドレスは、当サイトの トップページ(ホーム) の左上に表示の【 ご挨拶とお願い 】をクリックしていただけると、開いたページの最下行に表示がされています。) | プログラムのトップに戻る |
| ページトップ | |
使用したメインとなる下図 左側のプリント基板 は、"秋月電子" の "片面ガラスコンポジット・ユニバーサル基板 Bタイプ めっき仕上げ(95 x 72 mm)日本製 型番: AE-B2-CEM3(販売コード 103230)" ですが、後述の ケース加工図
で示したケース内に収めるためには、プリント基板の切断等の加工が必要です。 左図に示すように、まず基板下部の ----- X 線の位置で切断をします。 そして、この切断によって失われた基板下部の取り付け用穴の代理となる、新たなΦ3.2 の穴を図のように2か所開けます。 次に、基板右端に位置するスイッチ用基板の取り付けのために用いる、 ジュラコンスペーサ用のΦ3.2 の穴を2か所開けます。
次に 右側のプリント基板 は、"秋月電子" の "片面ガラス・ユニバーサル基板 Cタイプ(72 x 47.5 mm)めっき仕上げ(販売コード 100517)" で、左側メイン基板の右端に取り付けるスイッチ用基板になるもので、 他にコネクタ用の小基板2枚も切り出します。 図の ----- 線に従って、Y1, Y2, X1, X2, X3, X4 の順に切断をします。 Y2 線よりも左側の大きな部分と、X3 線よりも下部分は余りで今回は使用しません。 図中の (A) 基板がスイッチ用基板で、2か所のΦ3.2 の穴を開けることも忘れないでください。 (B), (C) の小さな基板は、メイン基板との接続のためのコネクタ用に使用します。 | プリント基板部品配置図 (PerpetualCalendarIIPC0.CE3) | (PerpetualCalendarII2PC0.CE3) | ページトップ | |
メイン基板に多くのパーツを搭載するにあたっては、それぞれに対して以降に述べるような注意事項があるので、基板を組み立てる上での参考にしてください。
なお、図の中で、細長い長方形の中に ○で表したものはピンヘッダ(オス)を、同様に◎で表したものはピンソケット(メス)を使用することを表しているので、注意をしてください。
・RTC モジュール( DS3231 For PI ) プリント基板の左上角に位置する小さな四角状のものが RTC モジュール( DS3231 For PI )で、本機では リアルタイムクロックモジュール( DS3231 For PI ) の項で説明をした改造が必要になります。 具体的には、"200. 6桁ニキシー管時計 III(IN-17)" の リアルタイムクロックモジュール( DS3231 For PI ) の項で詳述しているので、それに従って改造を行ってください。 改造後の RTC モジュール( DS3231 For PI )の取り付けは、付け替えた 5P のピンヘッダとメイン基板とを、直接ハンダ付けをします。 また、上写真に写っている赤色線のように、RTC モジュール基板のコイン電池を取り外した跡の+側に接続してあるジャンパー線も、 メイン基板のコイン電池ホルダの+端子との接続を、忘れないように必ず行います。 ・TP4056 充電モジュール プリント基板の左下に位置する "TP4056 充電モジュール" の取り付けについては、まず、縦横4か所の各青色線で示す位置の、メイン基板のハンダ面側から 0.4 〜 0.5 mm の錫メッキ線等を通し、モジュール基板上面側で各青色線の対となるもう片方の穴へグルっとUターンをして、 再び、メイン基板のハンダ面側に通した後はんだ付けをします。 このとき、モジュール基板側は 2.54 mm ピッチではないため注意が必要ですが、メイン基板側の穴位置は、前項 プリント基板の加工と部品配置 で示した縦横4か所の各青色線で示したランド穴位置を選択すれば問題はないでしょう。 次に、モジュール基板左側の斜2か所の青色線で示すモジュール基板側の穴に対応するメイン基板側の位置には、ランド穴が開いていないのでこの位置にΦ1 程度の穴を開ける必要があり * ます。 穴を開けた後、前の縦横4か所のときと同要領で斜2か所についても、錫メッキ線等でモジュール基板の固定をします。 ただし、前の縦横4か所についてはその後、メイン基板のハンダ面側で回路の配線が必要になりますが、この斜2か所については回路の配線はありません。
・OLED モジュール プリント基板の上部中央には、本機の目玉である OLED モジュールが位置します。 メイン基板側にはあらかじめ 4P のピンソケットを取り付けておき、OLED モジュール側のピンヘッダと嵌合させます。 このとき、ピンソケットには分割ピンソケットを使用するとその加工が楽になります。 ・トグルスイッチ プリント基板下部中央に位置する POWER スイッチには、3P(1回路)のトグルスイッチで良いのですが、3P でレバーが短いタイプが私の持ち合わせになく、6P(2回路)のものがあったので私は代わりにそれを使用しました。 したがって、3P でレバーが短いタイプを入手した場合には、基板パターン図を 3P(1回路)用に変更をしてください。 本機では ケース加工図 で示したケース(内寸高さ 24 mm)を使用したため、レバーが通常のタイプは不可で、短いタイプでないとケース内に収めることができません。 通常、本機のように時計関連の製作物には POWER スイッチ等は設けない場合が多いのですが、本機の場合には、18650 リチウムイオン電池を充電する場合には、TP4056 充電モジュールの負荷接続端子を開放しておく必要があるために、その目的でスイッチを設置しました。 ・タクトスイッチ用基板との接続コネクタ プリント基板の右端縦長の位置に、タクトスイッチ用基板を取り付けますが、この基板の取り付けには、後述の ケースへのプリント基板の取り付け で説明しているように、私の場合には手持ちの関係で、 13 mm 長のオネジ+メネジの六角ジュラコンスペーサ(廣杉計器 BS-313W)を使用しました。 そして、電気的な接続には、下の プリント基板(2)パターン図 (部品面) (ハンダ面) の項で示した、タクトスイッチ用基板のケーブルコネクタ( 6P ピンソケット(メス))と、メイン基板上に設けた 6P L型ピンヘッダとを、常時接続をさせておきます。 なお、メイン基板側のピンヘッダは、パターン図や写真のように L型でないと接続ができません。 ・その他 プリント基板左下の 3P のピンヘッダ B+ と B- 端子には、本機の電源である 18650 リチウムイオン電池を、電池ホルダからの配線( 3P ピンソケット(メス))を介して接続させます。 電気的には 2P で良いのですが、 2P 状態よりも 3P の方が、しっかりとコネクタ接続ができるために 3P としました。 そのため、真ん中のピンには配線はしていません。 | プリント基板パターン図 (部品面) (PerpetualCalendarIIPC.CE3) | 左図から黒色文字を除いた図 (PerpetualCalendarIIPC2.CE3) | ページトップ | |
前項 プリント基板パターン図 (部品面) でも述べたように、下パターン図や写真は、トグルスイッチに 3P(1回路)ではなく 6P(2回路)を使用したものなので、3P(1回路)トグルスイッチを使用した場合には、
スイッチ周りのパターンを適宜変更をしてください。
| プリント基板パターン図 (ハンダ面) (PerpetualCalendarIIPC1.CE3) | ページトップ | |
本機では、タクトスイッチをプリント基板(2) に取り付けるときには、スイッチの底面を基板にぴったり押し付けて取り付けることが必要です。 (詳細は、後述の ケースへのプリント基板の取り付け の項を参照してください。) |
![]() |
![]() |
| プリント基板(2)パターン図 (部品面) (PerpetualCalendarII2PC.CE3) | ページトップ |
![]() |
![]() |
| プリント基板(2)パターン図 (ハンダ面) (PerpetualCalendarII2PC1.CE3) | ページトップ |
本機のケースは、"秋月電子" の "ABS樹脂ケース(蝶番式・中)112−TS ニシムラ (販売コード: 100277)" を使用しました。 外側(内側)寸法が 117 (112) x 84 (80) x 28 (24) mm で、可動式のフタが付いています。
上図の(上面図)及び(左側面図)において、各丸穴の位置寸法を記入* はしてありますが、参考程度に見ておいてください。 実際に穴開けを行う場合には、プリント基板を仮に取り付けた後、ケースが透明で中が透けて見えているので、 現物合わせで丸穴の中心位置を千枚通し等で印を付けて位置決めを行った方が、穴開けがうまくいくと思います。 ただし、(下面図)におけるプリント基板の取り付け用の穴位置は、極力、正確な位置に穴開けを行うように心掛けてください。
・メイン基板の取り付け 上図の(下面図)はケースの裏面側から見た図で、上部の大きな点線の四角部分(72 x 89 mm)がメイン基板の取り付け位置です。 私がプリント基板をケース等に取り付ける場合、通常、両者の間には 5 mm 長のスペーサを挟んで 取り付けることが多いのですが、本機のメイン基板には 5 mm 長のスペーサを使用することができません。 上の プリント基板パターン図 (部品面) の項で、使用した トグルスイッチ について述べたように、本機ではレバーが短いタイプを使用していますが、メイン基板を上図のケース内に納めるためには 5 mm 長のスペーサでは長過ぎて、 上蓋が閉まらなくなってしまいます。 そこで本機では M3 のナットをスペーサ代わり、としました。 ウィルコ で購入したナットで、 "鉄(ニッケルめっき) 六角ナット・1種 FNT-03N" の厚さ 2.4 mm のものです。 ケースの裏面側(外側)の4か所から、それぞれ M3 x 10 サイズのビス(+なべ小ねじ)を通し、ケース内側でスペーサ代わりの M3 ナット → メイン基板 → ポリカーボネート平ワッシャー → M3 ナット、の順に取り付けます。 ポリカーボネート平ワッシャーは、プリント基板表面の傷つき防止とねじ緩み防止を兼ねて挿入をしてあります。(ねじ類の型番等については、使用部品表 を参照のこと) ・電池ホルダーの取り付け 同様に上図の(下面図)で、下部の横に細長い点線の四角部分に、18650 リチウムイオン電池用の電池ホルダーを取り付けます。 私が使用した電池ホルダー、およびその取り付けるときの注意点、方法などについては、 別ページ "198. MP3プレーヤー I" の 電池ホルダーをケースに取り付け を参考にしてください。 | ケース加工図 (PerpetualCalendarIICS.CE3) | ページトップ | |
下図は本機ケースの右側面側から上部半分ほどを見た図で、2枚のプリント基板やタクトスイッチの取り付けの様子がよく分かるように、右側面を切り取った断面図で表しています。 ケースへのメイン基板の取り付けに当たって、最も重要なのはその上下(高さ)位置で、重複しますが上述した メイン基板の取り付け のように、本機ではトグルスイッチ搭載のために M3 のナットをスペーサ代わりとして使用しています。 そして、前項で述べたケースを使用する限り、この状態が最もベストな上下(高さ)位置で変更することはできません。 また、同図に示すように本機では、スイッチ用プリント基板に取り付けたタクトスイッチのトップが、ケース上面から適度な長さ(X)を飛び出すようにしなければなりません。 そのために、タクトスイッチには手持ちにあった通常のものより少々長い、 スイッチ底面からトップまでの長さが 9.5mm のものを使用し、スイッチ用基板をメイン基板に取り付けるのに、これも手持ちの関係で右写真のような、M3 x 13 mm 長のオネジ+メネジの六角ジュラコンスペーサ(廣杉計器 BS-313W)を使用しました。
余談ですが、タクトスイッチをプリント基板に取り付ける場合に、私は通常、スイッチを基板穴に軽く押し込んだときに、足ピンがくの字に曲がったあたりで進入が止まった位置、すなわち、スイッチ底面が少し基板上面から浮いた位置でハンダ付けをすることが多いのですが、 今回は上図のように、スイッチ底面が基板上面に付くまでスイッチを押し込んで使用しました。 これは使用したタクトスイッチとスペーサの各長さによって X 値を調節するためで、ちなみに図の組み合わせでは X ≒ 2 mm ほどになりました。 | 基板の取り付け図 (pcb_attach.CE3) | ページトップ | |
(主要部品: IC, トランジスタ等) | (データシート) | |||
PICマイコン | .................... | PIC16F1705 | ||
三端子レギュレータ | .................... | S-812C33AY-B-G | ||
.................... | ||||
有機 EL ディスプレイ(OLED) | .................... | SSD1306 | ||
圧電ブザー | .................... | PKM17EPP-4001 |
| 部品表 | Excel ファイル (PerpetualCalendarII_parts.xls) | ページトップ |
PIC16F1705 データシート | .......... | https://ww1.microchip.com/downloads/en/DeviceDoc/40001729C.pdf | ||
SSD1306 データシート | .......... | https://akizukidenshi.com/goodsaffix/ssd1306.pdf | ||
174. グラフィック液晶表示 万年カレンダー | .......... | https://xyama.sakura.ne.jp/hp/PerpetualCalendar.html | ||
有機EL (OLED)をPICマイコンで制御 | .......... | https://jr3tgs-homebrew.net/contents/oled_test/oled_test.html |