ワンチップマイコン・PICでC言語を使った学習報告5
位相パルサーの製作
2か月弱ぶりの報告になります。あまりお金にはならない仕事が結構やっていましたが、いつか良いこともあるのでは・・・と願いつつ、チマチマしていいた時間をぬって、前回のStudy 時にアナウンスしました「位相パルサー
」を製作してみました。しばらく「C言語」から離れているともうすっかり色々なことを忘れていて、情けない自分にため息が出ます。(〃´o`)=3 フゥ
今回はハードウェアとソフトウェアの両面で苦労しました。またPICの癖と言うものが少し分かったような気がしました!?
(℃_゚)...ン!?
なお今回も、アップした回路図などに間違いや無駄などがあるかもしれません。そのあたりは勉強中と言うことでご容赦願います。できればご指摘やアドバイスを頂ければ幸いです。(メールなど直接でもOKです)
お決まりの条文ですが、ここに紹介するものは私個人が勝手に製作したもので、万一製作されて事故などの被害にあわれても当方は一切責任を持ちませんので、ご理解とご了解のうえで、ご利用ください。できれば勉強用として利用して頂ければ幸いです。
なにせ私もまったくの素人ですから!
昔し勤めていた所の仕事の中で、商用周波数(50Hzとか60Hz)の1サイクルの指定した位相角に雷
を打ち込むと言う製品を作っていましたが、その位相角を見つける回路を外注に頼んでいました。内容は3桁サムホイールスイッチで設定し、同期パルスを発生する基板1枚のもので、価格がなんと20万円強はしていたと記憶しています。
基板回路を見ると、さすがにCPLDが使われていて、自分ながら良く出来ているなぁーと感心したものでした。材料はともかく殆どが「技術料」と言うのがその時の印象でした。
当時の性能はそれほど厳しくなかったので、これくらいの周波数であれば
PICで十分できるのでは・・・と思い立って今回の製作に踏み切ることにしました。ところが・・・結構厄介なことが次から次と・・・手をかけてから1週間は悩みました。
でも、ようやく1号機
として学習内容をアップできることになったのでご紹介させて頂きます。まだまだ改良の余地があり、次のバージョン計画が既にありますので、今回はソースの掲載は割愛させて頂きます。なお、詳細が知りたい方は、直接メール等を頂ければ、可能な範囲でご紹介できると思います。
まずは全容と詳細を写真で紹介します。汚い机の上での作業です。((^┰^))ゞ テヘヘ
↑ マイコンブレードボード部 ↑ スイッチ操作部 ↑ 正弦波→パルス変換回路 ↑ 液晶表示部
いつもの様に「ブレードボード」を使い、おおざっぱに組み上げます。回路図から見てもそれほど大げさなものはないと思いますが、今回上写真の右端にある「正弦波→パルス変換回路
」と言う、大そうなものがありますが、単純にコンパレータで波形整形しているだけなのですが、この整形回路がPICにとって厄介で、月並みの回路では低い周波数
の計測で誤った数値を示すことがあり、いくつか改良しました。
また最終的にはパルスのエッジが欲しかったのですが、立ち下がり部を拡大すると若干振動しているのが分かり、これがまた数値をでたらめにする原因で、この辺りも改良致しました。結局、微分波形をPICに送ることにしました。
トリガーですからこれで十分です。上の写真のスイッチ操作部に5個のスイッチがありますが使用するのは4個です。液晶表示部は、手持ちのものが2行/16文字
のもので、ちょっと物足らなかったのですが、仕方なくこれで行きました。ほんとは20文字くらい欲しかったです。(TmT)ウゥゥ・・・
動作説明
回路図を見て下さい。以前に製作した回路とほとんど同じものです。交流の位相ゼロを見つけるため、小型トランスで降圧し、半波整流した後、コンパレータIC
の非反転入力端子[+]に入れています。一方、反転入力端子[-]には1/100の電圧を入れて、ゼロクロス点を見つけています。コンパレータの出力は、立ち上がりと立ち下がり部のエッジに振動波があるため、積分用コンデンサを挿入して振動を抑えています。
PICの方へは、タイミングだけがあれば良いので、ゼロクロス点の信号を微分したパルスを入れています。この信号は外部割り込み端子(Port-B0)に入力しいます。ハードウェアのポイントはこれだけです。
あとは、いつもの様なスイッチと液晶表示部だけです。パルス出力は今のところ予定がないので、およそ25μSと言うパルス幅の信号をロジックレベルで出しているだけです。
今回ソフトウェアは慣れないC言語と言うこともあって苦労しました。
I/Oの初期化後、周波数の計測に3秒間ゲートを開けて、安定する周波数の3回目を取りこんで、周波数としています。つまり、このパルサーは固定された周波数の機器
でしか使えません。周波数が変わったら、後ほど説明する更新ボタンを押して、再読み込みさせます。
その後、前回設定した位相角値をEEPROM内から読み込み、CCPレジスタに送る、カウンタ値(16ビット)
を計算します。今回はCCP機能の一つにある、「コンペア」を使っています。ゼロクロス信号が入ってくる毎に、TMR1をスタートさせ、CCP_1のレジスタ値と比較して同じになれば、パルスを発生させています。
最も難しいのは、位相角
0度と360度のところです。二つは同じ位置なのですが、意味が違います。通常考えられるのは360度に達したらすぐに次のカウンタを動作させなければなりません。遅れてしまいますと大きな誤差になります。この考え方では限界があります(※実際にその通り製作したところ、
320度が限界でした)。そこで、工夫したのが位相を180度ずらすことです。(その詳細は今の段階では割愛させて頂きます。)
今回、ゼロクロス信号のパルスで回路にこだわったおかげで、動作周波数のレンジが10Hz〜200Hz
と言う範囲で動作できました。それでは動作状態を見ていきましょう!
電源を投入すると、周波数計測に入ります。その間(3秒)品名とバージョン、GucciTechのロゴを表示します。その後、計測した周波数と前回の位相角値を表示します。
周波数10Hz 位相角設定と波形
周波数50Hz 位相角設定と波形
なお、360度は0度と同じ波形をしていますので割愛致します。また波形の線が太いのは、50Hzと25μSの差で出力パルスが見えないためオシロスコープ側で ピークディテクトをかけて、見えるようにしたためです。
周波数200Hz 位相角設定と波形
位相角の位置は、上写真の押釦スイッチで、左の赤色ボタンから「3桁目の数値変更」、「2桁目の数値変更
」、「1桁目の数値変更」、次の黒は未使用で、最後の右端の押釦スイッチが「.編集」ボタンです。最初に編集ボタンを押します。すると1桁目の数値がブリンク
します。変えたい桁のボタンを押すたびにイクリメントします。ちょっと凝ったのが、絶対に360以上、あがらないよう工夫しています。例えば3桁目が0か1か2の時は、2桁目は0〜9まで変化しますが、3桁目が3の時は2桁目は6までしか上がりません。また逆に、2桁目が7〜9の時、3桁目は2までしか上がらないと言う工夫をしています。
設定が終わると最後に、「編集」ボタンを押します。すると本器は改めて周波数を読みに行き、位相角をEEPROMに保存したのち、設定を反映して出力を出します。
今回は結構長く時間がかかってしまいました。その主な原因はハードウェアの無恥さにありました。例えば、内臓のEEPROMにデータを書き残す作業は、アセンブラでは何回か実績があるのですが、C言語で書くのは初めてでした。
文献など見ますとかなり簡単な命令で実現しています。その通り記述してICD-U40でデバッグしたところ、書き込む瞬間でブレークポイントかけた所、書き込めないことに悩んでしまいました。急遽、EEPROMだけのプログラムで検証して初めて「書きこむところでブレークポイントを置いてはいけない
」ことが分かりました。それに加え、うまく書き込めたかの検証で、電源のON/OFFをさせた所、データが化ける現象に悩まされました。いろいろ調べた所(とくに文献2が役に立った!)、リセット回路に問題があり、CRだけではまずいことが判明。対処法として、TO92型の
専用のリセットICを使いました。たいした値段がしないので、はじめから使えばよかったと後悔しています。(w_−; ウゥ・・
続いて悩まされたのが、位相検出信号です。「波形を最後まで、拡大して良く見る!
」・・・と言う当たり前のことをしなかったため、ソフトウェアでいくら頑張っても、つじつまの合わないことが続きました。
唯一、「イイージャン!」と自分で絶賛したのが、0度と360度の切れ目をどうやって計測するか?例えば200Hz
は5mSです。それの1/360は約14μSです。仮に位相角を359と設定された時、次のスタートである0度までにはたった14μS
しかありません・・・・割と早めにひらめきました。ただ今回はC言語の便利さを思い知らされたのが、位相角値の計算でした。32ビットクラスの計算をアセンブラで書くと大変なものになりますがさすがに
C言語!やめられませんね!( ゚ー゚)( 。_。)ウン♪
私にとっては結構大作でした。これを機に、もう少し難度を高めたものにチャレンジしたいと思います。今回の位相パルサーは次のバージョンを計画していて、二つの位相角を設定して、二つの出力を出そうと言うものです。さらに周波数も高くしたいと考えております。それにしても デジタルオシロスコープが欲しい!狙っているものは、AEMC社の4ch-12bit,100MHzのデジタルオシロでなんと100万円弱ですが・・・