三端子レギュレータとLCDの実装

#1．はじめに
今回の記事ではデータロガーに供給する電圧を作り出す三端子レギュレータとLCD(Liquid Crystal Display；液晶ディスプレイ)を動かしてみます．
農業農村工学系の人にとっては馴染みのない言葉も多く登場しますが，できるだけ詳しく解説したいと思います．
なお，わかりにくい箇所などがあったら遠慮なく連絡をください．解説などを追記します．
ツイッター：https://twitter.com/6LxAi9GCOmRigUI
メール：BattleShipMissouriWater@gmail.com

記事の構成は以下の通りです．
1．はじめに
2．必要な工具および部品
3．部品の組み立て
4．配線
5．プログラムの書き込み
6．プログラムの加工方法
7．おわりに
8．ソースコード

今回は実際に組み立てて動かしてみますが，ソースコードの詳しい解説は次回の記事で行います．

【気象・水文観測機器の自作】シリーズ一覧

>
【気象・水文観測機器の自作】　第1回　装置の概要
https://qiita.com/6LxAi9GCOmRigUI/items/bfdfc038e4360961d289
【気象・水文観測機器の自作】　第2回　完成品と部品の紹介
https://qiita.com/6LxAi9GCOmRigUI/items/8476ff1723f2f00dc45d
【気象・水文観測機器の自作】　第3回　三端子レギュレータとLCDの実装
https://qiita.com/6LxAi9GCOmRigUI/items/188b72d38bd81924c49c

###用語集
必要に応じて活用してください．

|用語|意味や説明|参考|
|:-----:|:-----|:-----|
|ブレッドボード|ソケット(穴)に部品を差し込むだけで電子回路の試作・実験が可能になる便利な道具|https://denshi-kousaku.nazotoki-k.com/kiso/eic-801.htm|
|ジャンパーワイヤー|ブレッドボードに刺して電子部品同士をを繋ぐ道具|https://dotstud.io/docs/jumperwire/#:~:text=%E3%82%B8%E3%83%A3%E3%83%B3%E3%83%91%E3%83%AF%E3%82%A4%E3%83%A4%E3%81%A8%E3%81%AF%E3%80%81%E3%81%9D%E3%81%AE,%E3%81%AA%E3%81%84%E3%82%82%E3%81%AE%E3%81%AE%E4%B8%80%E3%81%A4%E3%81%A7%E3%81%99%E3%80%82|
|PIC|電子部品を制御する司令塔のような存在|https://www.marutsu.co.jp/pc/static/large_order/begin_pic|
|PICKit3|PICとパソコンを繋ぎPICにプログラムを書き込むための道具．ライター(Writer)ともいう．|http://www.picfun.com/PICkit2/PICkit01.html|
|10進数|普段僕らが使っている数値の数え方．1桁を0～9の10個の数字で表す．10進数であることを明示するときは0d〇〇と書く．dはdemicalの意味．例えば，10進数の13は0d13と書く．||
|2進数|1桁を0か1かの2個の数字で表現する．コンピュータは2進数しか扱えない．2進数であることを明示するときは0b〇〇と書く．bはbinaryの意味．例えば，10進数の13は0b1101と書く．|https://www.pc-master.jp/words/2sinsu.html|
|16進数|1桁を0～15の16個の数字で表現する．2進数は桁が多くなり扱いづらいため，16進数がよく使われる．16進数であることを明示するときは0x〇〇と書く．xはhexadecimalの意味．例えば，10進数の13は0xDと書く．|https://www.pc-master.jp/words/2sinsu.html|
|三端子レギュレータ|電圧を変換するために使う電子部品|https://radio1ban.com/bb_regu/|
|文字コード|コンピュータに使われる文字に1対1で対応する番号を付けて表現する方法．|https://opentype.jp/charactercode.htm|
|ASCIIコード|文字コードの規格の1つ．アスキーコードと読む．今回使用するLCDでも採用されている規格|https://www.k-cube.co.jp/wakaba/server/ascii_code.html|
|統合開発環境|テキストエディタ，コンパイラ，デバッガなどと呼ばれる開発に必要なアイテムを1つにまとめたソフト．|https://tech-camp.in/note/technology/43103/|
|MPLAB|PICの開発に使う統合開発環境||
|プログラム|機械(パソコンなど)を動かすための命令文|||
|ソースコード|プログラミング言語を使って書かれた機械への命令書||

環境：
OS:Windows 10 Education
統合開発環境：MPLAB X IDE v5.45
ライター：PICKit3

#2．必要な工具および部品

|電子部品名称|個数||工具など|
|:-------:|:----:|:----:|:----:|
|LCDキャラクタディスプレイモジュール|1個||ブレッドボード|
|耐熱電子ワイヤー|-||ジャンパーワイヤー|
|半固定抵抗20kΩ|1個||PICKit3|
|QIコネクタハウジング(2×7ピン)|1個||テスター|
|QIコネクタハウジング(9ピン)|1個||はんだ|
|2.1mmDCジャック|1個||はんだごて|
|DCジャックDIP化基盤|1個||ACアダプター|
|三端子レギュレータ5V 100mA|1個||精密圧着ペンチ|
|電解コンデンサ10μF 16V|2個||ケーブルストリッパー|
|セラミックコンデンサ0.1μF 50V|2個||ニッパー|
|汎用整流用ダイオード|1個||収縮チューブ|
|PIC18F26K22|1個||ライターかドライヤーかトースター|
|丸ピンICソケット(28ピン)|1個|||
|ピンヘッダ1×40 (40P)|1個|||

#3．部品の組み立て
##3.1．LCDの組み立て(ピンソケットの取り付け)
LCDに付属している7×2穴のピンソケットを取り付けます．ピンヘッダもついでに取り付けてください．
はんだ付けの方法がわからない場合はググるか中学の技術の教科書を見てください．

>村田製作所：電子工作のコツ/はんだ付け
https://article.murata.com/ja-jp/article/soldering#:~:text=%E3%81%BE%E3%81%9A%E3%81%AF%E3%82%93%E3%81%A0%E3%81%94%E3%81%A6%E3%82%92,4%E7%A7%92%E3%81%8F%E3%82%89%E3%81%84%E6%B8%A9%E3%82%81%E3%81%BE%E3%81%99%E3%80%82&text=%E6%AC%A1%E3%81%AB%E3%80%81%E3%81%93%E3%81%A6%E5%85%88,%E3%81%84%E3%81%8F%E3%81%BE%E3%81%A7%E6%BA%B6%E3%81%8B%E3%81%97%E7%B6%9A%E3%81%91%E3%81%BE%E3%81%99%E3%80%82

![LCD.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/db723ebd-deea-0183-82c9-9df3d77870c1.jpeg)

##3.2．DCジャックの組み立て
・まずピンヘッダをニッパーで切って，1×4のピンヘッダを2本作ります．
![IMG20210501114745.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/cf253397-264a-a1f8-553f-d60ef6d9304e.jpeg)

・まずブレッドボードにピンヘッダを刺し，上からDCジャックDIP化基板を乗せます．DCジャックDIP化基板の表裏を間違えないように注意してください．
・DIP化基盤とピンヘッダをはんだ付けします．
![DCジャック1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/29001dd5-1237-05df-c215-c89c73b983c9.jpeg)
・2.1mm DCジャックをはんだ付けします．DCジャックを割り箸で挟んでマスキングテープで机に固定するなど工夫するとはんだ付けが楽になります．

![DCジャック2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/a2c1510a-3ff4-07cc-fdd6-37ae602dd081.jpeg)

##3.3．LCD接続用のケーブルの組み立て
・耐熱電子ワイヤーを所定の長さに切り出す．赤色約10 cm(2本)，黒色約10 cm(2本)，緑色約10 cm(1本)，黄色約18 cm(4本)，青色約18 cm(3本)です．長さはある程度テキトーでも大丈夫です．
・ケーブルストリッパーかニッパーを使ってケーブルの両側の被覆を5 mmほど剥いてください．ただし，赤・黒・緑のケーブルについては一方を15 mmほど剥いてください．
![LCDケーブル.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/f6aa1c2e-6835-b15b-0a83-a99ffb450b32.jpeg)
・被覆を5 mmほど剥いたケーブル端にQIコネクターのオスピンを精密圧着ペンチで取り付けます．

>QIコネクタ圧着方法
http://blog.digit-parts.com/archives/51796900.html
https://voltechno.com/blog/crimper-cable/
https://fumimaker.net/entry/2019/06/16/220408

![IMG20210502105405.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/c99c525b-af2b-bd2e-e0a6-859b76c24863.jpeg)

・20kΩの半固定抵抗に被覆を15 mmほど剥いた赤・黒・緑色のケーブル端をはんだ付けします．ただし，半固定抵抗のP 203と書いてある面を正面から見たときの真ん中の足に緑色のケーブルを付けてください．
・うまく繋ぐコツ：まず，ケーブル端にはんだを少し付けます．ラジオペンチではんだが付着したケーブルと足をつまんだ状態で，はんだごてを押し当てます．はんだが溶けてケーブルと足が一体化したらはんだごてを離して固化させる．
![IMG20210502160343.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/0ce737c7-5080-633c-e704-63e4a282492a.jpeg)

・はんだ付けした部分を覆うくらいの長さに収縮チューブを切る．
・それぞれの色のケーブルを収縮チューブに差し込む．
![IMG20210502160521 (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/cf925f57-af20-7bc2-bdd5-4f918d7692ee.jpeg)

・ライターであぶって収縮させる．ちなみにライターの火が近すぎると写真のように焦げます(失敗例)．収縮チューブは赤・黒・緑のケーブルがショートしないようにする役割があります．
![IMG20210502160744.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/9523401b-f05e-ef98-337b-a944b521db11.jpeg)

・QIコネクタハウジングにケーブルを差し込む．
![IMG20210502162856.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/8764b2d1-8a44-df63-feaf-ebc34ef733c1.jpeg)

・ハウジングには，番号が振ってあるわけではないので自分でどっちから数えるか決めてください．一般的にはハウジングに刻印されている△マークを基準にすることが多いです．ただし，LCD側のハウジング(2×7)の番号の振り方はLCDの裏側に書かれている番号と一致するようにしてください(写真の1，2，13，14という番号を参照)．
・テスターの導通確認機能を使って圧着がうまくいっているか，ケーブルがちゃんとつながっているか確認しましょう．
![IMG20210502095812.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/065be06c-764a-6c41-d2f6-a1ee800e75e6.jpeg)

・ケーブルの接続は下表を参考にしてください．ちなみにVDD，VSS，Voさえ合っていれば後からプログラム上で修正できます．

|LCD側(2×7ピンコネクタハウジング)|半固定抵抗|PIC側(1×9ピンコネクタハウジング)|
|:----:|:----:|:----:|
|1番：VDD(電源プラス側；5V)|左側の足|VDDポート(PICの20番ピン)|
|2番：VSS(電源マイナス側；GND)|右側の足|VSSポート(PICの19番ピン)|
|3番：Vo(コントラスト調整用)|真ん中の足||
|4番：RS(通信制御)||GPIOのRC5ポート(PICの16番ピン)|
|5番：RW(通信制御)||GPIOのRC6ポート(PICの17番ピン)|
|6番：E(通信制御)||GPIOのRC7ポート(PICの18番ピン)|
|7番：DB0(使用しない)|||
|8番：DB1(使用しない)|||
|9番：DB2(使用しない)|||
|10番：DB3(使用しない)|||
|11番：DB4(データ送信)||GPIOのRB0ポート(PICの21番ピン)|
|12番：DB5(データ送信)||GPIOのRB1ポート(PICの22番ピン)|
|13番：DB6(データ送信)||GPIOのRB2ポート(PICの22番ピン)|
|14番：DB7(データ送信)||GPIOのRB3ポート(PICの23番ピン)|

##3.4．PICへの丸ピンソケットの取り付け

・PICの足の幅は，丸ピンソケットの足の幅より広いので机に押し当てて内側に曲げます．
![IMG20210501120423 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/7502eb6c-d87e-c83d-d4dc-d2cd4c028e30.jpeg)

・PICを丸ピンソケットに取り付けてください．切り欠き(半円状)を合わせるようにしてください．
![IMG20210501120336.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/8f866866-cc9e-232a-397d-5d4a8a7f15a3.jpeg)
![IMG20210501120716 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/7eaeed45-08fe-35b9-421c-34c651a43916.jpeg)

#4．配線
##4.1．三端子レギュレータの配線
今回用意したACアダプターの出力値は9Vです．今回使う電子部品には5Vもしくは3.3Vを供給するので，三端子レギュレータという部品で電圧を変換します．
![IMG20210503130818.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/a971408a-0296-92c3-fd04-ccc17b143652.jpeg)

実態配線図の電圧変換部(三端子レギュレータ)を参考に配線してください．右側の茶色のユニバーサル基盤は無視してください．

>ブレッドボードの使い方
https://denshi-kousaku.nazotoki-k.com/kiso/eic-801.htm


![実態配線図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/363be4b4-2efa-1738-c572-f89c6d46af8d.png)

写真では，三端子レギュレータ，セラミックコンデンサ，電解コンデンサ，整流用ダイオードはもっと密集した状態になっています．部品の向きを間違えないように注意しましょう．
紫色の線が9V，黒色が0V(GND)，赤色が5Vです．
配線が完了したら，ACアダプターを繋いでテスターで赤色と黒色の間の直流電圧を測定してください．5V(実際には4.98V程度)であればオッケーです．

>三和電気計器株式会社：PM3取扱説明書
https://www.sanwa-meter.co.jp/japan/pdf/manual/digital_multimeters/PM3_JP.pdf

##4.2．LCDとPICとPICライターの配線
・PICとLCDとPICKit3(PICライター)も繋いでみましょう．PICとLCDは**3.3**で作成したケーブルを繋ぐだけです．他の部分はジャンパーワイヤーで接続してください．なお，SC1602Bの素材がなかったのでLCDの画像は実物とは異なります．実物はピン数が14だが，実態配線図では20になっています．LCDの15～20番のピンは無視してください．
・PICkit3の素材もなかったので実態配線図と写真が若干ことなりますが，ご容赦ください(配線方法がわかりづらい場合は記事の最後に記載している連絡先までご連絡ください)．
・半固定抵抗のねじをドライバーで回してLCDの画面がうっすら黒く塗りつぶされる状態にしてください(コントラスト調整)．
![IMG20210502180605.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/e0db34da-edba-90f2-6203-b7d886755b9b.jpeg)

#5．プログラムの書き込み
今回はMPLABという統合開発環境を使って，PICにプログラムを書き込みます．MPLAB上で作成するファイルをプロジェクトファイルと呼びます．
##5.1．環境構築
以下のサイトを参考にMPLAB・XC8コンパイラ・MCCのインストールをしてください
>MPLABの環境構築とトラブルシューティング
https://qiita.com/6LxAi9GCOmRigUI/items/e7185ac24cc300d79cc4

**この段階でパソコンとPICKit3，作成した回路を繋いでください．**

##5.2．プロジェクトファイルの作成
プロジェクトファイルはライブドアブログで公開しています
>

http://blog.livedoor.jp/senkan_missouri/%E3%83%87%E3%83%BC%E3%82%BF%E3%83%AD%E3%82%AC%E3%83%BC_%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.zip

メニューバーのFile>>New Projectをクリック．
![MPLAB X IDE v5.45 2021_05_02 17_28_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/2dbfc138-8494-e59b-4d3d-d1cb657d0fbc.png)

使用するPICの型番(PIC18F26K22)とPICWriterの種類を選択します．
![MPLAB X IDE v5.45 2021_05_02 17_28_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/f2afcd50-b197-6523-e30e-c7396d3d6587.png)

・インストールしたコンパイラ(XC8)を選択します．
![MPLAB X IDE v5.45 2021_05_02 17_28_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/386722f5-5e88-bfa9-00be-1aae8c464330.png)

プロジェクト名を入力し，Encodingタブは「Shift JIS」を選択します．
![MPLAB X IDE v5.45 2021_05_02 17_29_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/3d56cff7-0584-d92d-64b4-95b154bda6dd.png)

左側のプロジェクトウィンドウに作成したプロジェクトが表示されます．
![MPLAB X IDE v5.45 - DataLogger _ default 2021_05_02 17_30_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/fc9b639e-add3-63d7-8e68-2e5607bf1ec6.png)

メニューバーの少し下にある青色のMCCボタンをクリックすると，次のようなウィンドウが表示されるので，「保存」をクリック．
![Screenshot 2021_05_02 17_30_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/64b32540-d32c-f524-f1bb-ec6bfa1f1c88.png)

「System Module」タブの「Easy Setup」タブの「System Clock Select」を「FOSC」に，「Internal Clock」を「16MHz_HFINTOSC」にする．
![MPLAB X IDE v5.45 - DataLogger _ default 2021_05_02 17_32_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/f8906320-552e-ef2b-e771-a3489d53799c.png)
・「System Module」タブの「Registers」タブの「FCMEN」を「Fail-Safe Clock Monitor enabled」に，「HFOFST」を「HFINTOSC output and ready status are delayed by the oscillator stable status」にする．
・画面下の「Pin Manager: Grid View」の「Package」を「PDIP28」にする．
・LCDを接続しているピンの南京錠マークをクリックして緑色に変えてください．outputとinputを間違えないように注意．画面の「Pin Manager: Package View」も併せて確認しましょう．
![MPLAB X IDE v5.45 - DataLogger _ default 2021_05_04 13_10_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/cb9e953a-c12a-3378-d8a9-84c730efcee8.png)
「Pin Module」タブを開き，「Analog」列のチェックボックスをすべて外してください．
![MPLAB X IDE v5.45 - DataLogger _ default 2021_05_02 17_32_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/cb255dcb-bf5b-3c9c-d024-c80385c39acb.png)

・画面左の「Resource Mangement」ウィンドウの「generate」ボタンを押してください．
・画面下の「Output」ウィンドウに「Generation complete」と出たらMCCボタンをクリックして，MCCウィンドウを終了してください．
![MPLAB X IDE v5.45 - DataLogger _ default 2021_05_02 17_35_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/cc566c2f-a526-ff28-b929-bdaee09cbf6c.png)
・プロジェクトウィンドウのプロジェクトファイル名を右クリックして，「Property」をクリックしてください．
・「Categories」ウィンドウの「PICkit3」を選択します．「Option categories」は「Power」としてください．「Power target circuit from PIkit3」にチェックを入れ，「Voltage Level」を「3.25」としてください．
![MPLAB X IDE v5.45 - DataLogger _ default 2021_05_02 17_39_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/677f4fdd-8918-25c6-fdfd-837a3c229c19.png)
「Categories」ウィンドウの「XC8 Global Options」を選択します．「C standard」を「C90」にしたら，「OK」をクリックして「Property」ウィンドウを閉じます．
![MPLAB X IDE v5.45 - DataLogger _ default 2021_05_02 17_39_48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/eb6bb3e0-95cf-a9ca-6931-ebc79374a6ce.png)

・プロジェクトウィンドウのプロジェクトファイルの中の「Header Files」を右クリックしてNew>>xc8 header.h...をクリックます．
・「File Name」を「LCD」にして「Finish」をクリックします．成功すればプロジェクトファイルに「LCD.h」が追加されます．
・プロジェクトウィンドウのプロジェクトファイルの中の「Source Files」を右クリックしてNew>>xc8 ave-main.h...をクリックます．
・「File Name」を「LCD」にして「Finish」をクリックします．成功すればプロジェクトファイルに「LCD.c」が追加されます．
![MPLAB X IDE v5.45 - DataLogger _ default 2021_05_04 13_26_49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/bf399d7a-2d1f-4ae6-c9c0-01c8c3b6bacf.png)

本記事の最後に記載されているソースファイル「main.c」「LCD.c」「LCD.h」をプロジェクト内の「main.c」「LCD.c」「LCD.h」の内容と置き換えます．
![MPLAB X IDE v5.45 - DataLogger _ default 2021_05_04 13_24_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/a186f37c-708e-dbd2-8b48-b157004a30ed.png)

・メニューバーの下にある青色の金槌(カーソルを合わせると「Build Project DataLogger(F11)」と表示される)をクリック．
・画面下部の「Output」ウィンドウに以下のような表示がでればオッケーです．
![MPLAB X IDE v5.45 - DataLogger _ default 2021_05_04 11_23_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/50ae71b8-3711-d50b-e048-019069db09a5.png)

・青色の金槌の3つ右にある緑色の下向き矢印をクリックして，プログラムをPICに書き込みます．
・画面に「Programming/verify completes」と表示されて，PICkit3の「Active」というLEDが青色点灯すれば書き込み完了です．
![MPLAB X IDE v5.45 - DataLogger _ default 2021_05_04 13_35_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/f432cc1d-6d96-f030-fe3d-264dc55c3914.png)

ACアダプターを繋いで，「画面表示が消える」→「Hello World!と表示される」→「3+4=7と表示される」が1秒おきに繰り返されれば成功です．
なお，数字の4の下にカーソルが表示されればオッケーです．
![結果.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666904/38fc0e48-5b7f-83dd-a44b-025a87f218a3.jpeg)

#6．プログラムの加工方法
今回用意したLCDは半角文字を2行16列，一度に合計32文字表示できます．
LCDに任意の文字を表示したい場合，文字を表示する位置と表示する文字列をLCDに知らせる必要があります．

LCDの表示位置は以下のように規定されています．
例えば，1行目7列目はLCD内部では**47**という数字で表されます．

|行番号\列番号|0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|
|:-----------:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|0|0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|
|1|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|

また，今回使用するLCDにはASCIIコードという文字コード規格が採用されています．
例えば，ASCIIコードではアルファベットのXは0x58という数字が対応します．
つまり，「1行目7列目にアルファベットのXを表示して」という命令をLCDに伝えるとすると，「位置47にASCIIコードの0x58に相当する文字を表示して」と伝えることになります．
プログラムでは以下のようになります．

```c
LCD_Locate(1, 7);
LCD_Puts("X");
```

その他のプログラムとして，画面表示を消す関数LCD_Clearと処理を任意の時間(単位：ミリ秒)だけ停止させる__delay_ms(任意時間)があります．

```c
LCD_Clear();                //画面をリセット
__delay_ms(1000);           //1000ミリ秒(ms)待つ=1秒待つ   
```

なお，LCD_Puts関数は文字列しか扱えないので数値を扱いたいときは文字列に変換するsprintfを使います．

これら5つの命令を使えば自由に文字列を表示できます．

これを踏まえてmain.cの中身を見てみましょう．
なんとなく使い方・改造方法はわかるかと思います．
なお，そのほかの文(#inclde ～やint main(void)など)の意味は今は考えなくても大丈夫です．

#7．おわりに
最後までお付き合い頂き，ありがとうございました．

わかりにくい箇所などがあったら遠慮なく連絡をください．解説などを追記します．

それでは，また次回の記事でお会いしましょう．
次回は今回作成したプログラムの解説記事になります．

今後も農業農村工学(水文学，かんがい排水，土壌物理学，水理学)を中心に記事を執筆していきたいと思います．
リクエスト等も受け付けておりますので，ご遠慮なく連絡ください．
ツイッター：https://twitter.com/6LxAi9GCOmRigUI
メール：BattleShipMissouriWater@gmail.com

【気象・水文観測機器の自作】シリーズ一覧

>
【気象・水文観測機器の自作】　第1回　装置の概要
https://qiita.com/6LxAi9GCOmRigUI/items/bfdfc038e4360961d289
【気象・水文観測機器の自作】　第2回　完成品と部品の紹介
https://qiita.com/6LxAi9GCOmRigUI/items/8476ff1723f2f00dc45d
【気象・水文観測機器の自作】　第3回　三端子レギュレータとLCDの実装
https://qiita.com/6LxAi9GCOmRigUI/items/188b72d38bd81924c49c

検索用Key Words：
PIC，マイコン，C言語，プログラミング，データロガー，自作，低コスト，小型，農業農村工学，気象観測，水文観測，かんがい排水

#8．ソースコード
### main.c

```c
//ヘッダーファイルインクルード
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pic18.h>
#include "mcc_generated_files/mcc.h"
#include <xc.h>
#include "LCD.h"

#define _XTAL_FREQ 16000000     //クロック周波数を16MHzにする

//メイン関数
int main(void)
{
    // Initialize the device
    SYSTEM_Initialize();    //システムの初期化
    LCD_Initialize();       //LCDの初期化

    //デモンストレーション用変数
    int a=3;
    int b=4;
    int c=a+b;
    
    //無限ループ
    while(1){       
        LCD_Clear();                //画面をリセット
        __delay_ms(1000);           //1000ミリ秒(ms)待つ=1秒待つ
        LCD_Locate(0, 0);           //表示位置の先頭を0行目0列にする
        LCD_Puts("Hello World!");   //文字列「Hello World!」を表示
        __delay_ms(1000);           //1000ミリ秒(ms)待つ=1秒待つ   
        
        sprintf(BufLCD,"%d+%d=%d",a,b,c); //演算結果(数値データ)を文字列データに変換
        LCD_Locate(1, 2);           //表示位置の先頭を1行目2列にする
        LCD_Puts(BufLCD);           //文字列BufLCD(3+4=7)を表示する
        LCD_CURSOR_Set(1,4);        //カーソルを1行目4列目に合わせる
        __delay_ms(1000);           //1000ミリ秒(ms)待つ=1秒待つ   
    }
    return(0);
}
```


### LCD.h

```c
// 多重インクルード防止
#ifndef XC_HEADER_LCD_H
#define	XC_HEADER_LCD_H

#include <xc.h> // include processor files - each processor file is guarded.  

#ifdef	__cplusplus
extern "C" {
#endif /* __cplusplus */
#ifdef	__cplusplus
}
#endif /* __cplusplus */

/*******************************************************************************
 マクロ定義
 ******************************************************************************/
//通信制御用ピン
#define RS LATCbits.LATC5   //0：コマンドを送る，1：データを送る
#define RW LATCbits.LATC6   //0：書き込みモード，1：読み出しモード
#define E LATCbits.LATC7    //0：アイドル状態，1：通信中

//コマンド・データ送受信用ピン
//e.g. LCD=0b10101010のときRB3が1，RB2が0，RB1が1，，，，，，
#define DB4 LATBbits.LATB0
#define DB5 LATBbits.LATB1
#define DB6 LATBbits.LATB2
#define DB7 LATBbits.LATB3

/*******************************************************************************
 グローバル変数の定義
 ******************************************************************************/
char DataLCD;      //LCDに送信するデータ
extern char BufLCD[64];    //LCD表示用
extern char Cursor;        //LCDのカーソル位置

/*******************************************************************************
 関数のプロトタイプ宣言
 ******************************************************************************/
//LCDの初期化を行う(初期化手順は秋月電子通商のSC1602B付属のデータシートに従った)
void LCD_Initialize(void) ;
//カーソル位置をホーム位置に戻す
void LCD_CURCOR_Home(void); 
// LCD画面をクリアする
void LCD_Clear(void);		
//LCD上で文字を出力する先頭位置をLCDに送信する
void LCD_Locate(unsigned char row, unsigned char column);   
//カーソルを任意の場所に移動させる
void LCD_CURSOR_Set(char row,char column);
//ASCIIコードに従って文字定数を8bitの数値に変換し，4bitずつLCD_DATABUS_Write関数でLCDに送信する
void LCD_Putc(char c);
//文字列(複数の文字)を文字定数(1文字)に分割して，LCD_Putc関数でLCDに送信する
void LCD_Puts(const char* p) ;
//LCDに8bitのコマンドまたはデータを送信する
static void LCD_CMD_Write(unsigned char data) ;
//LCDに4bitのコマンドまたはデータを送信する
static void LCD_DATABUS_Write(unsigned char data) ;
//送信データに合わせてピンをHIGHまたはLOWに割り当てる
void LCD_PIN_Assign(unsigned char datasend);     
    
#endif	/* XC_HEADER_TEMPLATE_H */
```


### LCD.c

```c
//ヘッダファイルインクルード
#pragma jis
#include <stdio.h>
#include <xc.h>
#include <stdlib.h>
#include <pic18.h>
#include "mcc_generated_files/mcc.h"
#include "LCD.h"
#define _XTAL_FREQ 16000000 // __delay_ms()用クロック定義 (8MHz駆動)

char DataLCD;      //LCDに送信するデータ
char BufLCD[64];    //LCD表示用
char Cursor=0;      //LCDのカーソル位置

//カーソル位置をホーム位置に戻す
void LCD_CURCOR_Home(void){
    LCD_CMD_Write(0b00000010);
    __delay_ms(2);
}

//カーソルをrow行目columun列目に表示する
void LCD_CURSOR_Set(char row,char column){
    LCD_Locate(row, 0);
    for(int i=0;i<column;i++){
        LCD_CMD_Write(0b00010100);  //カーソルを右に1列だけシフト
        __delay_us(40);
    }
}
//LCDの初期化を行う(初期化手順は秋月電子通商のSC1602B付属のデータシートに従った)
//4bitのコマンド送信にはLCD_DATABUS_Write関数を，8bitのコマンドにはLCD_CMD_Write関数を使う
void LCD_Initialize(void){
	/**********LCD用GPIOポートの初期化**********/
	RS = 0;     //コマンド送信モード
	RW = 0;		//書き込みモード
	E = 0;      //アイドル状態
	DataLCD=0b00000000;         //送受信用ピンに割り当てるデータを用意
	LCD_PIN_Assign(DataLCD);    //送受信用ピンにDataLCDを割り当てる    
	__delay_ms(300);			//電圧が安定するまで待つ	

    /**********LCD初期化処理**********/
	LCD_DATABUS_Write(0b00000011);  //初期化コマンド1
	__delay_ms(20);			// 4.1mSec以上ウェイト

	LCD_DATABUS_Write(0b00000011);  //初期化コマンド2
	__delay_us(200);			// 100uSec以上ウェイト

	LCD_DATABUS_Write(0b00000011);  //初期化コマンド3
	__delay_ms(2);             // 40uSec以上ウェイト
    
	LCD_DATABUS_Write(0b00000010);  //4bit通信モードを選択
	__delay_ms(2);             // 40uSec以上ウェイト
	LCD_CMD_Write(0b00101000);	// ファンクションセット(2行表示、5*7dot)
	__delay_ms(2);
	LCD_CMD_Write(0b00001000);	// display on
	__delay_ms(2);
	LCD_CMD_Write(0b00000001);	// display off
	__delay_ms(2);
	LCD_CMD_Write(0b00000110);	// エントリモード(1:右にスクロール、0:シフトなし)
	__delay_ms(2);
    LCD_CMD_Write(0b00001100);	// エントリモード(1:右にスクロール、0:シフトなし)
	__delay_ms(2);
    
    /**********カーソルの設定**********/
	LCD_CMD_Write(0b00001110);	// ディスプレイ・カーソルの設定
	__delay_ms(2);
}

//LCD上で文字を出力する先頭位置をLCDに送信する
void LCD_Locate(char row,char column){
	char CharacterLocation;

	//↓↓↓↓↓↓↓↓↓↓↓↓↓ここはあとで確認する
	CharacterLocation = (unsigned char)(0b01000000 * row + column);	// 表示位置を決定(2行目に出すときは,3bit目を立てる)
	CharacterLocation |= 0b10000000;				// 最上位ビットを1にする(LCDのデータシートを参照)
	LCD_CMD_Write(CharacterLocation);				//文字を出力する位置をLCDに送信
}

//LCD画面をクリアする
void LCD_Clear(void){
	LCD_CMD_Write(0x01);	//LCD画面をクリア
	__delay_ms(3);		// 1.64mSec以上ウェイト
}


//ASCIIコードに従って文字定数を8bitの数値に変換し，4bitずつLCD_DATABUS_Write関数でLCDに送信する
void LCD_Putc(char c){
	// 文字コードはASCII
	// アスキーコードは8bitであるのに対し，今回はLCDに4bitでデータを送信するので上位4bitと下位4bitに分けて送信する
	RS = 1;			//データ送信モード(RS=1)にする
	__delay_us(1);	// 40nSec以上待つ

	LCD_DATABUS_Write((unsigned char)((c & 0xf0) >> 4));    //上位4bitを送信
	LCD_DATABUS_Write((unsigned char)(c & 0x0f));           //下位4bitを送信
}

//文字列(複数の文字)を文字定数(1文字)に分割して，LCD_Putc関数でLCDに送信する
void LCD_Puts(const char* p)
{
    //文字列の終端'\0'が出現するまでLCD_Putc関数を繰り返し呼ぶ
	while (*p) {
		LCD_Putc(*p);
		p++;
	}
}

//LCDに8bitのコマンドまたはデータを送信する
static void LCD_CMD_Write(unsigned char data){
	//コマンドまたはデータは8bitだが，LCDには4bitでデータを送信するので上位4bitと下位4bitに分けて送信する
	RS = 0;			//コマンド送信なのでRSは0
	__delay_us(1);	// 40nSec以上

	LCD_DATABUS_Write((unsigned char)((data & 0xf0) >> 4));     //上位4bitを送信
	LCD_DATABUS_Write((unsigned char)(data & 0x0f));            //下位4bitを送信
}

//LCDに4bitのコマンドまたはデータを送信する
static void LCD_DATABUS_Write(unsigned char data){
    //引数はunsigned char型(8bit)なので，下位4bitのみを有効とみなし，下位4bitをLCDに送信する
    
	// 書き込むコマンドまたはデータをDataLCDにセット
	DataLCD = (unsigned char)((DataLCD & 0x0f) | ((data << 4) & 0xf0));
    //送受信用ピンにDataLCDの内容を反映させる
    LCD_PIN_Assign(DataLCD);
    //安定待ち
    __delay_us(40);
    
    // まずEnableをactiveする
	E = 1;
    
    //LCDの受信待ち
	__delay_us(230);	// 80nSec以上

	// Enableをidleにする
	E = 0;
    
	__delay_us(1);	// 10nSec以上
   
	// データをALL0でクリア(PICの各ピンをLOW)しておく
	DataLCD = (unsigned char)(DataLCD & 0x0f); // 上位4bitをクリア(PICのポートCの上位4ピン(RC7?RC4)をLOW)
    LCD_PIN_Assign(DataLCD);

}

//送信データに合わせてピンをHIGHまたはLOWに割り当てる
void LCD_PIN_Assign(char datasend){
    //引数datasendの下位4bitを送受信用ピンに割り当てる
    DB7=(unsigned char)((datasend & 0b10000000) ? 1:0);
    DB6=(unsigned char)((datasend & 0b01000000) ? 1:0);
    DB5=(unsigned char)((datasend & 0b00100000) ? 1:0);
    DB4=(unsigned char)((datasend & 0b00010000) ? 1:0);
}
```