SSブログ

年の瀬

今日から年末年始の休暇に入りました、孫を連れて東宝シネマ
でガガ様を視てきました。


小学生 1,000円 60歳以上1,100円、通常大人1,800円ですから
お得です、が、孫には予想通り詰まらなかった様子で映画はガガ様
孫はガサゴソでした、ネタバレすると不味いですが一人の男との運命的な

出逢いが彼女をスターダムにのし上げたという内容です、鼻を
すする音が彼方此方から聞こえていました、ハンカチ必携かも
知れません、ま、兎も角も歌が素晴らしい事は間違いないです。

先ず靖国神社を参拝し品川の映画館へ向かう途中東京駅を
通過した時の構内の様子ですがいつもの土曜日よりは遙かに
人出が多く、例えばエスカレーターに乗るにも右側に立った

ままの人と歩きスマホが矢鱈に目立ちました、普段の都内の
通勤時と比較して可成り歩くのに危険です、出口が判らない
のかキョロキョロし乍らも歩きスマホは本当に困りものです

余所から来た人達が海外も含めてとても多い時期です、一方で
道路はガラガラ、然し乍ら此の時期は交通事故が多い
時期でペーパードライバーや他府県からの流入が多くカーナビ

だけで走っている為、殆どが三車線の中央を走行して居ます
これが結構奇っ怪な風景なんですよ左右はゼロなのに、一方
通行逆行も多く出会い頭の事故が増加します。

と、まあ例年の都内の様子に変わりは有りません、明後日は
大晦日、大掃除は済ませました、後は松飾り〆縄などですが
喪中のため無し、年賀葉書も11月に喪中葉書出してます、

そしてお節料理も喪中で無し、年越し蕎麦も無し、これは各家庭
や個人の主義思想で変わりますが一般的に無し、なのですが
実はそれって結構楽なもんですね、その分の手間も費用も
無し、まぁ哀しい事なんですけどね判って居てもやっぱり楽です。

2018/12/29(土)の東京駅


nice!(0)  コメント(0) 

AQM1602 LCD I2C PIC16F886 アセンブラ

秋月で買える廉価版LCDです
I2C接続小型キャラクタLCDモジュール(16x2行・3.3V/5V)¥550-
I2Cで色々動かして居るとどうしても読み込んだデータを表示
したく成ります、だからと言ってPIC の出力ポートにLED を接続して
モニタするにも自ずと限度があります、その時にはLCD表示が役立ちます

写真の様に基板無しでもそのまま動きます

DSCN0113

DSCN0114

ですが、コネクターの逆接続など間違うと私の経験では一瞬で壊れます
なので矢張り基板に実装してプロテクタなども実装して置けば
安心です
DSCN0111

DSCN0112

動画です
キャラクタを +1 づつインクリメントして行き表示しているだけです


I2C-BUS の様子です
S → 0x7C → A → 0x40 → A → data → A → P
これを data +1 し乍ら繰り返しているだけです

動いて仕舞えばただの、と言うか随分画面の狭いLCDです
何かの道具として使うには限定的で大したものでは無いです
然し乍ら、動くまでに丸二日無駄に過ごしました

ネット上の色々な製作記事を参考にし乍らプログラムした
のです、特に理解しにくかったのは初期化の仕方でした
普通ならばコントロール・レジスタ成る箱があって
それを指定してパラメータを書き込むものだという概念が

あるのですがこのLCDには全く別の概念が有って
Function Set  するしないを先ず宣言してから
複数のパラメータを連続して書き込みして結果的に設定する

というやりかたなんです、資料をダウンロードして
そのままパラメータを設定したのですが ウン とも
スン とも反応しません、普通 LCD ってのは電源が
入れば画面がすこーーーしぐらい暗く成るものなのですが

全く、全く反応しないのです、二日目には「これ絶対壊れてる」
と秋月に追加注文してしまいました。
資料の 初期化の例 とは下記の様な方法でした
bandicam 2018-12-27 18-57-38-730

特記すべきは Contrast set です、これが電源電圧 5V と 3.3V では
異なって居てどうやら画面が全く出て来ないそうです
それでは、という事でデータを変化させて確認して行ったのです

それでも全く画面が変化しません、全然無反応なのです
次ぎに疑ったのはI2Cのプルアップ抵抗です、Arduinoを使われる方の
記事を読むとプルアップ抵抗が1.8KΩとかで重すぎてLowレベルの
スレッショルドが確定しない、従ってI2C BUS BUFFER 成る回路

を経由してやっとこさ動くように成った、という記事です
それを読んで私はプルアップ抵抗を20KΩ~5.1KΩと試してみました
ですが全く無関係と言うか正に嘲うが如く全然反応無しでした

もう諦めてふてくされていたのです、その時、JA0QON HomePageさん
記事が目に留まり、あれ?、と思ったら 初期化の例 がちょっと
違うんです、この部分です
bandicam 2018-12-27 18-58-02-278

この順番が逆ではないですか!!
Clear Display  と Display ON/OFF control
こんなのが、正に コンナノガ ですよ逆で一体何が違うのか!!

と疑うのですが 逆 だった為に LCD は全く無反応だったのです
0x01  ->  0x0C  の順だとダメ 全く変化無し
0x0C -> 0x01 の順だとOK

メーカーと言うか秋月のホームページからダウンロードする資料が
どれだけ正しいのか本当に疑問です、秋月を責める積もりは
毛頭無いです、が、資料という責任の重さは決して無視出来ない

性質を帯びていて私共が作成するマニュアルにしても一字一句に
責任を帯びて居ます、下手すると事故に繋がるからです
まぁそういう事で逆順番にしたらアッサリと LCD がキャラクタを
出してきました。

序でに書いて置きます

この順番を逆にしてやっとこサ動いたのですが嫌らしいのは
それだけではありませんでした、一旦、LCDが動き出すと
順番逆を元に戻してもちゃんと LCD は動くのです、なんで?

これには時系列的な偶然性が潜んでいました、詰まりこういう事です
一旦動いた、プログラムを書き替えて順番逆を元に戻した
普通に考えて、また LCD は動かなく成る、そう考えるのが当然ですが
PICKIT3 でプログラムを書き替えているという理由から 5V はそのまま

投入し続けて居ます、その状態で再起動しても LCD 内の各レジスタには
データが残って居るからでしょう、ちゃんと動くのですと言うか動いて仕舞う
だから順番が逆だという証拠には無理が在る、さぁて困った、真実はなに?

判りました、LCD の電源が一旦 OFF すると内部レジスタは全て初期化
されますよね、その状態で順番逆のプログラムを書き込めばまたまた
LCD はウンともスンとも言わなくなるのです、この嫌らしさ・・・
従って順番はマニュアルのヤリかたではダメ、逆だという結論を
導きました。

*****************************************************************

次ぎの写真は LCD イニシャライズの波形です、連続した長い波形
と成りますがマニュアルに依れば Follower control の後は最低でも
200ms 置いて呉れとの事です、話しが前後しますがこのLCD には

読み出し機能が皆無なんです、従って 行きっぱなし な訳です
その為に 終了したであろう と思われるインターバルを置か
なければならないのです、もっと言えばそれぞれの設定項目の間にも

最低26.3us のインターバル を入れなければなりません
波形のデータは下記の通りです

0x7C ← スレーブアドレス
0x80 ← 0x80 の意味、次の1byteの後も続くからね、って意味 Co=1、以下同様
0x38 ← 設定パラメータ、以下同様
 26.3us ← 待ち時間、以下同様
0x80
0x39
 26.3us
0x80
0x14
 26.3us
0x80
0x78
 26.3us
0x80
0x53
 26.3us
0x80
0x6A
 200ms ←ここだけ矢鱈に長い
0x80
0x38
 26.3us
0x80
0x0C
 26.3us
0x00 ← 0x00 の意味、次の1byteの後はもう無いからね最後だよ、って意味 Co=0
0x01
 26.3us

I2Cプロトコルは下記の様に成って居ます、複数バイトの送信が可能です、鍵を握る
のは Co です Co=1 で送信すれば「あ、次の1バイト以降も続くのね」と LCD は理解
する、ってことです
bandicam 2018-12-28 10-43-04-968

**********************************************************

0x7C  0x80

DSCN0115

0x38  0x80

DSCN0116

0x39  0x80

DSCN0117

0x14  0x80

DSCN0118

0x78  0x80

DSCN0119

0x53  0x80

DSCN0120

0x6A   200ms

DSCN0121

0x80  0x38

DSCN0122

0x80  0x0C

DSCN0123

0x00  0x01

DSCN0124


このイニシャライズですがネットを読んでいると違う方法も在ります
それは下記の様に 3byte づつの書き込みです 参考、ツール・ラボさん

0x7C
0x00
0x38

0x7C
0x00
0x39

といった具合にブロック毎に送信するやりかたです

0x7C   ←スレーブアドレス
0x00   ←連続しないで送信するよ、という意味で連続して送信では 0x80です
0x38   ←設定パラメータ

これをイニシャライズに必要なブロックを複数送信するのですが
私は連続する方法を採用しました

ここまでのソースファイルはこちらからダウンロードして下さい、プログラム
は素人製作ですので動かないや間違い勘違い無理無駄が多く潜んでいます
発生する一切の責任を放棄します。

to be continued





続きを読む


nice!(0)  コメント(0) 

2018年の御礼

今年も一年間、ブログをご高覧下さり誠に有り難う御座いました

当たり前ですが一週間後は既に 2019/01/02 三が日の中日なのですね
ダウンカウントに入ってきました、クリスマスが終わりいつもの様に
全国の売り場で喧しく正月商戦が繰り広げられています

年の瀬は何か追い立てられるような気持ちに成るのです、何でも年内に
と云う気持ちからでしょうか、大掃除もしなければ・・・いやだぁ・・・
今年を振り返ってみますと色々と在りすぎた年でした、自宅、事務所の
引越から始まり義母実母の葬儀、姪御甥御の婚儀、避けては通れない様々な

営みは人が生まれて滅するまでの何所にでも在る出来事と判って居ても
特に永久のお別れはイザ自分の番に成ると・・・然し乍ら順番であれば
別な意味で幸福なことです、そもそも、そんな事をボヤいて居ては度重なる

自然災害にも関わらず全てを失い悲壮絶望のどん底で全てを受け入れて
忍耐と共に希望を抱いて生き抜いておられる多くの方々に対してとても
恥ずかしい、という気持ちに成ってきます

皆様はどの様にお過ごしか知るよしもありませんが、兎に角風邪など
召されませんようにお過ごし下さい、インフルエンザがまた流行って
来て居ますのでこっちが問題ですね、でも最近は「タミフル」「イナビル」
「リレンザ」から更に進化した「ゾフルーザ」と云う飲み薬で回復する
と聞いています、でも罹りたくないです

引き続き、ブログ、宜しくお願い申し上げます。

Dscn0076


nice!(0)  コメント(0) 

2018年の御礼

今年も一年間、ブログをご高覧下さり誠に有り難う御座いました

当たり前ですが一週間後は既に 2019/01/02 三が日の中日なのですね
ダウンカウントに入ってきました、クリスマスが終わりいつもの様に
全国の売り場で喧しく正月商戦が繰り広げられています

年の瀬は何か追い立てられるような気持ちに成るのです、何でも年内に
と云う気持ちからでしょうか、大掃除もしなければ・・・いやだぁ・・・
今年を振り返ってみますと色々と在りすぎた年でした、自宅、事務所の
引越から始まり義母実母の葬儀、姪御甥御の婚儀、避けては通れない様々な

営みは人が生まれて滅するまでの何所にでも在る出来事と判って居ても
特に永久のお別れはイザ自分の番に成ると・・・然し乍ら順番であれば
別な意味で幸福なことです、そもそも、そんな事をボヤいて居ては度重なる

自然災害にも関わらず全てを失い悲壮絶望のどん底で全てを受け入れて
忍耐と共に希望を抱いて生き抜いておられる多くの方々に対してとても
恥ずかしい、という気持ちに成ってきます

皆様はどの様にお過ごしか知るよしもありませんが、兎に角風邪など
召されませんようにお過ごし下さい、インフルエンザがまた流行って
来て居ますのでこっちが問題ですね、でも最近は「タミフル」「イナビル」
「リレンザ」から更に進化した「ゾフルーザ」と云う飲み薬で回復する
と聞いています、でも罹りたくないです

引き続き、ブログ、宜しくお願い申し上げます。

Dscn0076


nice!(0)  コメント(0) 

PIC16F886--I2C-- S-5851A アセンブラ

SII社 S-5851A 温度センサーです
I2C で制御し温度センサーを読み出します
-40℃ ~ +125℃ の範囲の仕様です

DSCN0098

緑色の小さな基板がセンサーです秋月電子でたったの110円

DSCN0096

DSCN0097


先ずは動画です
センサーを指で触れてデータが変化している様子が確認出来ます
但しこれでは使い物に成りません、バイナリを10進変換し表示
しなければ全く意味を持ちません、単なる実験です




I2C-BUS 波形です
マニュアルが日本語なのでとても助かりました



回路図、センサー基板
本当にシンプル、殆ど外付け部品は有りません
ですが特筆すべきはスレーブアドレス設定端子のAD0 / AD1 です
これは Low / Hi  設定だけでは無くて Open  でも状態認識します
詰まり一つの端子で Low / Open / Hi の状態が在るので
スレーブアドレスはその分多く合計8個を同じBUS上に並べられるのです
bandicam 2018-12-25 20-43-36-864


回路図、PIC16F886ホスト(マスター)側の基板です
bandicam 2018-12-25 20-43-13-986

I2C BUS 波形の拡大です、波形の詳細説明は写真に写っています
信号の方向はマスターから見て RX=受信 TX=送信 です、特に
ACKは双方向なので要注意です
S=スタート・コンフィギュレーション、送信
P=ストップ・コンフィギュレーション、送信
SR=リスタート、送信
DATA=測温データ、受信
A=ACK、送信又は受信
NA=NACK、送信

最初はコンフィギュレーションレジスタのイニシャライズ
写真の波形の詳細説明、間違ってます、正しくは
 S →  0x90 →  A →  0x01 →  A →  0x00 →  A →  P   全送信(TX)
DSCN0101

DSCN0102

次は測温データレジスタの読み出し

DSCN0103

DSCN0104

DSCN0105

お仕舞いは カレントリード です
これは連続して読み出す場合 0x91  を書くだけでデータが読み出せます
簡易的にして効率化を図っているのですね

DSCN0106

DSCN0107

波形を観測していて気が付いた点があります、それは測温データの
読み出し一回目は必ず 0x00 0x00 が返って来るという事です
言い換えれば測温データは前回のデータを記憶していてデータが

読み出されるとリフレッシュされる、と言い換えられます、詰まり
電源オンで一回目の読み出しはゼロクリアされた測温データが残って居て
それを読み出して初めて新鮮な測温データが書かれるという事です

温度レジスタ構成です、マイナス側に注目ですね
bandicam 2018-12-25 23-45-16-115

ソースコード等のファイルですがこのブログにアップロードすると
矢鱈に画面が縦長に成ってしまうのでダウンロード出来るように
アップロードしました、こちらからダウンロードして下さい。

素人プログラムなので笑われるのは覚悟です、が、これに依るトラブル
等は一切関知致しません、遊びの範囲でご利用下さい。



nice!(0)  コメント(0) 

PIC16F886--I2C-- S-5851A アセンブラ

SII社 S-5851A 温度センサーです
I2C で制御し温度センサーを読み出します
-40℃ ~ +125℃ の範囲の仕様です

DSCN0098

緑色の小さな基板がセンサーです秋月電子でたったの110円

DSCN0096

DSCN0097


先ずは動画です
センサーを指で触れてデータが変化している様子が確認出来ます
但しこれでは使い物に成りません、バイナリを10進変換し表示
しなければ全く意味を持ちません、単なる実験です




I2C-BUS 波形です
マニュアルが日本語なのでとても助かりました



回路図、センサー基板
本当にシンプル、殆ど外付け部品は有りません
ですが特筆すべきはスレーブアドレス設定端子のAD0 / AD1 です
これは Low / Hi  設定だけでは無くて Open  でも状態認識します
詰まり一つの端子で Low / Open / Hi の状態が在るので
スレーブアドレスはその分多く合計8個を同じBUS上に並べられるのです
bandicam 2018-12-25 20-43-36-864


回路図、PIC16F886ホスト(マスター)側の基板です
bandicam 2018-12-25 20-43-13-986

I2C BUS 波形の拡大です、波形の詳細説明は写真に写っています
信号の方向はマスターから見て RX=受信 TX=送信 です、特に
ACKは双方向なので要注意です
S=スタート・コンフィギュレーション、送信
P=ストップ・コンフィギュレーション、送信
SR=リスタート、送信
DATA=測温データ、受信
A=ACK、送信又は受信
NA=NACK、送信

最初はコンフィギュレーションレジスタのイニシャライズ
写真の波形の詳細説明、間違ってます、正しくは
 S →  0x90 →  A →  0x01 →  A →  0x00 →  A →  P   全送信(TX)
DSCN0101

DSCN0102

次は測温データレジスタの読み出し

DSCN0103

DSCN0104

DSCN0105

お仕舞いは カレントリード です
これは連続して読み出す場合 0x91  を書くだけでデータが読み出せます
簡易的にして効率化を図っているのですね

DSCN0106

DSCN0107

波形を観測していて気が付いた点があります、それは測温データの
読み出し一回目は必ず 0x00 0x00 が返って来るという事です
言い換えれば測温データは前回のデータを記憶していてデータが

読み出されるとリフレッシュされる、と言い換えられます、詰まり
電源オンで一回目の読み出しはゼロクリアされた測温データが残って居て
それを読み出して初めて新鮮な測温データが書かれるという事です

温度レジスタ構成です、マイナス側に注目ですね
bandicam 2018-12-25 23-45-16-115

ソースコード等のファイルですがこのブログにアップロードすると
矢鱈に画面が縦長に成ってしまうのでダウンロード出来るように
アップロードしました、こちらからダウンロードして下さい。

素人プログラムなので笑われるのは覚悟です、が、これに依るトラブル
等は一切関知致しません、遊びの範囲でご利用下さい。



nice!(0)  コメント(0) 

PIC16F886--I2C--MCP23017 アセンブラ

MCP23017 はMicroChip社のIO-Expanderです
8+8bitのI/Oを持ちI2Cで制御します
アドレスを変えることで合計8個並列に並べる事が出来ます
1個辺り16bitですから128の入出力が出来ます
然かも秋月電子では1個 ¥110で
8bitのIO-Expander PCF8574、1個 ¥130より安いです
再露出DSCN0067

GPIO(GPA/GPB)はそれぞれ1bit単位でin/outの設定が可能です
out  に設定した場合、Hi / Low 両方共 25mA の電流値が担保されています
但し負荷を接続する場合は注意しなければなりません、下記

VSS を基準としたその他全てのピンの電圧(VDD は除く) ..........................
.........................-0.6 ~ (VDD + 0.6) V

とデータシートに書かれていますので例えばDC24Vリレー等を直接
ドライブすることは出来ません、平たく言うと VSS~VDD間で使え
という事ですね、通常のC-MOS-TTLと同等と考えれば良さそうです

各in/outの内部には100KΩのプルアップ抵抗が用意されていて
GPPUレジスタを"1"にセットするとプルアップ有効と成ります
但し入力として設定した時に限りプルアップは使えます

デフォルト(電源ON後)では無効にセットされます
その他にもビット反転機能も備えていて入力に設定した場合
IPOLレジスタを"1"にすると反転します

20171214211056


今回も泥臭い乍らアセンブラで作りました
回路はシンプルです少しの外付けで完成します
DSCN0061

緑色のLEDは出力、INTA / INTB です、ここでは使用していませんが
とても柔軟に設定出来る様に成っていて読んでいるととても奥が深く
様々な要求から生まれたのだろうと感じ取れます


DSCN0062

DSCN0063

ホスト側はPIC16F886です
DSCN0065

DSCN0066

先ずは動画です
MCP23017 の GPIO-GPAを出力に設定
出力に対して0x00→0x01→0x02・・・0xFF→0x00→・・・
を繰り返しているだけのLチカです
また GPIO-GPBを入力として読み込んだデータを
ホスト側PIC16F886のPORTBに出力しLEDでモニタします
仕事としては無意味ですが、まぁやらないより益しという事で・・・


回路図、MCP23017基板
bandicam 2018-12-21 17-04-55-793

回路図、PIC16F886基板
bandicam 2018-12-21 17-04-36-422

データの詳細です、もっと詳しくはデータブックをダウンロード
してご確認下さい
スレーブアドレス、0x40(A0=A1=A3=0V)
GPA制御アドレス、0x00(IODIRA)
GPB制御アドレス、0x01(IODIRB)
GPA出力アドレス、0x12(GPIOA) 又は 0x14(OLATA) どっちでも出ます
GPB入力アドレス、0x13(GPIOB)

先ずはGPA制御アドレス、0x00(IODIRA)を出力に設定します
スタート→スレーブアドレス0x40→ACK→制御レジスタ0x00(IODIRA)→
ACK→0x00(全出力)→ACK→ストップ
DSCN0051

DSCN0052

次ぎはGPB制御アドレス、0x01(IODIRB)を全入力に設定します
これは実はやらなくても良いのです、理由は電源投入後、自動的に入力
設定に成るからです、デフォルトは全入力だという事です、が、敢えて
実験のためにイニシャライズしてます

スタート→スレーブアドレス0x40→ACK→制御レジスタ0x01(IODIRB)→
ACK→0xFF(全入力)→ACK→ストップ
DSCN0053

DSCN0054

次ぎは実際にGPAにデータ出力します
GPA出力アドレス、0x12(GPIOA) 又は 0x14(OLATA) どっちでも出ます
スタート→スレーブアドレス0x40→ACK→GPAレジスタ0x14(OLATA)→ACK→
連続データ0x00~0xFF(繰り返し)→ACK→ストップ→LOOP
DSCN0055

DSCN0056

次ぎはGPBからのデータ入力を読み出します
GPB入力アドレス、0x13(GPIOB)
スタート→スレーブアドレス0x40→ACK→GPBレジスタ0x13(GPIOB)→ACK→
リスタート→スレーブアドレス0x41(READ)→ACK→読み出しデータ→NACK→ストップ→LOOP

DSCN0057


DSCN0058

動画です
I2CのSCL / SDA の波形です、次のような流れです
GPAに出力 → GPBを読み込む → PIC16F886-PORTBのLEDでモニタ
これを繰り返しています
0x40→0x14→出力DATA   続いて 0x40→0x13→0x41→入力DATA




ACKですがデータシートでは抽象的に「このタイミングですよ」
みたいに波形が書かれているだけですよね、それは真実だし
そうでなければならないのは判るんですが実験していると

ちゃんとACK返ってきているのか、特に色々なデバイスが
I2C-BUSラインにぶら下がって居ると何か決定的な手掛かりが
欲しくなるのです、そういう時は矢張りオシロスコープが

一番です、詰まりデジタル的なロジックは判っていても
実際のアナログ的な部分を確認するためには必須ですよね
実際の波形を視てみましょう
DSCN0068

この電圧軸だとACKらしき足跡が見えませんが、電圧軸を拡大すると
視えて来ます、そうそう、これがACKの足跡なのです
特に双方向 BUS BUFFER 等の回路を設計する際にはこの足跡が
大変重要性を帯びてきます
DSCN0069





続きを読む


nice!(0)  コメント(0) 

PIC16F886 24LC64 EEPROM I2C アセンブラ

再露出DSCN0050


PCF8574  IO EXPANDER の序でにEEPROMもドキュメントを
残そうと取り組んでみました、皆様のようにサクッ!!っとC言語とかで
制御出来なくて地道にPICマイコンのアセンブラで組んでみましたが
思いの外難しくて時間が掛かりました。
(ソースプログラムはこちらからダウンロード)
特記すべきはネット記事では見つからなかったものの良く探せば同様
のトラブルが在った事を解決後に知りましたが下記の様な事です・・・

EEPROMの書き込み時間は最低 5ms を必要とする

・・・という事実、これを知らなかったばかりに書き込み後直ちに
読み出しすると最初のスレーブアドレスを送信してフリーズして
仕舞うのです、この問題を解決するためにオシロスコープとにらめっこ
して何日無駄にしたか・・・・はぁ、って感じです、たまたま
デバッグする為にタイマーを入れたらすんなり動いたので

「なんで?」

もしやインターバルが必要なのかとネット検索したら同様のトラブル
の記事がみつかりまして「ああ、やっぱりそうか」と、更には
EEPROMのデータシートを視れば書き込みに5msと書いて有る
ではないですか、そんな訳で無駄な悪戦苦闘を強いられました。
データシートの当該部分です赤枠内
bandicam 2018-12-28 07-23-30-631


取り敢えずこの動画はEEPROM のメモリー番地 0x000~0x0FF
の255のアドレスに00/01/02/03・・・・FD/FE/FF/00と一個ずつ加算
して書いて同時に読み出してLチカさせています。

実際のI2C波形です、一つずつインクリメントしている様子が判ります


ちゃんと書けているか確認しました、以前から所持していた秋月電子
PIC PROGRAMMER を使いました、この基板はPICだけで無く
アプリケーション・ソフトをダウンロードすればEEPROMの
読み書き込みも可能なのです
DSCN0047

但し、これを使うに当たっては色々と問題が在りました
先ず、今時のパソコンにはCOM1(9pin-D-sub / serial)が無い
で、あるにも関わらず我がDELL T3500には付いていた、だから今まで
PIC PROGRAMMERは問題無く動いていた、なのに秋月電子の

アプリケーション・ソフト、Serial EEPROM Programmer Ver6.5.8
は何故だか「エラー'13'型式が合いません」なるシステムエラーが出て
使えないのです、ならばという事で古いノートパソコンを引っ張り出して
それにインストールされている windows xp professional  の元で

動かしたものの同様のエラーで動作しません、もうなにをやってもダメ
そこで思いついたのは USB/Serial変換器 REX -USB60F
これです ↓
DSCN0049

これを使うことでSerial EEPROM Programmer Ver6.5.8は動くのです
折角COM1 / serial ポートが在るのにそれはダメでわざわざ
USB/Serial変換器を使うと動くという矛盾、その嫌らしさ・・・・
然かも COM14  とか、もう信じられない
という訳でちゃんと書けていることが確認出来ました
bandicam 2018-12-19 19-56-45-791



オシロスコープで波形観測するには肝心な部分だけを視たいのに
他の波形が重複して見辛いことこの上ないですよね、その問題は
簡単に解決出来ました、PICの空きポートを利用してそこにトリガー
パルスを出してディレーで眺めれば楽勝です

製作した EEPROM 基板です、LEDは短絡しています
DSCN9946

単純にEEPROMだけですが、保護ダイオード、パスコン、チェック端子
とシンプルな基板です

DSCN9947

全体回路図
bandicam 2018-12-18 20-22-22-539

これでは何も見えませんね、PIC部分
bandicam 2018-12-18 20-22-45-987

EEPROM部分
bandicam 2018-12-18 20-23-08-323

I2Cのプロトコルは下記の通り、データシートの抜粋です
bandicam 2018-12-28 07-20-50-075

bandicam 2018-12-28 07-21-05-061

bandicam 2018-12-28 07-21-25-172

bandicam 2018-12-28 07-21-41-500



デバッグしていて何が一番知りたかったか、それは実際の波形です
SCL / SDA の相互位相関係で全てが決まります、それぞれの立ち上がり
立ち下がり、その時の状況で様々な意味を持たせているので抽象的な
データシートの波形では満足できませんでした、特にACKは僅かな凹みが
足跡の様に残るのです、オシロスコープに顔を近づけないと判別出来ない
のですが、ACKが出ている、出ていない、の大きな手掛かりと成ります
写真は下記の条件での波形です

・EEPROM 24LC64 秋月で50円、マイクロチップ社製 255byte x 32頁
・SLAVE ADDRESS  0xA0(WRITE) / 0xA1(READ)
・MEMORY  ADDRESS 0x00
・WRITE & READ  DATA 0x55

WRITE→READ間インターバルはおよそ 6ms
データシートでは「書き込み時間」と称していますが「書いてから読み出す
までに最低5msは待って呉れ」とは書かれていないのです、データシートの
嫌らしさ、不親切さは自社の欠点や不利益な部分を別の真実という形で表現
し結果的に危険性が伝わらない、と云う形で書かれていると私は永年感じて
居ます
DSCN9976

I2C クロック周波数はほぼ100KHz

DSCN9977

オシロスコープ画面、左側が読み出し、右が書き込み
これを延々と繰り返すだけです

DSCN9978

読み出し START→ 0xA0→  ACK→  0x00→  ACK

DSCN9979

読み出し 0x00→  ACK→  RESTART→ 0xA1

DSCN9980

読み出し 上の写真の 0xA1 は重複、続いて ACK→  0x55→  NACK→  STOP

DSCN9981

書き込み START→  0xA0→  ACK→  0x00→  ACK
DSCN9982
書き込み 0x00→  ACK→  0x55→  ACK→  STOP

DSCN9983
こうした具体的な波形で無いと私には無理。

プログラムです、下記のファイルと成ります
・p16f886.inc
・p16f886_24C64_006.asm   メイン
・p16f886_24C64_read.asm   サブルーチン、読み出し
・p16f886_24C64_sub_i2c.asm サブルーチン
・p16f886_24C64_write.asm   サブルーチン、書き込み
・subroutin.asm         サブルーチン

プログラムの流れは・・・

・データ 0x55 を書く
・読み込む
・LEDを点灯させる(PORTB)

・・・と単純で無意味な動作です、然し乍ら方法を知る為には
やらないよりはまし
 ---------------------------------------------------------------------------------
・p16f886.inc はMICRO CHIP 社で配布しているものです
 それに追加した部分だけを示します


CBLOCK   H'20'	;20hからユーザーのメモリが連続して割り当てられる開始宣言
W_TEMP		;For Interupt
S_TEMP		;For Interupt
COUNT		;For サブルーチン変数
COUNT2		;For サブルーチン変数
COUNT3		;For サブルーチン変数
COUNT4		;For サブルーチン変数
COUNT10		;For サブルーチン変数
COUNT11		;For サブルーチン変数
COUNT12		;For サブルーチン変数
COUNT13		;For サブルーチン変数
TMR0_INT_C	;TMR0割込回数カウンタ(65.28msでインクリメント但し水晶=4MHz)
TMR0_INT_D	;上記カウンタが255を超えたら+1するカウンタ
		; MAX = 4244.8秒 ( 65.28ms x 255 x 255 ) およそ70分
FLAG		;FLAG RESISTER
		;0=
		;1=
		;2=
		;3=
		;4=
		;5=
		;6=
		;7=
SWFLAG		;SW FLAG ONLY RESISTER
		;0=SWの状態ビット0
		;1=SWの状態ビット1
		;2=SW ON ビット、MAINプログラムではこれが立った事でSW ONを知る
		;3=
		;4=
		;5=
		;6=
		;7=
SWFLAG2		;SW FLAG ONLY RESISTER
		;0=SWの状態ビット0
		;1=SWの状態ビット1
		;2=SW ON ビット、MAINプログラムではこれが立った事でSW ONを知る
		;3=
		;4=
		;5=
		;6=
		;7=
COUNTB		;For Interrupt 避難用
COUNT2B		;For Interrupt 避難用
COUNT3B		;For Interrupt 避難用
COUNT4B		;For Interrupt 避難用
TEMP1		;For A/D value MSB
TEMP2		;For A/D value LSB
TEMP3		;For Adjustable timer routin
PTA		;For I/O register
PTB		;For I/O register
PTC		;For I/O register
PTE		;For I/O register

WRITEADRS	;スレーブアドレス・ライト
WRITEHADRS	;メモリ上位アドレス・ライト
WRITELADRS	;メモリ下位アドレス・ライト
EPROMWDATA	;書き込むデータ
		
READADRS	;スレーブアドレス・リード
READHADRS	;メモリ上位アドレス・リード
READLADRS	;メモリ下位アドレス・リード 

・p16f886_24C64_006.asm   メイン


;***************************************************************************************************************
;This software is provided in an “AS IS” condition,NO WARRANTIES in any form apply to this software.
; picmicrolab.com 5.31.2014  
; Modified Dec,10,2018 by maru
;***************************************************************************************************************
; PCF8574 I2C  8-bit IO expander interface with PIC16F876A;
;-------------------------------------------------------------------------------------;
	LIST		P=PIC16F886
	include		P16f886.inc
	errorlevel  	-302		; 翻訳時に302エラーが出ないようにします
	errorlevel  	-205		; 翻訳時に205エラーが出ないようにします
	errorlevel  	-305		; 翻訳時に305エラーが出ないようにします
;サブルーチンは別ファイルをコール
;	EXTERN	TIMADJ,TIM8ms,TIM100ms,TIM500ms,TIM10ms,ADGET,OUT_A,OUT_B,OUT_C,SWON,SWON2
EXTERN	E24LC64_READ,I2C_INIT,START_I2C,STOP_I2C,E24LC64_WRITE,IDLE
EXTERN	TIM100ms,TIM8ms,TIM10ms
			;別ファイルに存在するサブルーチンのラベル名を宣言する
			;別ファイルでは必ず GLOBAL で受ける、つまり EXTERN と GLOBAL はペア。
; __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF & _HS_OSC & _LVP_OFF & _DEBUG_OFF & _CPD_OFF
__CONFIG  _CONFIG1 , _CP_OFF & _DEBUG_OFF  & _CPD_OFF & _LVP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTOSCIO & _BOR_OFF
	    org		0x00
reset:	
	    goto start
	    org		0x04
start:
;===============================================================================
;スレーブアドレスとデータの宣言
	;--------------
	WSADRS		EQU	    H'00A0'	;スレーブアドレス WRITE
	WSHADRS		EQU	    H'0000'	;メモリアドレス上位 WRITE
	WSLADRS		EQU	    H'0000'	;メモリアドレス下位 WRITE
	ROMWDATA	EQU	    H'0055'	;E24LC64 に書き込むデータ
	;--------------	
	RSADRS		EQU	    H'00A1'	;スレーブアドレス READ
	RSHADRS		EQU	    H'0000'	;メモリアドレス上位 READ
	RSLADRS		EQU	    H'0000'	;メモリアドレス下位 READ
	;--------------	
	MOVLW   	WSADRS			;data -> W
	MOVWF		WRITEADRS		;W -> F
	MOVLW   	WSHADRS			;data -> W
	MOVWF		WRITEHADRS		;W -> F
	MOVLW   	WSLADRS			;data -> W
	MOVWF		WRITELADRS		;W -> F
	;--------------
	MOVLW		ROMWDATA		;data -> W
	MOVWF		EPROMWDATA		;W -> F
	;--------------
	MOVLW   	RSADRS			;data -> W
	MOVWF		READADRS		;W -> F
	MOVLW		RSHADRS			;data -> W
	MOVWF		READHADRS		;W -> F
	MOVLW		RSLADRS			;data -> W
	MOVWF		READLADRS		;W -> F
	;--------------
;	READADRS	;スレーブアドレス・リード・レジスタ
;	WRITEADRS	;スレーブアドレス・ライト・レジスタ
;===============================================================================
;For PORTA  RA0=OUT using trigger pulse for oscilloscope
	BANKSEL		TRISA
	MOVLW		b'00000000'
	MOVWF		TRISA
	banksel		PORTA
	CLRF		PORTA
;===============================================================================
;For MCLR INIT 1pin MCLR to use reset sw 1pin (PORTE-RE3)
	BANKSEL		PORTE
	CLRF		PORTE
	BANKSEL		ANSEL
	CLRF		ANSEL
	BANKSEL		TRISE
	MOVLW		b'00001000'
	MOVWF		TRISE
;===============================================================================
;***	iNTERNAL OSC 設定 ( OSCCON-8Fh )
;OSCINIT
	BANKSEL		OSCCON
	MOVLW   	70h        	;CLOCK=4MHz (70H=8MHzでMAX)
        MOVWF   	OSCCON
       	BCF		STATUS,5	;Back to BANK0
;===============================================================================
;I2C の為の初期化
LOOP:
	CALL		I2C_INIT
;===============================================================================
;LOOP:
;===============================================================================
;E24LC64WRITE
	CALL		IDLE
	CALL		START_I2C
	CALL		E24LC64_WRITE
	CALL		STOP_I2C
;===============================================================================
;For EEPROM WRITE WAITING TIME(Musd be 5ms minimum) if no wait gonna be freeze
	CALL		TIM10ms	
;===============================================================================
;E24LC64READ
	BANKSEL		PORTA	    ;For oscilloscope trigger 
	CLRF		PORTA	    ;↑
	BSF		PORTA,0	    ;↑
	
	CALL		IDLE
	CALL		START_I2C
	CALL		E24LC64_READ
	CALL		STOP_I2C
	
	banksel		PORTA	    ;For oscilloscope trigger
	BCF		PORTA,0	    ;↑
;===============================================================================	
	BANKSEL		W_TEMP
	MOVF		W_TEMP,W	;W_TEMP -> W
	MOVWF		PORTB		;W → PORTB に即出力(LEDモニタとして使用)
;===============================================================================
	GOTO		LOOP

end


・p16f886_24C64_read.asm   サブルーチン、読み出し

	list      	p=16F886	; 翻訳時にリストファイルを作ります
	#include 		; 定義ファイルを読み込みます
	errorlevel  	-302		; 翻訳時に302エラーが出ないようにします
	errorlevel  	-205		; 翻訳時に205エラーが出ないようにします
	errorlevel  	-305		; 翻訳時に305エラーが出ないようにします
	;***********************************************************************
;サブルーチン、E24LC64を読む
	GLOBAL	E24LC64_READ
	;サブルーチンのラベル名がメインプログラムでEXTERNで宣言されて居る
	;その為、必ずGLOBALで受ける、つまり EXTERN と GLOBAL はペア
;===============================================================================
CODE	;サブルーチン、ここから
;===============================================================================
;	WRITEADRS	;スレーブアドレス・リードの為のライト
E24LC64_READ
	BANKSEL		WRITEADRS
	MOVF		WRITEADRS,W	;F -> W  スレーブアドレス一発目はライトモード
	MOVWF		SSPBUF		;W -> F  INITIATE SEND この瞬間に送信される
;SLAVE ADDRESS
SENDC3:
	BANKSEL		PIR1
	BTFSS		PIR1, SSPIF	;SEND COMPLETED? YES,SKIP NEXT 送信完了?
	GOTO		SENDC3
	BCF		PIR1, SSPIF	;YES,CLEAR FLAG 割り込みフラグ・クリア
	BANKSEL		SSPCON2
	BTFSC		SSPCON2,ACKSTAT	;ACK RECEIVED FROM SLAVE?IF YES SKIP
					; スレーブからの ACK待ち 0=受信済み次ぎをスキップ
	GOTO		$-1		;IF NO,END 
	
;===============================================================================
;	メモリアドレス上位送信
	BANKSEL		READHADRS
	MOVF		READHADRS,W	;F -> W  
	MOVWF		SSPBUF		;W -> F  INITIATE SEND この瞬間に送信される
;SLAVE ADDRESS
SENDC3B:
	BANKSEL		PIR1
	BTFSS		PIR1, SSPIF	;SEND COMPLETED? YES,SKIP NEXT 送信完了?
	GOTO		SENDC3B
	BCF		PIR1, SSPIF	;YES,CLEAR FLAG 割り込みフラグ・クリア
	BANKSEL		SSPCON2
	BTFSC		SSPCON2,ACKSTAT	;ACK RECEIVED FROM SLAVE?IF YES SKIP
					; スレーブからの ACK待ち 0=受信済み次ぎをスキップ
	GOTO		$-1		;IF NO,END 
;	RETURN
;===============================================================================
;	メモリアドレス下位送信
	BANKSEL		READLADRS
	MOVF		READLADRS,W	;F -> W  
	MOVWF		SSPBUF		;W -> F  INITIATE SEND この瞬間に送信される
SENDC3C:
	BANKSEL		PIR1
	BTFSS		PIR1, SSPIF	;SEND COMPLETED? YES,SKIP NEXT 送信完了?
	GOTO		SENDC3C
	BCF		PIR1, SSPIF	;YES,CLEAR FLAG 割り込みフラグ・クリア
	BANKSEL		SSPCON2
	BTFSC		SSPCON2,ACKSTAT	;ACK RECEIVED FROM SLAVE?IF YES SKIP
					; スレーブからの ACK待ち 0=受信済み次ぎをスキップ
	GOTO		$-1		;IF NO,END 
;===============================================================================
	;repeated start
	banksel		SSPCON2
	bsf		SSPCON2,RSEN
	btfsc		SSPCON2,RSEN
	goto		$-1
;===============================================================================
;	READADRS	;スレーブアドレス・リード
	BANKSEL		READADRS	;bank0
	MOVF		READADRS,W	;F -> W  スレーブアドレス・リード
	MOVWF		SSPBUF		;W -> F  INITIATE SEND この瞬間に送信される
SENDC3D:
	BANKSEL		PIR1
	bcf		PIR1,SSPIF
	BTFSS		PIR1, SSPIF	;SEND COMPLETED? YES,SKIP NEXT 送信完了?
	GOTO		SENDC3D
	BCF		PIR1, SSPIF	;YES,CLEAR FLAG 割り込みフラグ・クリア
	BANKSEL		SSPCON2
	BTFSC		SSPCON2,ACKSTAT	;ACK RECEIVED FROM SLAVE?IF YES SKIP
					; スレーブからの ACK待ち 0=受信済み次ぎをスキップ
	GOTO		$-1		; Wait to ACK END
;===============================================================================
;	I2Cから1byte入力しWREGに格納する。デバイスへはNACKを返す。
;	i2c_last_read	最終1byte入力
        bsf		SSPCON2,RCEN    ; 受信を許可
        btfsc		SSPCON2,RCEN
        goto		$-1		; PICが受信許可状態になるまでループ
	
	banksel		PIR1		;bank0
	btfss		PIR1,SSPIF
	goto		$-1
	bcf		PIR1,SSPIF
	
	banksel		SSPBUF		;bank0
	movf		SSPBUF,W
	MOVWF		W_TEMP		;W -> W_TEMP  I/O EXPANDER へ出力するデータの確保
	
	banksel		SSPCON2		;bank1
        bsf		SSPCON2,ACKDT   ; NACKを出力
        bsf		SSPCON2,ACKEN   ; ACKENをセット
        btfsc		SSPCON2,ACKEN
        goto		$-1		; ACKの送信が終了するループ
	
	banksel		PIR1		;bank0
	bcf		PIR1,SSPIF
        
        return

END


・p16f886_24C64_sub_i2c.asm サブルーチン

	list      	p=16F886	; 翻訳時にリストファイルを作ります
	#include 		; 定義ファイルを読み込みます
	errorlevel  	-302		; 翻訳時に302エラーが出ないようにします
	errorlevel  	-205		; 翻訳時に205エラーが出ないようにします
	errorlevel  	-305		; 翻訳時に305エラーが出ないようにします
	;***********************************************************************
;サブルーチン、PCF8574を読む
	GLOBAL	I2C_INIT,START_I2C,STOP_I2C,IDLE

	;サブルーチンのラベル名がメインプログラムでEXTERNで宣言されて居る
	;その為、必ずGLOBALで受ける、つまり EXTERN と GLOBAL はペア
;===============================================================================
CODE	;サブルーチン、ここから
;===============================================================================
I2C_INIT
;===============================================================================
;I2C の為の初期化
	BANKSEL		SSPCON		;BANK0
	movlw		0x28		;0x28 = シリアルポートを動作させ、SDA とSCL ピンをシリアルポートピンにする。
					;0x28 = I2C マスターモード、クロック= FOSC / (4 * (SSPADD+1) )
	movwf		SSPCON
	
	BANKSEL		SSPSTAT		;BANK1
	BSF		SSPSTAT, SMP
	BCF		SSPSTAT, CKE
	CLRF		TRISB		;BANK1
	BSF		TRISC, 0x04	;SDA=IN
	BSF		TRISC, 0x03	;SCL=IN
	MOVLW		0x13		;I2C BUS speed  小さい程早く成る
	MOVWF		SSPADD		;BANK1
	NOP
	RETURN
;********************* START CONDITION *****************************************
START_I2C
	BANKSEL		SSPCON2
	BSF		SSPCON2, SEN	; INITIATE START
SENDB2:
	BANKSEL		PIR1
	BTFSS		PIR1, SSPIF	;START COMPLETED?YES SKIP NEXT
	GOTO		SENDB2
	BCF		PIR1, SSPIF	;YES,CLEAR FLAG
	RETURN
;*********************	INITIATE STOP*******************************************
STOP_I2C
SENDB5:	
	BANKSEL		SSPCON2		;bank1
 	BSF		SSPCON2,PEN
	BCF		STATUS,RP0	;bank0
SENDBE:	
	BTFSS		PIR1,SSPIF	
	GOTO		SENDBE
	BCF		PIR1,SSPIF
	RETURN
;===============================================================================
;idle
IDLE:
    banksel SSPCON2
;    
;    CLRF    SSPCON2
;    btfsc   SSPCON2,ACKDT
;    goto    $-1
;    
    btfsc   SSPCON2,ACKEN
    goto    $-1
    btfsc   SSPCON2,RCEN
    goto    $-3
    btfsc   SSPCON2,PEN
    goto    $-5
    btfsc   SSPCON2,RSEN
    goto    $-7
    btfsc   SSPCON2,SEN
    goto    $-9
    RETURN
				
END

・p16f886_24C64_write.asm   サブルーチン、書き込み

	list      	p=16F886	; 翻訳時にリストファイルを作ります
	#include 		; 定義ファイルを読み込みます
	errorlevel  	-302		; 翻訳時に302エラーが出ないようにします
	errorlevel  	-205		; 翻訳時に205エラーが出ないようにします
	errorlevel  	-305		; 翻訳時に305エラーが出ないようにします
	;***********************************************************************
;サブルーチン、PCF8574を読む
	GLOBAL	I2C_INIT,START_I2C,STOP_I2C,IDLE

	;サブルーチンのラベル名がメインプログラムでEXTERNで宣言されて居る
	;その為、必ずGLOBALで受ける、つまり EXTERN と GLOBAL はペア
;===============================================================================
CODE	;サブルーチン、ここから
;===============================================================================
I2C_INIT
;===============================================================================
;I2C の為の初期化
	BANKSEL		SSPCON		;BANK0
	movlw		0x28		;0x28 = シリアルポートを動作させ、SDA とSCL ピンをシリアルポートピンにする。
					;0x28 = I2C マスターモード、クロック= FOSC / (4 * (SSPADD+1) )
	movwf		SSPCON
	
	BANKSEL		SSPSTAT		;BANK1
	BSF		SSPSTAT, SMP
	BCF		SSPSTAT, CKE
	CLRF		TRISB		;BANK1
	BSF		TRISC, 0x04	;SDA=IN
	BSF		TRISC, 0x03	;SCL=IN
	MOVLW		0x13		;I2C BUS speed  小さい程早く成る
	MOVWF		SSPADD		;BANK1
	NOP
	RETURN
;********************* START CONDITION *****************************************
START_I2C
	BANKSEL		SSPCON2
	BSF		SSPCON2, SEN	; INITIATE START
SENDB2:
	BANKSEL		PIR1
	BTFSS		PIR1, SSPIF	;START COMPLETED?YES SKIP NEXT
	GOTO		SENDB2
	BCF		PIR1, SSPIF	;YES,CLEAR FLAG
	RETURN
;*********************	INITIATE STOP*******************************************
STOP_I2C
SENDB5:	
	BANKSEL		SSPCON2		;bank1
 	BSF		SSPCON2,PEN
	BCF		STATUS,RP0	;bank0
SENDBE:	
	BTFSS		PIR1,SSPIF	
	GOTO		SENDBE
	BCF		PIR1,SSPIF
	RETURN
;===============================================================================
;idle
IDLE:
    banksel SSPCON2
;    
;    CLRF    SSPCON2
;    btfsc   SSPCON2,ACKDT
;    goto    $-1
;    
    btfsc   SSPCON2,ACKEN
    goto    $-1
    btfsc   SSPCON2,RCEN
    goto    $-3
    btfsc   SSPCON2,PEN
    goto    $-5
    btfsc   SSPCON2,RSEN
    goto    $-7
    btfsc   SSPCON2,SEN
    goto    $-9
    RETURN
				
END

・subroutin.asm         サブルーチン
無駄なプログラムが多いです、流用なのでご容赦

;***********************************************************************************
;  PIC16F886 Extra Subroutines	Ver 1.00 2009/11/25
;***********************************************************************************
	list      	p=16F886	; 翻訳時にリストファイルを作ります
	#include 		; 12F683用定義ファイルを読み込みます
	errorlevel  	-302		; 翻訳時に302エラーが出ないようにします
	errorlevel  	-205		; 翻訳時に205エラーが出ないようにします
	errorlevel  	-305		; 翻訳時に305エラーが出ないようにします
;============================================================
	GLOBAL	TIMADJ,TIM8ms,TIM100ms,TIM500ms,TIM10ms,ADGET,OUT_A,OUT_B,OUT_C,SWON,SWON2	
				;サブルーチンのラベル名がメインプログラムでEXTERNで宣言されて居る
				;その為、必ずGLOBALで受ける、つまり EXTERN と GLOBAL はペア
;============================================================
CODE	;サブルーチン、ここから
;============================================================
;A/D コンバータースタート、10bit有る、ADINITで左シフトに設定してあるので上位8ビットがTEMP1に入る
;ADCON0のbit2を1にするとスタートし、それが0に成ったらA/D変換終了
;A/D回路はノイズが出るらしく、ここではいちいちA/Dを使う設定をし、変換したら使わない設定にするADCON0,0
ADGET				;A/D Convertion
	BSF	ADCON0,0	;USE A/D Convertion
	CALL	SC01
	BSF	ADCON0,1	;A/D Covert to start
	CALL	SC01		;Wait 40us for A/D Convertion Capacitor Charge Time
LP00B
	CLRWDT			;WATCH DOG TIMER RESET
        BTFSC	ADCON0,1
        GOTO	LP00B
        MOVF	ADRESH,W	;A/D Value MSB to W
        MOVWF	TEMP1		;W to TEMP1
	BSF	STATUS,5	;Change to Bank1 (STATUS Register Bit5 set to 1)
        MOVF	ADRESL,W	;A/D Value LSB to W
	BCF	STATUS,5	;Back to Bank0 (STATUS Register Bit5 set to 0)
        MOVWF	TEMP2		;W to TEMP2
	BCF	ADCON0,0	;NO-USE A/D Convertion (For Noise cut)
	RETURN
SC01				;Timer 40us
        MOVLW   24H
        MOVWF   COUNT
LP01B   
        DECFSZ  COUNT,F	;Dec COUNT untill 0
        GOTO    LP01B
        RETURN
;============================================================
;TEMP3レジスタの数値を01--FFhで変化させる事で待ち時間を設定出来る
TIMADJ				;Adjustable TIMER
	MOVLW	D'1' 		;DataA write to the W register(under the ALU)
	MOVWF	COUNT4		;Data set to the COUNT4
LP5B	MOVLW	D'12' 		;DataA write to the W register(under the ALU)
	MOVWF	COUNT3		;Data set to the COUNT3
LP5C	DECFSZ	COUNT2		;COUNT2 DEC
	GOTO	LP5C		;CNTR INC UNTILL 0
	CLRWDT			;WATCH DOG TIMER RESET
	MOVF	TEMP3,W		;TEMP1 to W
	MOVWF	COUNT2		;W to COUNT2
	DECFSZ	COUNT3		;COUNT3 DEC
	GOTO	LP5C		;REPT DEC UNTILL 0
	DECFSZ	COUNT4		;REPT2 DEC
	GOTO	LP5B		;REPT2 DEC UNTILL 0
	RETURN			;BACK TO Main Rutin
;============================================================
;10ms待つ
TIM10ms				;10msTIMER
	MOVLW	D'1' 		;DataA write to the W register(under the ALU)
	MOVWF	COUNT3		;Data set to the COUNT2
LP08B	MOVLW	D'13' 		;DataA write to the W register(under the ALU)
	MOVWF	COUNT2		;Data set to the COUNT
LP08C	INCFSZ	COUNT		;CNTR INC
	GOTO	LP08C		;CNTR INC UNTILL 256
	CLRWDT			;WATCH DOG TIMER RESET
	DECFSZ	COUNT2		;COUNT DEC
	GOTO	LP08C		;COUNT DEC UNTILL 0
	DECFSZ	COUNT3		;COUNT2 DEC
	GOTO	LP08B		;COUNT2 DEC UNTILL 0
	RETURN			;BACK TO MAIN
;============================================================
;8ms待つ
TIM8ms				;8msTIMER
	MOVLW	D'1' 		;DataA write to the W register(under the ALU)
	MOVWF	COUNT3		;Data set to the COUNT2
LP08D	MOVLW	D'1' 		;DataA write to the W register(under the ALU)
	MOVWF	COUNT2		;Data set to the COUNT
LP08E	INCFSZ	COUNT		;CNTR INC
	GOTO	LP08E		;CNTR INC UNTILL 256
	CLRWDT			;WATCH DOG TIMER RESET
	DECFSZ	COUNT2		;COUNT DEC
	GOTO	LP08E		;COUNT DEC UNTILL 0
	DECFSZ	COUNT3		;COUNT2 DEC
	GOTO	LP08D		;COUNT2 DEC UNTILL 0
	RETURN			;BACK TO MAIN
;============================================================
;100ms待つ
TIM100ms				;100msTIMER
	MOVLW	D'10' 		;DataA write to the W register(under the ALU)
	MOVWF	COUNT3		;Data set to the COUNT2
LP08F	MOVLW	D'13' 		;DataA write to the W register(under the ALU)
	MOVWF	COUNT2		;Data set to the COUNT
LP08G	INCFSZ	COUNT		;CNTR INC
	GOTO	LP08G		;CNTR INC UNTILL 256
	CLRWDT			;WATCH DOG TIMER RESET
	DECFSZ	COUNT2		;COUNT DEC
	GOTO	LP08G		;COUNT DEC UNTILL 0
	DECFSZ	COUNT3		;COUNT2 DEC
	GOTO	LP08F		;COUNT2 DEC UNTILL 0
	RETURN			;BACK TO MAIN
;============================================================
;500ms待つ
TIM500ms				;100msTIMER
	MOVLW	D'50' 		;DataA write to the W register(under the ALU)
	MOVWF	COUNT3		;Data set to the COUNT2
LP08H	MOVLW	D'13' 		;DataA write to the W register(under the ALU)
	MOVWF	COUNT2		;Data set to the COUNT
LP08I	INCFSZ	COUNT		;CNTR INC
	GOTO	LP08I		;CNTR INC UNTILL 256
	CLRWDT			;WATCH DOG TIMER RESET
	DECFSZ	COUNT2		;COUNT DEC
	GOTO	LP08I		;COUNT DEC UNTILL 0
	DECFSZ	COUNT3		;COUNT2 DEC
	GOTO	LP08H		;COUNT2 DEC UNTILL 0
	RETURN			;BACK TO MAIN
;============================================================
;PORTAが出力に設定されて居る場合PTAレジスタのビットを立てればそのビットを出力する
OUT_A	NOP			;PORT OUTPUT ROUTIN
	CLRWDT			;WATCH DOG TIMER RESET
	MOVF	PTA,W		;DATA COPY FROM PTA TO W RESISTER
	MOVWF	PORTA		;DATA COPY FROM W TO PORTA
	RETURN
;============================================================
;PORTBが出力に設定されて居る場合PTAレジスタのビットを立てればそのビットを出力する
OUT_B	NOP			;PORT OUTPUT ROUTIN
	CLRWDT			;WATCH DOG TIMER RESET
	MOVF	PTB,W		;DATA COPY FROM PTB TO W RESISTER
	MOVWF	PORTB		;DATA COPY FROM W TO PORTB
	RETURN
;============================================================
;PORTCが出力に設定されて居る場合PTCレジスタのビットを立てればそのビットを出力する
OUT_C	NOP			;PORT OUTPUT ROUTIN
	CLRWDT			;WATCH DOG TIMER RESET
	MOVF	PTC,W		;DATA COPY FROM PTC TO W RESISTER
	MOVWF	PORTC		;DATA COPY FROM W TO PORTC
	RETURN
;============================================================
;入力はPA0(17pin)
;ここでは入力が H-->L-->H を一通り経由すると SWFLAGのbit2 が0-->1に成る
;チャタリングは30msに設定されて居る
;特徴は入力の状態をずっと見ているのでは無く時々見に行きフラグを変化させている
;その為、入力を見に行って他のことが何も出来ないのではなく同時に並行して他の
;作業を出来ることである
;------------------------------
SWON	CLRWDT
	BCF	SWFLAG,2	;SW ON のフラグをクリア
	BCF	STATUS,Z
	BCF	STATUS,C
	BCF	STATUS,DC
	MOVLW	D'1'		;D'5'--->W  1= 10ms
	MOVWF	COUNT4		;W--->COUNT4
	;-----------------------SW ポートの H/Lチェック
	MOVF	TRISA,W		;IO-->W
	MOVWF	PTA		;W-->PTA
	BTFSC	PTA,0		;SW=Hつまり押されていない、次へ
				;SW=Lつまり押された、次をスキップ
	GOTO	SWONC		;押されて居ないへ進む
	;-----------------------SW ポートは L チャタリングチェック
SWONB	CLRWDT
	CALL	TIM10ms	
	CALL	TIM10ms	
	CALL	TIM10ms	
	MOVF	TRISA,W		;IO-->W
	MOVWF	PTA		;W-->PTA
	BTFSC	PTA,0		;SW=1つまり押されていない、次へ
				;SW=0つまり押された、次をスキップ
	RETURN			;押されて居ない、チャタリング、MAINへ戻る
;	CALL	TIM10ms		;10ms timer チャタリング対策
;	DECFSZ	COUNT4,1	;COUNT4 = COUNT4 - 1 ゼロに成ったら次をスキップ
				;ゼロで無いならば次へ進む
;	GOTO	SWONB		;再度押されたかチェックを繰り返す
	;-----------------------
	MOVLW	D'1'		; 1 --> W
	SUBWF	SWFLAG,1	;SWFLAG=SWFLAG-1
	BTFSC	STATUS,C	;C=1(キャリーフラグ)ならばプラス、次へ
				;C=0ならばゼロかマイナス次をスキップ
	GOTO	SWONB1
	BTFSS	STATUS,Z	;Z=0ならマイナス次 Z=1ならゼロ次をスキップ
	GOTO	SET0		;SWFLAGをゼロにしてMAINに戻る
SWONB1	SUBWF	SWFLAG,1	;SWFLAG=SWFLAG-1
	BTFSC	STATUS,C	;C=1(キャリーフラグ)ならばプラス、次へ
				;C=0ならばゼロかマイナス次をスキップ
	GOTO	SWONB2
	BTFSS	STATUS,Z	;Z=0ならマイナス次 Z=1ならゼロ次をスキップ
	GOTO	SET2		;SWFLAGを2にしてMAINに戻る
SWONB2	SUBWF	SWFLAG,1	;SWFLAG=SWFLAG-1
	BTFSC	STATUS,C	;C=1(キャリーフラグ)ならばプラス、次へ
				;C=0ならばゼロかマイナス次をスキップ
	GOTO	SWONB3
	BTFSS	STATUS,Z	;Z=0ならマイナス次 Z=1ならゼロ次をスキップ
	GOTO	SET2		;SWFLAGを2にしてMAINに戻る
SWONB3	GOTO	SET0		;SWFLAGをゼロにしてMAINに戻る
	;-----------------------SW ポートは H チャタリングチェック
SWONC	CLRWDT
	CALL	TIM10ms	
	CALL	TIM10ms	
	CALL	TIM10ms		
	MOVF	TRISA,W		;IO-->W
	MOVWF	PTA		;W-->PTA
	BTFSS	PTA,0		;SW=0つまり押されていない、次をスキップ
				;SW=1つまり押された、次へ
	RETURN			;押されて居ない、チャタリング、MAINへ戻る
;	CALL	TIM10ms		;10ms timer チャタリング対策
;	DECFSZ	COUNT4,1	;COUNT4 = COUNT4 - 1 ゼロに成ったら次をスキップ
				;ゼロで無いならば次へ進む
;	GOTO	SWONC		;再度押されたかチェックを繰り返す
	;-----------------------
	MOVLW	D'1'		; 1 --> W
	SUBWF	SWFLAG,1	;SWFLAG=SWFLAG-1
	BTFSC	STATUS,C	;C=1(キャリーフラグ)ならばプラス、次へ
				;C=0ならばゼロかマイナス次をスキップ
	GOTO	SWONC1
	BTFSS	STATUS,Z	;Z=0ならマイナス次 Z=1ならゼロ次をスキップ
	GOTO	SET1		;SWFLAGを1にしてMAINに戻る
SWONC1	SUBWF	SWFLAG,1	;SWFLAG=SWFLAG-1
	BTFSC	STATUS,C	;C=1(キャリーフラグ)ならばプラス、次へ
				;C=0ならばゼロかマイナス次をスキップ
	GOTO	SWONC2
	BTFSS	STATUS,Z	;Z=0ならマイナス次 Z=1ならゼロ次をスキップ
	GOTO	SET1		;SWFLAGを1にしてMAINに戻る
SWONC2	SUBWF	SWFLAG,1	;SWFLAG=SWFLAG-1
	BTFSC	STATUS,C	;C=1(キャリーフラグ)ならばプラス、次へ
				;C=0ならばゼロかマイナス次をスキップ
	GOTO	SWONC3
	BTFSS	STATUS,Z	;Z=0ならマイナス次 Z=1ならゼロ次をスキップ
	GOTO	SET3		;SWFLAGを3にしてMAINに戻る、つまりSWは一通りの経過を経て押された
SWONC3	GOTO	SET0		;SWFLAGをゼロにしてMAINに戻る
	;-----------------------
SET0	CLRF	SWFLAG		;SET0
	RETURN
SET1	MOVLW	D'1'		;SET1
	MOVWF	SWFLAG		;W --> SWFLAG
	RETURN
SET2	MOVLW	D'2'		;SET2
	MOVWF	SWFLAG		;W --> SWFLAG
	RETURN
SET3	MOVLW	D'3'		;SET3 つまりSW操作は正しく一通り行われた
	MOVWF	SWFLAG		;W --> SWFLAG
	BSF	SWFLAG,2	;SW ON のフラグを立てる
	RETURN
;============================================================
;入力はPA1(18pin)
;ここでは入力が H-->L-->H を一通り経由すると SWFLAG2のbit2 が0-->1に成る
;チャタリングは30msに設定されて居る
;特徴は入力の状態をずっと見ているのでは無く時々見に行きフラグを変化させている
;その為、入力を見に行って他のことが何も出来ないのではなく同時に並行して他の
;作業を出来ることである
SWON2	CLRWDT
	BCF	SWFLAG2,2	;SW ON のフラグをクリア
	BCF	STATUS,Z
	BCF	STATUS,C
	BCF	STATUS,DC
	MOVLW	D'1'		;D'5'--->W  1= 10ms
	MOVWF	COUNT4		;W--->COUNT4
	;-----------------------SW ポートの H/Lチェック
	MOVF	TRISA,W		;IO-->W
	MOVWF	PTA		;W-->PTA
	BTFSC	PTA,1		;SW=Hつまり押されていない、次へ
				;SW=Lつまり押された、次をスキップ
	GOTO	SWON2C		;押されて居ないへ進む
	;-----------------------SW ポートは L チャタリングチェック
SWON2B	CLRWDT
	CALL	TIM10ms	
	CALL	TIM10ms	
	CALL	TIM10ms		
	MOVF	TRISA,W		;IO-->W
	MOVWF	PTA		;W-->PTA
	BTFSC	PTA,1		;SW=1つまり押されていない、次へ
				;SW=0つまり押された、次をスキップ
	RETURN			;押されて居ない、チャタリング、MAINへ戻る
;	CALL	TIM10ms		;10ms timer チャタリング対策
;	DECFSZ	COUNT4,1	;COUNT4 = COUNT4 - 1 ゼロに成ったら次をスキップ
				;ゼロで無いならば次へ進む
;	GOTO	SWON2B		;再度押されたかチェックを繰り返す
	;-----------------------
	MOVLW	D'1'		; 1 --> W
	SUBWF	SWFLAG2,1	;SWFLAG2=SWFLAG2-1
	BTFSC	STATUS,C	;C=1(キャリーフラグ)ならばプラス、次へ
				;C=0ならばゼロかマイナス次をスキップ
	GOTO	SWON2B1
	BTFSS	STATUS,Z	;Z=0ならマイナス次 Z=1ならゼロ次をスキップ
	GOTO	SETB0		;SWFLAG2をゼロにしてMAINに戻る
SWON2B1	SUBWF	SWFLAG2,1	;SWFLAG2=SWFLAG2-1
	BTFSC	STATUS,C	;C=1(キャリーフラグ)ならばプラス、次へ
				;C=0ならばゼロかマイナス次をスキップ
	GOTO	SWON2B2
	BTFSS	STATUS,Z	;Z=0ならマイナス次 Z=1ならゼロ次をスキップ
	GOTO	SETB2		;SWFLAG2を2にしてMAINに戻る
SWON2B2	SUBWF	SWFLAG2,1	;SWFLAG2=SWFLAG2-1
	BTFSC	STATUS,C	;C=1(キャリーフラグ)ならばプラス、次へ
				;C=0ならばゼロかマイナス次をスキップ
	GOTO	SWON2B3
	BTFSS	STATUS,Z	;Z=0ならマイナス次 Z=1ならゼロ次をスキップ
	GOTO	SETB2		;SWFLAG2を2にしてMAINに戻る
SWON2B3	GOTO	SETB0		;SWFLAG2をゼロにしてMAINに戻る
	;-----------------------SW ポートは H チャタリングチェック
SWON2C	CLRWDT
	CALL	TIM10ms	
	CALL	TIM10ms	
	CALL	TIM10ms		
	MOVF	TRISA,W		;IO-->W
	MOVWF	PTA		;W-->PTA
	BTFSS	PTA,1		;SW=0つまり押されていない、次をスキップ
				;SW=1つまり押された、次へ
	RETURN			;押されて居ない、チャタリング、MAINへ戻る
;	CALL	TIM10ms		;10ms timer チャタリング対策
;	DECFSZ	COUNT4,1	;COUNT4 = COUNT4 - 1 ゼロに成ったら次をスキップ
				;ゼロで無いならば次へ進む
;	GOTO	SWON2C		;再度押されたかチェックを繰り返す
	;-----------------------
	MOVLW	D'1'		; 1 --> W
	SUBWF	SWFLAG2,1	;SWFLAG2=SWFLAG2-1
	BTFSC	STATUS,C	;C=1(キャリーフラグ)ならばプラス、次へ
				;C=0ならばゼロかマイナス次をスキップ
	GOTO	SWON2C1
	BTFSS	STATUS,Z	;Z=0ならマイナス次 Z=1ならゼロ次をスキップ
	GOTO	SETB1		;SWFLAG2を1にしてMAINに戻る
SWON2C1	SUBWF	SWFLAG2,1	;SWFLAG2=SWFLAG2-1
	BTFSC	STATUS,C	;C=1(キャリーフラグ)ならばプラス、次へ
				;C=0ならばゼロかマイナス次をスキップ
	GOTO	SWON2C2
	BTFSS	STATUS,Z	;Z=0ならマイナス次 Z=1ならゼロ次をスキップ
	GOTO	SETB1		;SWFLAG2を1にしてMAINに戻る
SWON2C2	SUBWF	SWFLAG2,1	;SWFLAG2=SWFLAG2-1
	BTFSC	STATUS,C	;C=1(キャリーフラグ)ならばプラス、次へ
				;C=0ならばゼロかマイナス次をスキップ
	GOTO	SWON2C3
	BTFSS	STATUS,Z	;Z=0ならマイナス次 Z=1ならゼロ次をスキップ
	GOTO	SETB3		;SWFLAG2を3にしてMAINに戻る、つまりSWは一通りの経過を経て押された
SWON2C3	GOTO	SETB0		;SWFLAG2をゼロにしてMAINに戻る
	;-----------------------
SETB0	CLRF	SWFLAG2		;SETB0
	RETURN
SETB1	MOVLW	D'1'		;SETB1
	MOVWF	SWFLAG2		;W --> SWFLAG2
	RETURN
SETB2	MOVLW	D'2'		;SETB2
	MOVWF	SWFLAG2		;W --> SWFLAG2
	RETURN
SETB3	MOVLW	D'3'		;SETB3 つまりSW操作は正しく一通り行われた
	MOVWF	SWFLAG2		;W --> SWFLAG2
	BSF	SWFLAG2,2	;SW ON のフラグを立てる
	RETURN
;********************************************************************************************
END


nice!(0)  コメント(0) 

世田谷ボロ市

寒いですねぇ

世田谷のボロ市ってのはいつでも寒い、という印象が在りますが
矢張り今回も寒かったです、北風が良く通るからかもしれません。
そのせいか風邪をひいてしまう方が多い事を過去の経験からも
聞いています、その理由ですが・・・

・普段あんまり長時間外歩きをしない
・自由に歩けない
・長時間、寒い中ゆっくりとしか進まない
・行列に並んで居る様なものだ
・人混みである

・・・と私は分析しています、外歩きでも早歩きならば体は温まるの
ですがボロ市ではそうは行かない。

兎に角、暖かい物がご馳走でした、甘酒は何所で飲んでも100円
と格安です、コンビニではアンマン、肉まんがよく売れていました
今年は明日(12/16)までボロ市はやっていますので沢山の人出で賑わう
事でしょう、ただ、欲しいモノが在るのか無いのかでは無く物見遊山

で来て興味があれば買って帰るという人が圧倒的に多い様に思います
もしお出掛けであれば防寒対策は必須、そして来月もボロ市
は在りますが、、平日と成って居ます。

2018年も余すところ半月と成りましたウチの事務所、年内売上もっと
頑張らねばと焦って居ますが、なかなか思うようには行きませんね。




nice!(0)  コメント(0) 

ソースコード枠

bandicam 2018-12-20 10-09-27-070


;***********************************************************************************
;  Extra Initialize for PIC16F88	Ver 1.00 2009/10/23
;***********************************************************************************
	list      	p=16F88	; 翻訳時にリストファイルを作ります
	#include 		; 12F683用定義ファイルを読み込みます
	errorlevel  	-302		; 翻訳時に302エラーが出ないようにします
	errorlevel  	-205		; 翻訳時に205エラーが出ないようにします
	errorlevel  	-305		; 翻訳時に305エラーが出ないようにします
;-----------------------------------------------------------
	GLOBAL	IOINIT,OPTINIT,OSCINIT,INTINIT,PWMINIT,ADINIT,COMPINIT
				;サブルーチンのラベル名がメインプログラムでEXTERNで宣言されて居る
				;その為、必ずGLOBALで受ける、つまり EXTERN と GLOBAL はペア
;-----------------------------------------------------------
CODE
;==============================================
;*** IO INITIALIZATION
IOINIT
	BSF	STATUS,RP0	;Set BANK1
;-------PORT A TRISA (85h)
	MOVLW	B'00000000'	;Port A 0=OUTPUT 1=INPUT(B=bit map / H=hex code)
	MOVWF	TRISA		;Port A Setup regist to PORTA
;-------PORT B TRISB (86h)
	MOVLW	B'11111111'	;Port B 0=OUTPUT 1=INPUT(B=bit map / H=hex code)
	MOVWF	TRISB		;Port B Setup regist to PORTB
	BCF 	STATUS,RP0 	;Bank 0 へ戻る
	RETURN
;==============================================	
;*** OPTION RESISTER INITIALIZATION
OPTINIT
	BSF 	STATUS,RP0 	;Bank 1 へ切替
	;-----------------------
	;	OPTION REGISTER (81h)
	;-----------------------
	MOVLW	B'00000111'	;Option register setting
				;MSB(here)
				;PORTB pull-up 		0=使用する 1=使用しない
				;RB0/INT割り込みエッジ 	0=H-->L  1=L-->H
				;TMR0のクロック 		0=内部クロック(Fosc/4) 1=外部クロック(RA4,TOCKI)
				;TMR0が外部クロック(RA4,TOCKI)の場合のインクリメント0=L-->H  1=H-->L
				;プリスケーラをどちらに使うか 	0=TMR0  1=WDT
				;111=prescaller value=1/256  (2/4/8/16/32/64/128/256)
				;LSB(here)
	MOVWF	OPTION_REG	;Optionregister to Set abovementioned value
	;-----------------------
	BCF 	STATUS,RP0 	;Bank 0 へ戻る
	RETURN
;==============================================	
;***	OSCCON (8Fh) & OSCTUNE (9Fh)
	BSF 	STATUS,RP0 	;Bank 1 へ切替
OSCADJ	EQU	3Fh		;内部発振クロックの調整値、デバイスに依って異なる
				;00h=Center MAX 1Fh-->1Eh・・・01h-->00h-->3Fh・・・1Fh-->20h MIN
				;最大で±12.5%の調整可能、但し 0.4% / 1bitと粗調である
OSCINIT
	BSF 	STATUS,RP0 	;Bank 1 へ切替
        MOVLW	B'01100100'	;内部発振クロック4MHz stable(安定の意味)0110=4MHz 0111=8MHz
	MOVWF	OSCCON		;水晶無し(_INTRC_IO)で内部クロック利用での設定
	MOVLW	OSCADJ		;00h=Center MAX 1Fh-->1Eh・・・01h-->00h-->3Fh・・・1Fh-->20h MIN
	MOVWF	OSCTUNE		;±12.5% Adjustable
	BCF 	STATUS,RP0 	;Bank 0 へ戻る
	RETURN
;==============================================	
;*** INTERRUPT INITIALIZATION
INTINIT
	;-----------------------
	;	INTCON REGISTER (0Bh)
	;-----------------------
	BCF 	STATUS,RP0 	;Bank 0 へ戻る
	MOVLW	B'00000000'	;INTCON register setting (0Bh)
				;MSB(here) ここでは RB0 を割り込み設定している
				;GIE 1=全てのマスクされて居ない割り込み発生を許可する-->(*1)
				;EEIE EEライト完了発生割り込み	0=禁止 1=許可
				;TOIE TMR0割り込み発生		0=禁止 1=許可
				;INTE RB0/INT割り込み発生	0=禁止 1=許可(*3)
				;RBIE RBポート変化発生割り込み	0=禁止 1=許可
				;TOIF 1=FLAG ON/ 0=OFF TOIF:TMR0オーバーフロー割り込みフラグビット(要クリア)
				;INTF 1=FLAG ON/ 0=OFF INTF:RB0/INT割り込みフラグビット(要クリア)
				;RBIF 1=FLAG ON/ 0=OFF RBIF:RBポート変更割り込みフラグビット(要クリア)
	MOVWF	INTCON		;INTCON register to Set abovementioned value
	RETURN
;==============================================	
;***	PWM INITIALIZATION CCPR1L(15h) CCP1CON(17h) T2CON(12h)
;PWMのパルスは出力命令無しに勝手に15pinに出てくる
PWMINIT
	BCF 		STATUS,RP0 	;Bank 0 へ戻る
	CLRF		TMR2		;TMR2カウンタのクリア
					;(TMR0,TMR1はPWMには使用不可)
	;CCP1パラメータ
	MOVLW		B'01111111'	; DUTY 01h(殆どLow)-->FFh(殆どHi) 00h=off
	MOVWF		CCPR1L		;SET CCPR1L REGISTER
	MOVLW		B'00000000'	;CCP1XY=0 ON=1100(PWM) OFF=0000
	MOVWF		CCP1CON		;SET CCP1CON REGISTER
	;CCP2パラメータは存在しない(機能無し)
	;CCP1パラメータ      
	BSF		STATUS,RP0	;CHANGE TO BANK1
	MOVLW		D'255'		;周期(244Hz/4MHz_X-TAL)
					;PR2は、255<-- 遅い--速い-->001
	MOVWF		PR2		;SET PR2 REGISTER(PR1は存在せず)
	BCF		STATUS,RP0	;CHANGE TO BANK0
	MOVLW		B'00000110'	;PST=1:1 TMR2=ON PWM専用プリスケール=1:16
	MOVWF		T2CON		;SET T2CON REGISTER
					;T1CONはTMR1専用PWMには使用不可
					;因みにT0CONは存在せず
	RETURN
;==============================================	
;***	A/D 設定 ADCON0 (1Fh) & ADCON1(9Fh) & ANSEL(9Bh)
ADINIT
	BSF 	STATUS,RP0 	;Bank 1 へ切替
	MOVLW	B'00000000'	;ADCON1はPIC16F873とは異なるので要注意!!
				;この設定はA/D Conv Value 10 bit resister Left Shift
				;Vref+ = AVdd(Vcc) / Vref- = AVss(0V,GND)
	MOVWF	ADCON1		;ADCON1 to Set abovementioned value
	MOVLW	B'00000000'	;bit7=0 設定無し
				;bit6=AN6 13pin 0=I/O 1=A/D
				;bit5=AN5 12pin   ↑↑
				;bit4=AN4  3pin   ↑↑
				;bit3=AN3  2pin   ↑↑
				;bit2=AN2  1pin   ↑↑
				;bit1=AN1 18pin   ↑↑
				;bit0=AN0 17pin   ↑↑
	MOVWF	ANSEL		;A/D Input AN0使用
	;
	BCF	STATUS,RP0	;Back to BANK0
	;
	MOVLW	B'01000000'	;ADCON0 PIC16F873と同一
				;Bit7,6 Fosc/8標準
				;Bit5--3 Channel設定、下記
				;110	AN6
				;101	AN5
				;100	AN4
				;011	AN3
				;010	AN2
				;001	AN1
				;000	AN0
				;bit1は使用せず
				;bit0はA/DのON/OFF 1=ON 0=OFF
	MOVWF	ADCON0		;ADCON0 to Set abovementioned value
	BCF 	STATUS,RP0 	;Bank 0 へ戻る
	RETURN
;==============================================
;	COMPARATOR 定義 (CMCON 9Ch)--ここでは使用しない設定--
COMPINIT
	BSF 	STATUS,RP0 	;Bank 1 へ切替
	MOVLW	B'00000111'	;CMCON resister setting 使用しないのでOPアンプ入力をターミネイトする
	MOVWF	CMCON		;CMCON register to Set abovementioned value
	BCF 	STATUS,RP0 	;Bank 0 へ戻る
	RETURN
;==============================================
;==============================================
;==============================================
;********************************************************************************************
END

続きを読む


nice!(0)  コメント(0) 

I2Cを使う PIC16F876A PCF8574AN

お客様の案件で I2C を使う回路設計の必要が在りました
はい、過去形ですが実は没に成って仕舞った案件です
然し乍ら設計者のさがで一度始めると納得行くまでやって仕舞う
この悪い癖、何とかしなければならないのですが・・・・

でも、やって置けば其れだけ後々何かの役に立つ事も有るでしょう
という訳でドキュメントを残す意味で簡単な回路を組んでみました
まず、使用するICは・・・・

CPU が PIC16F876A  28pin Dip MICROCHIP社
日本語マニュアルが用意されているので製作記事が多いです
このPICにはMSSP(Master Synchronous Serial Port)が内蔵され
これがあることでI2Cが利用しやすいわけです
他のデバイスICと高速にシリアル通信をするためのモジュールで、SPIと
I2Cという2種類の動作モードで使うことができます。

F4671628-01

 RC3/SCK/SCLとRC4/SDI/SDA を使います。

bandicam 2018-12-10 11-31-00-992




IO Expander が PCF8574AN TEXAS社
16pin Dip で 8bit I/O です
回路を組む上で注意しなければならない事が有ります
それは出力で使うときの電流値です
Low出力は50mA流せますからリレー動きますよね
ところが
High出力はたったの4mA
LEDを点灯しようとしても昔のLEDだと暗くて話しに成りません
もう一つ押さえておきたいことは入力として使用した場合
OPEN = High だという事です、入力端子の空きピン処理は考慮に
入れて置かなければなりませんね
F5170249-01
pcf8574a-pin
またスレーブアドレスが僅かな型式違いで異なるので知らないと焦ります
驚くのは同じPCF8574Aでもスレーブアドレスが違うって・・・何?
購入するときは良く確認しなければなりません

bandicam 2018-12-07 00-02-28-302

bandicam 2018-12-10 09-41-15-897


どう考えてもおかしい、このスレーブアドレスで設計された記事を
全く見掛けません、マニュアルのダウンロードにもご注意下さい
仮にスレーブアドレス 0x20 とした場合、READ アドレスは 0x21
てなければならない、なのに A0 = High と成ったときに 0x21に
成って居ます、通常は LSBがHigh に成った場合スレーブアドレスは
0x02加算されなければなりません、なんで?
bandicam 2018-12-06 23-59-09-840




これらを使って LEDの点滅、詰まり Lチカ をやってみようと思います
この組み合わせにした理由ですが下記の様な条件が在ったからです・・・

・GPIOを使う
・LEDを50個ぐらい使う
・スイッチを20個ぐらい使う
・メンブレン・パネルに実装したい
・UART / I2C は可能
・SPI はダメ

・・・とこんな条件なのですがGPIOではピン数が限定的でとても
これだけの I/O はカバー仕切れません、その為に IO Expander を採用しました
I2Cにしたのは過去にハードウェアのみ経験しているからです

ところが採用したい I2C のソフトウェアに問題が在るのです
私はめっきりソフトウェアに弱いので皆様のように C言語でサクッ!! っと
プログラミング出来ません、なのでどうするか・・・・

・アセンブラ言語とする
・可能な限りネット検索してプログラムを引っぱってくる
・ブレッドボードを使う

・・・・こんな地味ぃな戦略なのです

2018/12/07(金)
ブレッドボードに仮組みしてみました

DSCN9756

写真で出来て居る事は、出力制御です、8bit 出力の確認をLEDで
行って居ます。
ここで判った事ですが上でも書いたように出力が Low / High で
電流値が大きく異なり、実際のLEDを接続するとこんな感じです。
この写真は出力Highの様子です、LEDは点いているのか消えているのか
良く視ないと判別がつきません
DSCN9752

一方でこの写真は出力Lowの様子で、これが正常ですよね。
DSCN9753

この様にバッファー・ドライバー無しで使うときは注意が必要です
トランジスタ・アレイ程度ならHighでドライブ出来ると思いますが
確認はマストですね。

話が少し逸れますが、使用している PIC KIT3 ですが壊した経緯が
有ります、原因はVDDに +24V が印加された為、PIC KIT3のあの
スケルトンで中が燃えているのが見えました、ひやぁーーー、でした
まぁ回路屋なので回路図をネット検索して探し、壊れて居そうな部品
をRSコンポーネンツで購入し直しました、ですがもう二度とあんな事は
嫌なのでプロテクタを中間に入れて使用しています。
DSCN9772

ツェナーダイオードの大きめのを入れ、抵抗が燃え切れる様にしました
序でなのでPIC KIT3が付いたままだと動かない事、って有りますよね
なので CLK / DAT をスイッチで切れる様にもして居ます、以来
気をつけているのでトラブルは無いですが、また在ると嫌だな。

DSCN9773

ブレッドボードで製作した回路ではプログラムに書かれたHEXデータ
1byte 分をLED表示するというものです
参考にと言うかコピーしたプログラムで引用元はこちらです

ソースコードの窓をこのブログに作りたいのですが面倒なので
後回しです、下記の通りです、折り返しが出ていますので
コピペの後、ご注意下さいこのままだとコンパイルエラーが出ます
因みにコンパイラは MICROCHIP社MPLABXIDEを使って居ます
ここから
;***************************************************************************************************************

;This software is provided in an “AS IS” condition,NO WARRANTIES in any form apply to this software.

; picmicrolab.com 5.31.2014
;***************************************************************************************************************
; PCF8574 I2C  8-bit IO expander interface with PIC16F876A;
;-------------------------------------------------------------------------------------;
		LIST 	P=PIC16F876A
		include	P16f876A.inc

 __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF & _HS_OSC & _LVP_OFF & _DEBUG_OFF & _CPD_OFF

	    org		0x00
reset:	goto start
	    org		0x04
start:

	bcf		STATUS, RP0
	bcf		STATUS, RP1
	movlw		0x28
	movwf		SSPCON
	bsf		STATUS, RP0
	BSF		SSPSTAT, SMP
	BCF		SSPSTAT, CKE
	CLRF		TRISB
	BSF		TRISC, 0x04	;SDA
	BSF		TRISC, 0x03	;SCL
	MOVLW		0x21
	MOVWF		SSPADD
LOOP:	
	BCF		STATUS,RP0
SENDB:
	BCF		PIR1,SSPIF	
;*********************START****************************************************
	BSF		STATUS, RP0	
	BSF		SSPCON2, SEN	; INITIATE START
	BCF		STATUS, RP0
SENDB2:
	BTFSS		PIR1, SSPIF	;START COMPLETED?YES SKIP NEXT
;*********************SLAVE ADDRESS-READ AFTER SETTING WORD ADDRESS*************

	GOTO		SENDB2
	BCF		PIR1, SSPIF	;YES,CLEAR FLAG
	MOVLW		0x40;		;0x40 is the  SLAVE ADDRESS   
	MOVWF		SSPBUF		;INITIATE SEND 
;SLAVE ADDRESS
SENDB3:
	BTFSS		PIR1, SSPIF	;SEND COMPLETED? YES,SKIP NEXT
	GOTO		SENDB3
	BCF		PIR1, SSPIF	;YES,CLEAR FLAG
	BSF		STATUS, RP0
	BTFSC		SSPCON2,ACKSTAT	;ACK RECEIVED FROM SLAVE?IF YES SKIP
	GOTO	 	SENDB5		;IF NO,END 

;*********************SEND Control Byte ****************************
	BCF		STATUS, RP0
	MOVLW		0x55		;Port Data		
	MOVWF		SSPBUF		;BEGIN TRANSMISSION
SENDB4:
	BTFSS		PIR1,SSPIF	;SEND COMPLETED?IF YES SKIP NEXT
	GOTO		SENDB4
	BCF		PIR1,SSPIF	;YES,CLEAR FLAG
	BSF		STATUS, RP0
	BTFSC		SSPCON2,ACKSTAT	;ACK RECEIVED FROM SLAVE?IF YES SKIP
	GOTO		SENDB5		;IF NO,END 
;*********************STOP****************************************************

    	BSF		STATUS,RP0
	BSF		SSPCON2,PEN
	BCF		STATUS,RP0
SENDBI:
	BTFSS		PIR1,SSPIF	
	GOTO		SENDBI
	BCF		PIR1,SSPIF
;*********************SEND NOACK TO END TRANSACTION*****************************
	BSF		STATUS,RP0
	BSF		SSPCON2,ACKDT	;SELECT NOACK
	BSF		SSPCON2,ACKEN	;INITIATE ACKNOWLEDGE SEQUENCE
	BCF		STATUS,RP0
SENDBC:
	BTFSS		PIR1,SSPIF	;ACK SEQUENCE COMPLEMENTED;IF YES SKIP
	GOTO		SENDBC	
	BCF		PIR1,SSPIF
;*********************	INITIATE STOP*******************************************
SENDB5:	
	BSF		STATUS,RP0
 	BSF		SSPCON2,PEN
	BCF		STATUS,RP0
SENDBE:	
	BTFSS		PIR1,SSPIF	
	GOTO		SENDBE
	BCF		PIR1,SSPIF

	goto		LOOP

end

ここまで

スレーブアドレス下記の部分です
MOVLW 0x40; ;0x40 is the SLAVE ADDRESS
LED表示データは下記の部分です
MOVLW 0x55 ;Port Data
プログラムの大まかな流れは
・I2Cの設定
・スタート・コンディションの開始
・スレーブアドレス送信 + WRITE モード
・ACK待ち
・LEDに表示するデータ送信
・ACK待ち
・ストップ・コンディションの開始
・LOOP

これらは全てI2Cの様々な解説に書かれていることです、こちらが参考に成ります

実際のCLK/DATの波形です、上がCLK  下がDAT
何故か同期はビデオだと良く見えました、なんで?
DSCN9754

DSCN9761



---記事制作中---

続きを読む


nice!(0)  コメント(0) 

I2Cを使う PIC16F876A PCF8574AN

お客様の案件で I2C を使う回路設計の必要が在りました
はい、過去形ですが実は没に成って仕舞った案件です
然し乍ら設計者のさがで一度始めると納得行くまでやって仕舞う
この悪い癖、何とかしなければならないのですが・・・・

でも、やって置けば其れだけ後々何かの役に立つ事も有るでしょう
という訳でドキュメントを残す意味で簡単な回路を組んでみました
まず、使用するICは・・・・

CPU が PIC16F876A  28pin Dip MICROCHIP社
日本語マニュアルが用意されているので製作記事が多いです
このPICにはMSSP(Master Synchronous Serial Port)が内蔵され
これがあることでI2Cが利用しやすいわけです
他のデバイスICと高速にシリアル通信をするためのモジュールで、SPIと
I2Cという2種類の動作モードで使うことができます。

F4671628-01

 RC3/SCK/SCLとRC4/SDI/SDA を使います。

bandicam 2018-12-10 11-31-00-992




IO Expander が PCF8574AN TEXAS社
16pin Dip で 8bit I/O です
回路を組む上で注意しなければならない事が有ります
それは出力で使うときの電流値です
Low出力は50mA流せますからリレー動きますよね
ところが
High出力はたったの4mA
LEDを点灯しようとしても昔のLEDだと暗くて話しに成りません
もう一つ押さえておきたいことは入力として使用した場合
OPEN = High だという事です、入力端子の空きピン処理は考慮に
入れて置かなければなりませんね
F5170249-01
pcf8574a-pin
またスレーブアドレスが僅かな型式違いで異なるので知らないと焦ります
驚くのは同じPCF8574Aでもスレーブアドレスが違うって・・・何?
購入するときは良く確認しなければなりません

bandicam 2018-12-07 00-02-28-302

bandicam 2018-12-10 09-41-15-897


どう考えてもおかしい、このスレーブアドレスで設計された記事を
全く見掛けません、マニュアルのダウンロードにもご注意下さい
仮にスレーブアドレス 0x20 とした場合、READ アドレスは 0x21
てなければならない、なのに A0 = High と成ったときに 0x21に
成って居ます、通常は LSBがHigh に成った場合スレーブアドレスは
0x02加算されなければなりません、なんで?
bandicam 2018-12-06 23-59-09-840




これらを使って LEDの点滅、詰まり Lチカ をやってみようと思います
この組み合わせにした理由ですが下記の様な条件が在ったからです・・・

・GPIOを使う
・LEDを50個ぐらい使う
・スイッチを20個ぐらい使う
・メンブレン・パネルに実装したい
・UART / I2C は可能
・SPI はダメ

・・・とこんな条件なのですがGPIOではピン数が限定的でとても
これだけの I/O はカバー仕切れません、その為に IO Expander を採用しました
I2Cにしたのは過去にハードウェアのみ経験しているからです

ところが採用したい I2C のソフトウェアに問題が在るのです
私はめっきりソフトウェアに弱いので皆様のように C言語でサクッ!! っと
プログラミング出来ません、なのでどうするか・・・・

・アセンブラ言語とする
・可能な限りネット検索してプログラムを引っぱってくる
・ブレッドボードを使う

・・・・こんな地味ぃな戦略なのです

2018/12/07(金)
ブレッドボードに仮組みしてみました

DSCN9756

写真で出来て居る事は、出力制御です、8bit 出力の確認をLEDで
行って居ます。
ここで判った事ですが上でも書いたように出力が Low / High で
電流値が大きく異なり、実際のLEDを接続するとこんな感じです。
この写真は出力Highの様子です、LEDは点いているのか消えているのか
良く視ないと判別がつきません
DSCN9752

一方でこの写真は出力Lowの様子で、これが正常ですよね。
DSCN9753

この様にバッファー・ドライバー無しで使うときは注意が必要です
トランジスタ・アレイ程度ならHighでドライブ出来ると思いますが
確認はマストですね。

話が少し逸れますが、使用している PIC KIT3 ですが壊した経緯が
有ります、原因はVDDに +24V が印加された為、PIC KIT3のあの
スケルトンで中が燃えているのが見えました、ひやぁーーー、でした
まぁ回路屋なので回路図をネット検索して探し、壊れて居そうな部品
をRSコンポーネンツで購入し直しました、ですがもう二度とあんな事は
嫌なのでプロテクタを中間に入れて使用しています。
DSCN9772

ツェナーダイオードの大きめのを入れ、抵抗が燃え切れる様にしました
序でなのでPIC KIT3が付いたままだと動かない事、って有りますよね
なので CLK / DAT をスイッチで切れる様にもして居ます、以来
気をつけているのでトラブルは無いですが、また在ると嫌だな。

DSCN9773

ブレッドボードで製作した回路ではプログラムに書かれたHEXデータ
1byte 分をLED表示するというものです
参考にと言うかコピーしたプログラムで引用元はこちらです

ソースコードの窓をこのブログに作りたいのですが面倒なので
後回しです、下記の通りです、折り返しが出ていますので
コピペの後、ご注意下さいこのままだとコンパイルエラーが出ます
因みにコンパイラは MICROCHIP社MPLABXIDEを使って居ます
ここから
;***************************************************************************************************************

;This software is provided in an “AS IS” condition,NO WARRANTIES in any form apply to this software.

; picmicrolab.com 5.31.2014
;***************************************************************************************************************
; PCF8574 I2C  8-bit IO expander interface with PIC16F876A;
;-------------------------------------------------------------------------------------;
		LIST 	P=PIC16F876A
		include	P16f876A.inc

 __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF & _HS_OSC & _LVP_OFF & _DEBUG_OFF & _CPD_OFF

	    org		0x00
reset:	goto start
	    org		0x04
start:

	bcf		STATUS, RP0
	bcf		STATUS, RP1
	movlw		0x28
	movwf		SSPCON
	bsf		STATUS, RP0
	BSF		SSPSTAT, SMP
	BCF		SSPSTAT, CKE
	CLRF		TRISB
	BSF		TRISC, 0x04	;SDA
	BSF		TRISC, 0x03	;SCL
	MOVLW		0x21
	MOVWF		SSPADD
LOOP:	
	BCF		STATUS,RP0
SENDB:
	BCF		PIR1,SSPIF	
;*********************START****************************************************
	BSF		STATUS, RP0	
	BSF		SSPCON2, SEN	; INITIATE START
	BCF		STATUS, RP0
SENDB2:
	BTFSS		PIR1, SSPIF	;START COMPLETED?YES SKIP NEXT
;*********************SLAVE ADDRESS-READ AFTER SETTING WORD ADDRESS*************

	GOTO		SENDB2
	BCF		PIR1, SSPIF	;YES,CLEAR FLAG
	MOVLW		0x40;		;0x40 is the  SLAVE ADDRESS   
	MOVWF		SSPBUF		;INITIATE SEND 
;SLAVE ADDRESS
SENDB3:
	BTFSS		PIR1, SSPIF	;SEND COMPLETED? YES,SKIP NEXT
	GOTO		SENDB3
	BCF		PIR1, SSPIF	;YES,CLEAR FLAG
	BSF		STATUS, RP0
	BTFSC		SSPCON2,ACKSTAT	;ACK RECEIVED FROM SLAVE?IF YES SKIP
	GOTO	 	SENDB5		;IF NO,END 

;*********************SEND Control Byte ****************************
	BCF		STATUS, RP0
	MOVLW		0x55		;Port Data		
	MOVWF		SSPBUF		;BEGIN TRANSMISSION
SENDB4:
	BTFSS		PIR1,SSPIF	;SEND COMPLETED?IF YES SKIP NEXT
	GOTO		SENDB4
	BCF		PIR1,SSPIF	;YES,CLEAR FLAG
	BSF		STATUS, RP0
	BTFSC		SSPCON2,ACKSTAT	;ACK RECEIVED FROM SLAVE?IF YES SKIP
	GOTO		SENDB5		;IF NO,END 
;*********************STOP****************************************************

    	BSF		STATUS,RP0
	BSF		SSPCON2,PEN
	BCF		STATUS,RP0
SENDBI:
	BTFSS		PIR1,SSPIF	
	GOTO		SENDBI
	BCF		PIR1,SSPIF
;*********************SEND NOACK TO END TRANSACTION*****************************
	BSF		STATUS,RP0
	BSF		SSPCON2,ACKDT	;SELECT NOACK
	BSF		SSPCON2,ACKEN	;INITIATE ACKNOWLEDGE SEQUENCE
	BCF		STATUS,RP0
SENDBC:
	BTFSS		PIR1,SSPIF	;ACK SEQUENCE COMPLEMENTED;IF YES SKIP
	GOTO		SENDBC	
	BCF		PIR1,SSPIF
;*********************	INITIATE STOP*******************************************
SENDB5:	
	BSF		STATUS,RP0
 	BSF		SSPCON2,PEN
	BCF		STATUS,RP0
SENDBE:	
	BTFSS		PIR1,SSPIF	
	GOTO		SENDBE
	BCF		PIR1,SSPIF

	goto		LOOP

end

ここまで

スレーブアドレス下記の部分です
MOVLW 0x40; ;0x40 is the SLAVE ADDRESS
LED表示データは下記の部分です
MOVLW 0x55 ;Port Data
プログラムの大まかな流れは
・I2Cの設定
・スタート・コンディションの開始
・スレーブアドレス送信 + WRITE モード
・ACK待ち
・LEDに表示するデータ送信
・ACK待ち
・ストップ・コンディションの開始
・LOOP

これらは全てI2Cの様々な解説に書かれていることです、こちらが参考に成ります

実際のCLK/DATの波形です、上がCLK  下がDAT
何故か同期はビデオだと良く見えました、なんで?
DSCN9754

DSCN9761



---記事制作中---

続きを読む


nice!(0)  コメント(0) 

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。