Comments
Description
Transcript
PICプロセッサを用いたラジコン操作型戦車の設計と製作
卒 業 研 究 報 告 題 目 PIC プロセッサを用いたラジコン操作型戦車の 設計と製作 指 導 教 員 綿森 道夫 助教授 報 告 者 学籍番号:1050226 氏名: 島田 尚彦 平成 17年 2月 22日 高知工科大学 電子・光システム工学科 目次 第1章 ― 目的 ― ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 3 第2章 ― PIC について ― (2−1)PIC そのものについて ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 4 (2−2)一般的な性質・性能など ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 5 (2−3)PIC の種類 ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 6 (2−4)PIC の開発環境 ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 7 (2−5)ROM ライタの写真 ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 8 (2−6)MPLAB について ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 9 (2−7)PIC16F628 について ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 10 (2−8)PIC16F876 について ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 12 第3章 ― 電子ルーレットの設計と製作 ― (3−1)概略・外観 ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 14 (3−2)回路図 ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 15 (3−3)フローチャート[スタート部分] ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 16 (3−4)フローチャート[回転部分] ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 17 (3−5)フローチャート[ストップ部分] ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 18 (3−11)タイマカウントについてⅠ ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 19 (3−12)タイマカウントについてⅡ ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 20 (3−13)タイマカウントについてⅢ ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 21 第4章 ― 汎用ロジック IC を用いたワンボード CPU の製作 ― (4−1)概略・回路図 ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 22 (4−2)外観 ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 24 (4−3)動作確認 ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 25 -1- 第5章 ― AM 無線方式リモコン送信部の設計と製作 ― (5−1)概略・回路図 ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ (5−2)外観 ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ (5−3)AM 送信モジュールについて ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ (5−4)AM 通信について ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ (5−5)データ送信方法 ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ (5−6)フローチャート[送信部分] ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 26 27 28 29 30 31 第6章 ― AM 無線方式リモコン戦車の設計と製作 ― (6−1)概略・回路図 ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 32 (6−2)外観 ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 33 (6−3)AM 受信モジュールについて ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 34 (6−4)受信部について ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 36 (6−5)フルブリッジモータ制御回路 ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 37 (6−6)PWM モータ速度可変回路 ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 39 (6−7)ダイナミック点灯表示回路 ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 40 (6−8)車速検出回路 ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 41 (6−9)衝突回復回路 ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 43 (6−10)フローチャート[受信部分] ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 44 (6−11)フローチャート[速度表示部分] ・・・・・・・・・・・・・・・・・・・・・・・・・・ 45 (6−12)フローチャート[レバー処理部] ・・・・・・・・・・・・・・・・・・・・・・・・・・・ 46 (6−13)動作確認 ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 47 第7章 ― まとめ・感想 ― ― 謝辞 ― ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 50 ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 51 ― 参考文献 ― ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 52 ― 付録(プログラムリスト) ― (7−1)電子ルーレットのプログラム ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 53 (7−2)リモコン送信部のプログラム ・・・・・・・・・・・・・・・・・・・・・・・・・・・・ 62 (7−3)リモコン戦車受信部のプログラム ・・・・・・・・・・・・・・・・・・・・・・・・ 70 -2- 第1章 ― 目的 ― 本研究で使用しているマイクロコンピュータは、私たちの身近な所で大いに活躍し ています。例えば、エアコン・冷蔵庫・テレビ・炊飯器などの「民生機器」、エンジン・ブ レーキ・ABS・サスペンション・エアバックなどの「自動車機器」、マウス・キーボード・ FAX・プリンタなどの「OA 機器」、携帯電話・固定電話・モデムなどの「通信機器」、モ ータ制御・ロボット制御・煙検出器などの「産業機器」といったものが挙げられます。 その中でも、コンピュータの周辺に接続される周辺機器の接続部分を制御するた めに開発された「PIC(Peripheral Interface Controller)」というプロセッサを使用して、 AM 無線方式リモコン戦車と AM 無線方式リモコン送信部の設計・製作とプログラム製 作を行うことにより、この分野の知識や技術などを自分なり吸収することを目的として 掲げています。 -3- 第2章 ― PIC プロセッサについて ― (2−1)PIC とは PIC(Peripheral Interface Controller)とは、米国のマイクロチップテクノロジー社が開 発したマイクロコンピュータで、マイクロコントローラとも呼ばれている。現在出荷台数 が世界で第2位を誇るマイコンシリーズである。マイクロチップテクノロジー社は「ゼネ ラルインスツルメンツ」社から分離独立した会社である。PIC 自体は本国で本社のある アリゾナ州とタイ王国にある自社工場で生産され、全世界に提供されています。 -4- (2−2)一般的な性質・性能など PIC の主な特徴として、 [1]先程も述べたが、8ビットのワンチップマイコン [2]RISC チップで高速動作 [3]命令数自体が「35個」しかない [4]小型デバイスのラインアップ [5]低電圧で動作可能 [6]ワンタイムデバイスが主流 [7]高出力 I/O(入出力)ポート [8]高いハードソフト互換性 [9]ローコスト(いわゆる安い) といったものが挙げられます。 -5- (2−3)PIC の種類 PIC には次のような3つのシリーズがあります。 [1]ベースラインシリーズ 命令が12ビット幅の最初に開発されたマイコンで、入出力ピンとタイマ機能 だけを持った単機能のシリーズで、今でも使われているが PIC の世代として は古くなっています。 例;12C5**、16C5*など 代表的なもの;12C508A、16C54B、16C57C など [2]ミッドレンジシリーズ 命令が14ビット幅のマイコンで、最もよく使われているシリーズです。A/D 変 換機能やシリアルポートなどの多機能を内蔵するものであって、フラッシュメ モリタイプのものもあることから種類も豊富にあります。 例;16F8**、16C62*、16C7**など 代表的なもの;16F84A、16F62X、16C711など [3]ハイエイドシリーズ 16ビット幅のマイコンで、文字どおり高機能なシリーズです。しかし、まだ種 類が少なく使いこなすのが困難です。 例;17C***、18C***など 代表的なもの;17C42A、17C756など これらの中から、全体として必要なピン数やメモリの大きさなどを中心として、あとは A/D 変換やシリアル通信など専用機能の有無、入手しやすさ・価格などを考慮して使 用するマイコンを決めます。 -6- (2−4)PIC の開発環境 PIC を使用してプログラムを開発するには、次のような環境が必要となってきます。 <ハードウェア関係> [1]パーソナルコンピュータ 当然のことながら必要となってきます。主にプログラムの作成・デバ ック・書き込みに使います。一応「MS-DOS」ベースと「Windows」ベー スのどちらでも可能なのですが、「Windows」ベースの方がはるかに 効率の良い開発ができるので、今回はこちら側で開発しました。 [2]PIC ライタ(書き込み器) パソコンと接続して、プログラムを直接 PIC に書き込むのに必要とな ります。今回は(株)秋月電子通商がキットとして売っている 「AKI-PIC プログラマーキット VER3.5」に「スパーフェニックス Ver4,0」を付 けて、書き込みとしました。(次ページの図 1 に外観を) [3]ターゲットマシン 実際に動作させるハードウェアです。 <ソフトウェア関係> [1]エディタ プログラムを書くためのツールで、テキストファイルで保存できれば 何でも使えます。今回は Windows の「メモ帳」と「MPLAB(別項参照・ 次ページに使用図あり)」を使って書きました。 [2]アセンブラ・デバッガ いずれもフリーソフトとしてマイクロチップテクノロジー社のホームペ ージで提供しています。今回は「MPLAB(別項参照・次ページに使用 図あり)」を使用しました。 [3]PIC ライタプログラム パソコン上で動作させてライタを制御し、PIC にプログラムを書き込 むために使うもので、たいていは市販の PIC ライタに添付されていま す。今回は PIC ライタに添付されていたのを使用しました。 -7- (2−5)ROM ライタの写真 図1 ROM ライタ 図 2 MPLAB を使用中のパソコン画面 -8- (2−6)MPLAB について MPLAB は、IDE(Integrated Development Environment)ともいわれ、Windows ベー スの統合開発環境を提供するプログラムで、マイクロチップテクノロジー社提供のフリ ーソフトです。 MPLAB には、次のようなプログラム群を含んでいます。 [1]MPLAB Project Manager 環境を常に統合管理してくれるので、ソース・オブジェクトなどを一括 して扱えます。 [2]MPLAB Editor プログラムを書くためのエディタで、テンプレート機能など楽に書ける よう工夫されています。しかし、日本語入力はできません。 [3]MPASM Universal Assembler 書いたプログラムをアセンブラし、オブジェクトを作成します。 [4]MPLAB-SIM Software Simulator プログラムをデバックするためのシミュレータで、ブレークポイントな ど多くの機能を含んでいます。 [5]PICMASTER Emulator PICMASTER というハードシミュレータ、ROM ライタの制御 MPLAB の入手法としては、一番手軽なのはマイクロチップテクノロジー社のホーム ページからダウンロードできます。もちろんフリーソフトなので、無料でダウンロードで きます。もしそれができないようなら、手ごろな参考書に付属されているのをインスト ールすると良いでしょう。 -9- (2−7)PIC16F628 について PIC16F628 はシリーズでいえば「ミッドレンジシリーズ」に属していて、内部 RC(発振) を持つ・入出力に設定できるポートが増えた・プログラムメモリが倍増した・動作電圧 幅が狭い・タイマ1&2と CCP 機能を持つ・割り込み判定数が増えたなどの違いがあ ります。 PIC16F628 の外観を下記に、次ページにピンの状態を記します。 図3 16F628 の外観 - 10 - 表1 16F628 のピン配置 PIC16F628 形態 1 形態 2 形態 3 状態 1 番ピン RA2 AN3 VREF 入出力 2 番ピン RA3 AN4 CMP1 入出力 3 番ピン RA4 TOCK1 CMP2 入出力 4 番ピン RA5 MCLR THV 入力 5 番ピン Vss 6 番ピン RB0 INT 入出力 7 番ピン RB1 RX 入出力 8 番ピン RB2 TX 入出力 9 番ピン RB3 CCP1 入出力 10 番ピン RB4 PGM 入出力 11 番ピン RB5 12 番ピン RB6 T1OSO 13 番ピン RB7 T1OSI 14 番ピン VDD 15 番ピン RA6 OSC2 CLKOUT 出力 16 番ピン RA7 OSC1 CLKIN 入力 17 番ピン RA0 AN0 入出力 18 番ピン RA1 AN1 入出力 入力 入出力 T1CKI 入出力 入出力 入力 - 11 - (2−8)PIC16F876 ついて PIC16F876 はシリーズでいえば「ミッドレンジシリーズ」に属していて、PIC16F628 と 比べても高性能となっていて、入出力に設定できるポートが増えた(ピン数自体が増 えた)・プログラムメモリが 4K もある・A/D 変換ができる・専用の RC(発振)ポートがあ る・アースが2ヶ所ある・割り込み判定数がさらに増えたなどの違いがあります。 PIC16F876 外観を下記に、ピンの状態を次ページに記します。 図4 PIC16F876 の外観 - 12 - 表2 PIC16F876 ピン配置 PIC16F876 形態 1 形態 2 形態 3 状態 1 番ピン MCLR VPP THV 入力 2 番ピン RA0 AN0 入出力 3 番ピン RA1 AN1 入出力 4 番ピン RA2 AN2 VREF- 入出力 5 番ピン RA3 AN3 VREF+ 入出力 6 番ピン RA4 T0CKI 7 番ピン RA5 AN4 8 番ピン Vss 9 番ピン OSC1 CLKIN 入力 10 番ピン OSC2 CLKOUT 出力 11 番ピン RC0 T1OSO 入出力 12 番ピン RC1 T1OSI 13 番ピン RC2 CCP1 14 番ピン RC3 SCK SCL 入出力 15 番ピン RC4 SDI SDA 入出力 16 番ピン RC5 SDO 17 番ピン RC6 TX CK 入出力 18 番ピン RC7 RX DT 入出力 19 番ピン Vss 入力 20 番ピン VDD 入力 21 番ピン RB0 22 番ピン RB1 入出力 23 番ピン RB2 入出力 24 番ピン RB3 25 番ピン RB4 入出力 26 番ピン RB5 入出力 27 番ピン RB6 PGC 入出力 28 番ピン RB7 PGD 入出力 入出力 SS 入出力 入力 INT PGM - 13 - CCP2 入出力 入出力 入出力 入出力 入出力 第3章 ― 電子ルーレットの設計と製作 ― (3−1)概略・外観 ここで設計・製作した電子ルーレットは、START スイッチを押すと 12個の LED(発光 ダイオード)でできたルーレットが、光りながら高速で回転し始め、同時にブザーも鳴り 始めます。その後、STOP スイッチを押し、だんだん LED の点灯スピードが減速しなが ら、やがては 1 箇所だけが点灯して、ブザーもセットで停止する動作をします。 下記にこの電子ルーレットの外観を、次ページに回路図を示します。 図 5 自作した電子ルーレット - 14 - (3−2)回路図 10k SW START + - BUZZER LED2 10k LED1 U1 SW STOP LED5 LED6 RA2 RA3 RA4 MCLR GND RB0 RB1 RB2 RB3 RA1 RA0 RA7 RA6 Vcc RB7 RB6 RB5 RB4 LED4 LED3 LED12 LED11 PIC16F628A LED7 LED10 LED8 LED9 68 図 6 電子ルーレットの回路図 - 15 - 3V + SW (3−3)フローチャート[スタート部分] 電源 ON 初期化 VALUE 値を +1 入出力ピンの設定 LED を点灯 スタートが 押されたか NO あり YES スタートキー 0.3 秒待ち バグは なし 10m 秒待ち 処理へ ルーレットゲーム開始 図7 電子ルーレットのフローチャート(スタート部分) このスタート部分では、電源が入った後に、初期化処理と入出力ポートの処理を行 います。この後は、スタートスイッチをチェックし、「押されてなければ」、隣の LED を 0.3 秒間光らせながら、VALUE 値を+1 しています。このループを繰り返すことで、低速で ルーレットが回転しているように見えます。 また、スタートスイッチが「押されていれば」、10m 秒の「チャッタリング処理」を行い ます。「チャッタリング処理」とは、スイッチが ON になるときに、安定した値を取るため の待ち時間処理のことです。なぜ必要になるかというと、今回の 1 命令は「1.0μ秒」で 行っているので、コンピュータからすればチャッタリング(安定した値を取るため)の時 間はとても長い時間となり、非常に不安定な動作を起こしてしまうので、待ち時間が 必要となってきます。「チャッタリング処理」が終わり、バグが発生してなければ、ルー レットゲームの開始となります。 - 16 - (3−4)フローチャート[回転部分] LED を回転 スタート制御より ブザー VALUE 値が 0 か LED を回転 ストップが押されたか YES NO YES ストップ制御へ VALUE 値をー1 NO 10m 秒待ち VALUE 値で 待ち時間を制御 VALUE 値を+1 図 8 電子ルーレットのフローチャート(回転部分) ルーレットゲームが開始されたなら、ブザーを ON にすることで鳴り始めます。また、 ストップスイッチが「押されていない状態」なら、10m 秒の間隔で次々と LED がシフトし ながら点灯していきます。 ここでストップスイッチが押されると、停止処理に進みます。停止処理では、ランダ ムに膨れ上がった VALUE 値が 0 になるまで回転し続けますが、VALUE 値の減少とと もに待ち時間が増加するので、回転がどんどんとスローになっていきます。VALUE 値 が 0 になれば、ストップ制御を行います。 - 17 - (3−5)フローチャート[ストップ部分] 次のゲームを開始 停止処理より ルーレットを停止 LED を一箇所だけ点灯 YES スタートが押されたか NO VALUE 値を+1 YES スタートが押されたか 0.3 秒待ち NO ストップが押されたか NO YES 回転方向を逆転 LED の位置を シフトして点灯 図 9 電子ルーレットのフローチャート(ストップ部分) 停止処理により VALUE 値が 0 になれば、ルーレットがストップし、止まった位置の LED が点灯し続けることとなります。そこでスタートスイッチが押されれば、再び LED が回転し始めて、ルーレットが再開されます。もし、押されてないのなら次にストップス イッチのチェックをします。 押されてなければ、スタート&ストップスイッチのチェックを繰り返し続けますが、こ こで押されれば LED の回転方向を逆転します(これの詳しい説明は次ページでしま す)。 そして再び、「スタート制御」のルーチンに戻ります。 ここまでが、この電子ルーレットの全体の流れです。この後は、このプログラムの目 玉である「タイマ1割り込み」について詳しく説明します。また、これの全体のプログラ ムリストは巻末の「CD-R」の中に収録しています。また、付録には回路図を改めてコ ピーしたものを付けておきます。 - 18 - (3−11)タイマ1割り込みについてⅠ 今回の電子ルーレットにおいては、サブルーチンを利用し作った時間と、TMR1のオ ーバーフローを利用した時間と、TMR1の割り込みを利用して作った時間の 3 種類の プログラムを作りました。まずは、サブルーチンを利用し作った時間のプログラムを下 記に示します。 リスト1 サブルーチンを利用した時間のプログラム ;*** 0.4msec Timer Subroutine **** tim04 movlw h’64’ movwf cnt1 timlp1 nop decfsz cnt1,f goto timlp1 return ;1 ;1+1=2 ;1+1+2=4 ;2+4*100-1=401 ;401+2=403*1.0usec=0.403msec このように、「4.0MHZ.」のクロックなら,一命令は「1.0μ秒」となり、このサブルーチン を抜け出すのに「400 ステップ」必要なら、 1.0*10^-6*400=0.4*10^-3=0.4m 秒 といった具合に、時間を作ることができるようになります。この方法は自分なりに非常 に使いやすい方法と思っているので、これからの作品において大いに利用しています。 - 19 - (3−12)タイマ1割り込みについてⅡ 次に利用したのが、「TMR1オーバーフロー」で時間を作る方法です。これは先ほど述 べたサブルーチンを利用した方法に近いやりかたをしています。では、下記にプログ ラムを示します。 リスト2 TMR1オーバーフローを利用した時間 ;**** 150msec Timer Subroutine **** tim150 bsf status,rp0 ;プリスケーラの設定 movf option_reg,w movlw h’87’ movwf option_reg bcf status,rp0 tm movlw h’3c’ ;50msec の作成 movwf tmr1 ;256×196≒50msec tm1 movf tmr1,w btfss intcon,7 goto tm1 return 今回の方法は先ほど述べたサブルーチンを利用したもの代わりに「TMR1」を使用し ている様なものです。ここでリスト中にある「プリスケーラ」について説明します。 それは、「分周率」といったもので、1:2、1:4、1:8、1:16、1:32、1:64、1:128、1:256 とい った具合に分周でき、プリスケーラを利用しなければ「TMR1」は「256」カウントでオー バーフローしてしまいます。そこでプリスケーラを利用し、1:256 に分周すれば、 「256*256=65536」となり一命令は「1.0μ秒」なので、オーバーフローまでには「約 65m 秒」必要となります。なお、「プリスケーラ」は「OPTIN-RWG」にて設定することができま す。 これを利用して時間を作ったのが上のプログラムです。 - 20 - (3−13)タイマ1割り込みについてⅢ 最後に時間を作るのに利用したのが「TMR1割り込み」です。この方法は、先ほど の「TMR1のオーバ−フロー」でフラグチェックをするのでなく、割り込み発生させて時 間を作る方法です。下記に割り込みプログラムを示します。 リスト3 「TMR1割り込み」を利用した時間 ;****TMR0 設定********** movlw h’30 movwf ccpr1h movlw h’d4’ movwf ccpr1l bcf intcon,7 bsf t1con,tmr1on nop bsf intcon,7 jump btfss chk,2 goto jump btfss chk,1 ;**** 割り込みルーチン ccp1int movwf movf movwf incf movf movwf swapf swapf retfie **** wsave status,w stsave chk,f stsave,w status wsavv,f wreg,w 上のリストで左側は「TMR1割り込み」を利用しているところから一部分を取り出し てきました。 これは、単純に割り込みが発生したら、割り込みプログラム内であるレジスタ(ここで は CHK)を+1しているだけで、メインのルーチンでは何回割り込みが発生したか調 べているだけです。これだけでも、立派に時間を作ることができます。 - 21 - 第4章 ― 汎用ロジック IC を用いたワンボード CPU の製作 ― (4−1)概略・回路図 最初に汎用ロジックICを用いてワンボードCPUを製作します。このワンボードCPU は、単行本『CPUの作り方』(渡波郁著 朝日コミュニケーションズ刊)に掲載されてい たものであるが、回路規模が比較的大きく、ユニバーサル基板に製作することによっ て、部品の配置ならびに配線の訓練になると考え、実際に作ってみました。 ここで製作したワンボード CPU は、徹底的に単純化した CPU で、13個の汎用ロジ ック IC とハンドアセンブラを用いて LED を光らせるというものです。 下記に回路図を、次ページには外観を示します。 CLOCK RESET A B CLR LOAD ENT ENP CK A B C D 1G 1C0 1C1 1C2 1C3 2G 2C0 2C1 2C2 2C3 1Y 2Y B1 B2 B3 B4 1 2 3 4 C4 +5V CO 74HC283 74HC153 CO PR CK D CLR A B QA QB QC QD 1G 1C0 1C1 1C2 1C3 2G 2C0 2C1 2C2 2C3 74HC161 CLR LOAD ENT ENP CK A B C D A1 A2 A3 A4 CO 1Y 2Y +5V 74HC10 +5V +5V 74HC10 74HC10 74LHC32 CO QA QB QC QD CO D D D D D D D D QA QB QC QD A A A A 74HC32 74HC161 CLR LOAD ENT ENP CK A B C D 74HC32 74HC153 QA QB QC QD 74HC161 CLR LOAD ENT ENP CK A B C D Q1 Q2 74HC74 74HC32 1k 1k 1k 1k 74HC161 1k 1k 1k 1k DIPsw 4 3 21 +5V 5678 図10 CPU の回路図 - 22 - +5V 10k DIPSW 10k DIPSW DIPSW DIPSW DIPSW DIPSW DIPSW DIPSW 87 65 4 3 21 87 6 5 4 3 2 1 87 6 54 3 21 87 65 4 3 2 1 87 6 5 4 3 2 1 87 6 5 4 3 21 87 6 5 4 3 2 1 87 6 54 32 1 910111213141516 910111213141516 910111213141516 910111213141516 910111213141516 910111213141516 910111213141516 910111213141516 10k 10k 10k 10k 10k 10k U11 G1 G2 A1 A2 A3 A4 A5 A6 A7 A8 D0 D1 D2 D3 D4 D5 D6 D7 74HC540 DIPSW DIPSW DIPSW DIPSW DIPSW DIPSW DIPSW DIPSW 87 6 5 4 3 2 1 87 6 54 32 1 87 6 5 4 3 21 87 65 4 3 2 1 87 6 5 4 3 2 1 87 6 54 32 1 87 6 5 4 3 21 87 65 4 3 2 1 910111213141516 910111213141516 910111213141516 910111213141516 910111213141516 910111213141516 910111213141516 910111213141516 74HC154 A0 A1 A2 A3 E0 E1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 図11 ROM の回路図 +5V 1k 10k 100k 100 74HC14 + Manual Clock SW 10uF 10uF S1 3.3k Manual C Nomal 33k +5V 100k 100 74HC14 74HC14 1k 10k 100k R 74HC14 SW + Reset 74HC14 10uF 図12 クロック&リセット回路図 - 23 - D0 D1 D2 D3 D4 D5 D6 D7 (4−2)外観 図13 CPU 本体の外観 図14 クロック&リセット回路の外観 - 24 - (4−3)動作確認 図15 ハンドアセンブラによる LED 点灯の動作確認 - 25 - 第5章 ― AM 無線方式リモコンの設計と製作 ― (5−1)概略・回路図 PIC16F628と AM 送信モジュールを用いて、AM 無線方式リモコンの設計・製作を しました。リモコンには左右のレバーがあり、上下させることによって進む方向のデー タを受信ロボットに送信し、何も操作していないときも、停止状態のデータを送信し続 けます。 下記に回路図を、次ページには外観を示します。 3V + SW Vcc GND ANT1 shiro aka kiiro ao RA2 RA3 RA4 RA5 GND RB0 RB1 RB2 RB3 RA1 RA0 OSC1 OSC2 Vcc RB7 RB6 RB5 RB4 DATA ANT AM-RT5 4.0MHz 図16 AM 無線リモコン送信部の回路図 (5−2)外観 - 26 - 図17 AM 無線リモコンの外観 図18 リモコン内部の外観 (5−3)AM 送信モジュールについて - 27 - 今回使用した AM 送信モジュール(AM-RT5-315)は、英国アールエフソリューショ ンズ社製の微弱電波に適した送信モジュールです。そのピン配置と仕様を下記に、次 ページに外観を示します。 表7 ピン配置 ピン番号 信号名 備考 1 EA 外部アンテナへ接続 2 IN デジタル信号入力 3,4,5 NC ピン端子なし 6 GND 電源アース 7 Vcc +電源を供給 表8 仕様 項目 Min Typ Max 単位 電源電圧 2 5 14 Vdc 電源電流 - 4 - mA 送信周波数 303.8 - 433.92 MHz 送信出力 - 0 - -dBm スプリアス - -30 - -dBc 入力信号 2 - Vcc V 送信速度 - - 4 KHz 使用温度 -25 - +80 ℃ 図19 AM 送信モジュール - 28 - (5−4)AM 通信について 今回の赤外線通信では、テレビなどのリモコンの通信方法を利用した。送データフォ ーマットは以下のようになっている。 フレーム データ部 データ部 リーダー部 (1 送目) (2 送目) 16bit 40bit 16bit 8bit 図20 フレームフォーマットの構成 0 0 0 0 0 0 0 0 8bit 固定 図21 フレームリーダ部の構成 1 C2 C1 C0 0 1 D4 D3 D2 D1 D0 スタート デバイスコード スイッチコード ストップシーケンス セパレータ 図22 データ部の構成 - 29 - 1 0 0 0 0 (5−5)データ送信方法 送信するデータ全体は図 5.1 のようになっている。まず、8bit のフレームリーダ部を 送信し、そして 16bit のデータ部を 2 回送信する。 リーダー部は図 5.2 のように 0 だけを送信する。これは、連続してデータを送信した ときに、一定の休憩の間隔を確保するためである。 そして、データ部は図 5.3 のようになっている。まず、データの始まりを表す「1」のス タートビットがある。 次に 3bit のデバイスコードが続く。これは 1 つのリモコンが制御する対象が複数あ る場合などで、受信側でこのデバイスコードだけを区別すれば、送信機のスイッチな どでデバイスコードを切り替えることにより、1 つの送信機で複数の異なる対象機器を 制御できる。 次は、別のデータの始まりを表す 2bit のセパレータが続く。これは、固定のデータで ある。 そして、5bit のスイッチコードが続く。5bit なので 32 個のスイッチの区別ができること になる。 最後にストップシーケンスでデータは終わる。 この 16bit の同じデータを 2 回送信する。そうすることにより、受信で 2 回のデータを 照合して、同じであれば正常に受信したと判断し、データにあった処理をするが、同じ でなければエラーとみなす。通信誤りのチェックの信頼性がますのである。このことを 2 連送照合という。 - 30 - (5−6)フローチャート[送信部分] 赤外線リモコンはキーが押されるまで、ずっとキー入力待ちをする。キーが押されれ ば、そのキーに沿った処理をして、0.3 秒待つ。そしてまた始めの処理に戻る。ずっと キーを押されると 0.3 秒毎にキーのデータが送信されることになる。 スタート 初期化 スイッチ入力 チェック No 入力 ありか? Yes キースキャン リーダー部送信 データ部送信 データ部送信 0.3 秒待ち 図23 フローチャート[送信部分] - 31 - 第6章 ― AM 無線方式リモコン戦車の設計と製作 ― (6−1)概略・回路図 PIC16F628・PIC16F876と AM 受信モジュールを用いて、AM 無線方式リモコン戦 車の設計・製作をしました。特徴としては、受信データを LED に表示、車速検出、衝突 回復などの機能をつけました。下記に回路図を、次ページに外観を示します。 3V + SW ANT1 Vcc GND ANT kSW rSW fSW GND RA1 RA0 OSC1 OSC2 Vcc RB7 RB6 RB5 RB4 PNP 2SA1015 4.3k 4.3k Vcc GND Vcc TEST DATA Vcc PNP 2SA1015 4.0MHz Vin C+ SEL CSHT Vout GND OK PIC16F628 10uF 120 10k 40% + 10uF MCP1252 10uF 0.1uF 10MHz 130 130 150 130 V+ V+ 130 RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 Vcc GND RC7 RC6 RC5 RC4 Vcc 130 30k 120 120 120 120 B-1000SR 5k 5k 5k 5k G1 D1 G2 D2 G3 D3 G4 D4 GNDVcc RPR220 Vcc 130 130 abcdefg. abcdefg. MCLR RA0 RA1 RA2 RA3 RA4 RA5 GND OSC1 OSC2 RC0 RC1 RC2 RC3 PIC16F876 150 RPR220 120 0.1uF AM-HRR3 + RA2 RA3 RA4 RA5 GND RB0 RB1 RB2 RB3 10k 10k 120 + 0.1uF 10k 120 120 120 CN1 MP4212 30k GND G1 D1 G2 D2 G3 D3 G4 D4 GNDVcc 74HC04 0.1uF GND 74HC00 MP4212 0.1uF 図24 リモコン戦車受信部の回路図 - 32 - CN2 (6−2)外観 図25 リモコン戦車の外観 - 33 - (6−3)AM 受信モジュールについて 今回使用した AM 受信モジュール(AM-HRR3-315)は、英国アールエフソリューシ ョンズ社製の微弱電波に適した受信モジュールです。そのピン配置と仕様を下記に、 次ページに外観を示します。 表9 ピン配置 ピン番号 信号名 備考 1 RF+Vcc RF+電源を供給 2 RF GND RF 電源アース 3 DATA IN 外部アンテナへ接続 4,5,6 NC ピン端子なし 7 RF GND RF 電源アース 8,9 NC ピン端子なし 10 AF+Vcc AF+電源を供給 11 AF GND RF 電源アース 12 AF+Vcc AF+電源を供給 13 TEST POINT テストポイント 14 DATA OUT TTL データ出力 15 AF+Vcc AF+電源を供給 表10 仕様 項目 Min Typ Max 単位 電源電圧 4.5 5 5.5 Vdc 電源電流 - 2.5 3 mA 受信周波数 200 - 450 MHz 受信感度 - -105 - -dBm 出力信号 - 3.7 - V 通信速度 - - 3 KHz 使用温度 -25 - +85 ℃ - 34 - 図26 AM 受信モジュール - 35 - (6−4)受信部について 受信回路の電源が3V なのに対して、AM 受信モジュールには4.5∼5.5V の電源が 必要となります。そこで、チャージポンプ方式の DC/DC コンバータ(MCP1252)を用い て、5V 前後まで電圧を上げます。このため MSOP の表面実装により、本体回路に組 み込みます。その回路図と外観を下記に示します。 5V 10uF Vin C+ SEL CSHT Vout GND OK MCP1252 + 10uF + + 3V 10uF 図27 MCP1252 で昇圧する回路図 図28 昇圧回路の外観 - 36 - 0.1uF (6−5)フルブリッジモータ制御回路 単一電源でモータに加える電圧の向きを変えられる回路として考案されたのが、フ ルブリッジ回路です。構成回路は、下記のようになっています。 このフルブリッジ回路の動作の仕組みは、Q1 と Q4 のトランジスタだけを同時に ON にすると、モータへの電流は左から右へ流れ、モータは正転(逆転)します。Q2 と Q3 だけを ON にすると、電流は右から左へ流れ、モータは逆転(正転)します。Q3 と Q4 だけを同時に ON にすると、モータのコイルをショートすることになり、ブレーキをかけ る動作となります。 この回路の動作では、Q1 と Q3、あるいは Q2 と Q4 を同時に ON にすると、トランジ スタで電源をショートすることになるので、大電流がトランジスタに流れ、トランジスタ が壊れてしまう恐れがあります。したがって、回転方向を切り替えるときには、短時間 でよいので、一旦全部 OFF の停止状態にしてから切り替える必要があります。 表11 フルブリッジ回路の動作モード Q1 Q2 Q3 Q4 モーター制御 OFF OFF OFF OFF 停止 ON OFF OFF ON 正転(逆転) OFF ON ON OFF 逆転(正転) OFF OFF ON ON ブレーキ 図29 フルブリッジ回路 - 37 - 今回使用したモータドライバー(MP4212)の特徴は、出力トランジスタにパワー MOS 型 FET を使うことにより、オン抵抗を極端に小さくできるので、IC 内部での電力ロ スを限りなく0V にすることができます。これにより、電源電圧の大部分がモータに加 えられて効率がよくなります。 この IC の内部構成は下記のようになっていて、パワーMOS FET とダイオードが4 個内臓されているだけで、他の機能は何もありません。また、フルブリッジを組むため には、外部から各 FET のオン/オフ制御をすることが必要です。 Vcc Q1 Q2 MOTOR Q8 Q7 図30 MP4212 の内部構成 - 38 - (6−6)PWM モータ速度可変回路 RC1 と RC2 に PWM 機能を持つ PIC16F876 と先ほどの MP4212 を用いて、PWM の 可変速制御回路とその動作モードを下記に示します。 Vcc MCLR RA0 RA1 RA2 RA3 RA4 RA5 GND OSC1 OSC2 RC0 RC1 RC2 RC3 RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 Vcc GND RC7 RC6 RC5 RC4 5k 5k PIC16F876 Vcc G1 D1 G2 D2 G3 D3 G4 D4 GNDVcc GND 0.1uF 74HC00 MP4212 MOTOR 図31 PWM]モータ速度可変回路 表12 PWM 動作モード 制御状態 RC4 RC5 RC1 モータ状態 停止 L × L オフ状態で停止 PWM 正転 H PWM L 正方向に PWM 回転 PWM 逆転 L PWM H 逆方向に PWM 回転 ブレーキ H L H ブレーキ状態で停止 正転 H H L オン/オフ制御で正回転 逆転 L H H オン/オフ制御で逆回転 - 39 - (6−7)ダイナミック点灯表示回路 「ダイナミック点灯制御」とは、複数の 7SEG-LED をすべて光らせるのではなく、ひ とつだけ光らせて、その点灯を高速でシフトしていくことで、人間の目にはあたかもす べて光っているように見えます。 この回路においては、基盤の上側につけている「2SA1015」が PIC から「LOW」の出 力を受けると、7SEG に電源を供給するスイッチの役割をしています。もちろんのこと ですが、「HIGH」の出力を受けると 7SEG には電源が供給されなくなります。これは 「PNP 型トランジスタ」の性質を利用していて、ベースとエミッタに電流が流れると、エミ ッタからコレクタには電流が流れなくなります。逆にベースに電流が流れなければ、エ ミッタとコレクタが同通状態となり、エミッタからコレクタに電流が流れます。 ダイナミック点灯表示回路を下記に示します。 Vcc 4.3k RA2 RA3 RA4 RA5 GND RB0 RB1 RB2 RB3 RA1 RA0 OSC1 OSC2 Vcc RB7 RB6 RB5 RB4 PNP1 2SA1015 4.3k PIC16F628 130 130 130 V+ V+ 130 130 abcdefg. abcdefg. 130 130 図32 ダイナミック点灯表示回路 - 40 - PNP 2SA1015 (6−8)車速検出回路 [車速の考え方] タイヤが 1 周するのに X msec かかり、タイヤの直径をD cm とすると、πD cm 進 むということを表している。車速にするためには、3600 秒でいくら進んだかを km の単 位にしなければならない。 このことから、 X msec : 3600 sec = πD cm : L km とすると、 L km/h = 3600 sec * πD / X msec [ cm/h ] = 3600 sec * πD * 10^-2 / X * 10^-3 [ m/h ] = 36 * πD / X [ km/h ] ここで、30 msec ごとにカウントアップするカウンタで 1 周の時間を測定すると、カウ ント値がAカウントなら、 X msec = 30 * A 車速はカウント値Aを用いて表すのであるが、1km/h 未満であるので、小数点以下 2桁を表示するとして 100 倍すると、整数部のみを表示することができる。 すなわち、 36πD * 100 /30 * A = 120πD / A となる。 この式に実際の数値、D = 4.0 cm を代入すると、 120πD = 1508(10 進数) = 05E4(16 進数) となり、車速検出プログラムに 05E4 の値を設定すればよいこととなる。 また、次ページに車速検出回路を示します。 - 41 - Vcc RA2 RA3 RA4 RA5 GND RB0 RB1 RB2 RB3 RA1 RA0 OSC1 OSC2 Vcc RB7 RB6 RB5 RB4 PIC16F628 150 150 RPR220 RPR220 Vcc 30k GND 74HC04 図33 車速検出回路 - 42 - 30k (6−9)衝突回復回路 リモコン戦車の前後にスイッチを付け、物や壁などに衝突した場合、前に当たれば バック、後ろに当たれば前進するようにしました。 下記に衝突回復回路を示します。 Vcc kSW 10k rSW fSW 10k 10k MCLR RA0 RA1 RA2 RA3 RA4 RA5 GND OSC1 OSC2 RC0 RC1 RC2 RC3 図34 衝突回復回路 - 43 - RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 Vcc GND RC7 RC6 RC5 RC4 (6−10)フローチャート[受信部分] スタート 初期化 データ受信 No 2連送照合 OKか? Yes No デバイスコード 一致か? Yes スイッチコード に従った処理 図35 フローチャート[受信部] - 44 - (6−11)フローチャート[速度表示部分] スタート 初期値設定 スイッチの値を読む 10 の桁表示 ボリュームの値を読んで 1msec の時間待ち 1 の桁表示 回数カウンタの値をもらっ て割り算実行し、速度の 値を set する No 既定回数 ループか? Yes 再度スイッチの値を読ん で同じかどうか調べる PWM の値更新 図36 フローチャート[速度表示部分] - 45 - (6−12)フローチャート[レバー処理部] 各キーに応じた処理 レバー操作 No 停止処理 ありか? Yes 前進レバー Yes ONか? フラグを 1 にする No 後進レバー ONか? Yes フラグを2にする No 図37 フローチャート[レバー処理部] - 46 - フラグを0にする (6−13)動作確認 図38 リモコン戦車の動作確認 図39 停止状態の送信データ - 47 - 図40 左タイヤ前進の送信データ 図41 左タイヤ後退の送信データ - 48 - 図42 右タイヤ前進の送信データ 図43 右タイヤ後退の送信データ - 49 - 第7章 ― まとめ・感想 ― 本研究では、段階をおってダイナミック点灯・PWMの速度可変・AM送受信モジュ ールなどの勉強をしました。そして回路実装では、以下に低消費電力で、小さく、美し く製作するかを心がけ、AM無線方式リモコン戦車の設計と製作をしました。 AM無線方式リモコン送信部では、簡単にではありますがAM無線データ通信の原 理や送信方法を学習し使用しました。そして、設計・実装では使う人にとっていかに使 いやすく、わかりやすいもので、かつスムーズに動作をするかというところに重点を置 きました。 リモコン戦車では、AM無線データの受信読み込みや、PWMによるモータ速度可 変や、フルブリッジ回路、モータ IC のことについて学習しました。特に、PWMによる速 度可変の実験にはかなりの時間を費やし、なかなかうまくいかず苦労しました。それ と、受信機が5Vで動作するので、3Vから5Vにするための昇圧回路の表面実装にも 苦労しました。また、2つのPICを使用した理由は、PIC16F876だけでは、フォトリフ レクターと7seg-LED による車速検出・表示とモータドライバによる速度可変の実現が 非常に困難なため、PIC16F628も使用しました。 プログラムには、アセンブラを使用しました。最初は、ルーチンの考え方や作り方が よく分からずかなり苦労しました。この研究においてもプログラミングが一番苦労した 部分だと思います。しかし、日をおうごとに段々理解していっているのが分かり、最初 の頃に比べ成長している自分に喜びを感じました。 この研究を通して、「PIC」の素晴らしさに身を通して感じられたことと、もの作りに対 する面白さを改めて感じました。そして、なによりもこのゼミに所属していたことは、こ れからの人生においてとても貴重な「財産」になったと思います。これからもこの経験 を生かし、日々精進していきたいと思います。 - 50 - ― 謝辞 ― 今回の研究と卒業論文の作成にあたり、終始丁寧なご指導と、ご教示を賜りまし た高知工科大学工学部電子・光システム工学科、綿森道夫助教授には率直に厚く御 礼申し上げます。本研究は、綿森道夫助教授のご助成がなければ完成しなかったと いっても過言ではありません。本当にありがとう御座いました。 また、高知工科大学工学部電子・光システム工学科在学中にご指導を賜った神戸 宏学科長には心から感謝の意を申し上げます。 そして、高知工科大学工学部電子・光システム工学科在学中に本研究の実験遂行 や学生生活面、その他各過程で終始ご厚意とご協力を頂いた、河東田隆教授・河津 哲教授・原央教授・成沢忠教授・木村正廣教授・矢野政顕教授・山本哲也教授・畠中 兼司教授・八田章光教授・橘昌良助教授・野中弘二助教授・高村禎二助教授・山本 真行講師・西田謙助手・吉村紘明助手・武田光由教育講師・安岡文子秘書・中山愛 秘書のみなさまには重ねての感謝の意を述べさせていただきます。 最後になりましたが、本研究を遂行するにあたり、細部までにわたり実験に協力し ていただいた高知工科大学大学院工学研究科基盤工学専攻電子・光システム工学 コースの新田氏と、高知工科大学工学部電子・光システム工学科の伊東賢一郎氏・ 近森準氏・高橋壮平氏・森本祐幸氏・川田研二氏・谷川晃大氏にも深く感謝いたしま す。 - 51 - ― 参考文献 ― [1]電子工作のための PIC 活用ガイドブック 後閑哲也著作・技術評論社出版 [2]PIC マイコンで始める 作って遊べるロボット工作 後閑哲也著作・技術評論社出版 [3] PIC マイコン タミヤ工作セットでできるロボット改造工作マニュアル② 後閑哲也著作・技術評論社出版 [4]たのしくできる PIC 電子工作 後閑哲也著作・東京電機大学出版局出版 [5]ハードウェアデザインシリーズ 15 PIC マイコン活用ハンドブック トランジスタ技術編集部編集・CQ 出版社出版 [6]電子回路シミュレータ入門 加藤ただし著作・講談社出版 [7]CPUの創りかた 渡波郁著作・朝日コミュニケーションズ出版 - 52 - ― 付録 (プログラムリスト) ― (7−1)電子ルーレットのプログラム ;******************************************************* ; 電子ルーレットゲーム ; 12 個の LED を点滅制御、2 個のスイッチ入力 ; 1 個の圧電ブザーを制御 ;******************************************************* list include p=pic16f628 "p16f628.inc" ;******************************************************* ; 変数とレジスタ割付 ;******************************************************* pin0 equ h'20' wsave equ h'21' stsave equ h'22' value equ h'23' ;Randomized Data ledA equ h'24' ;LED position portA ledB equ h'25' ;LED position portB dir equ h'26' chk equ h'27' wreg equ h'28' ;******************************************************* org goto org goto 0 main 4 ccp1int ;******************************************************* - 53 - ; main program ; ;******************************************************* main bcf status,rp0 ;Bank 0 movlw h'07' ;すべてデジタル movwf cmcon movlw b'00110000' ;プリスケール値を 1:8 movwf t1con clrf tmr1h clrf tmr1l movlw b'01000000' ;周辺割り込み movwf intcon movlw b'00001011' ;スペシャルイベントトリガ movwf ccp1con bsf status,rp0 ;Bank 1 clrf trisb ;PORT B を全て出力にセット movlw b'00011000' ;PORT A をセット movwf trisa ;RA3,4 が入力 bsf pcon,3 ;内部クロック(4.0MHz) movlw b'00000100' movwf pie1 bcf status,rp0 ;Bank 0 movlw h'02' ;点灯初期位置セット movwf ledA ;初期位置点灯 clrf ledB ;全て消灯 clrf dir ;右回転 clrf chk ;割り込み脱出判定 ccp1set movlw h'92' movwf ccpr1h movlw h'7c' movwf ccpr1l bcf pir1,ccp1if bsf t1con,tmr1on - 54 - nop bsf intcon,7 ;interrupt on ;********** キー入力待ち、ゆっくり点灯制御 ************* idlelp bcf porta,2 ;ブザー停止 btfss porta,3 ;スタートキー入力ありか? goto strtky ;スタートキー処理へ call ledcnt ;LED 点灯制御(低速) movlw h'30' movwf ccpr1h movlw h'd4' movwf ccpr1l bcf pir1,ccp1if bsf t1con,tmr1on nop bsf intcon,7 jump btfss chk,2 goto jump btfss chk,1 goto jump clrf chk incf value,f ;ランダム変数アップ goto idlelp ;入力なし、繰り返し ;********** スタートキー処理 *************************** strtky movlw h'04' ;チャッタリング回避(D8=216) movwf ccpr1h movlw h'e2' movwf ccpr1l bcf pir1,ccp1if bsf t1con,tmr1on nop bsf intcon,7 jump2 btfss chk,0 - 55 - goto clrf bcf btfsc goto jump2 chk intcon,7 porta,3 idlelp ;再入力チェック ;ノイズ? ;************** ルーレットゲームスタート *************** gamelp bsf porta,2 ;ブザーON call ledcnt ;LED 点灯制御(高速) incf value,F ;ランダム変数アップ btfss porta,4 ;ストップキーON か? goto stpky ;ストップキー処理へ movlw h'04' ;10msec 待ち(高速) movwf ccpr1h movlw h'e2' movwf ccpr1l bcf pir1,ccp1if bsf t1con,tmr1on nop bsf intcon,7 jump3 btfss chk,0 goto jump3 clrf chk bcf intcon,7 goto gamelp ;キー無し継続 ;****************** stpky bcf cntdwn movf sublw btfss goto movf ストップ処理 *********************** porta,2 ;ブザー一旦 OFF value,w h'20' status,c first value,w ;乱数取りだし ;VALUE が 32 より大きいか? ;32-W>0? ;32 より大きい高速へ ;再度乱数取りだし - 56 - sublw h'10' btfss status,c goto middle goto slow ;VALUE が 16 より大きいか? ;16-W>0? ;32 より小さい中速へ ;16 より小さい低速へ ;**************** 低速表示と停止処理 ******************* slow call ledcnt ;LED 表示次へ bsf porta,2 ;ブザー断続鳴動 ON movlw h'30' ;100msec 待ち(3C=60) movwf ccpr1h movlw h'd4' movwf ccpr1l bcf pir1,ccp1if bsf t1con,tmr1on nop bsf intcon,7 jump4 btfss chk,1 goto jump4 clrf chk bcf intcon,7 bcf porta,2 ;ブザーOFF movlw h'61' ;200msec 待ち(3C=60) movwf ccpr1h movlw h'a8' movwf ccpr1l bcf pir1,ccp1if bsf t1con,tmr1on nop bsf intcon,7 jump5 btfss chk,2 goto jump5 clrf chk bcf intcon,7 decfsz value,f ;VALUE-1 goto cntdwn ;まだ次へ - 57 - ;******************** 停止処理 ************************* bcf porta,2 ;ブザー停止 stplp btfss porta,3 ;スタートキー入力待ち goto strtky ;次のゲーム開始へ btfsc porta,4 ;ストップキー入力か? goto stplp ;キー入力なし、ループ comf dir,f ;回転反転 btfss dir,0 call right btfsc dir,0 call left goto idlelp ;アイドルループへ ;******************** 中速表示 ************************* middle call ledcnt ;LED 表示次へ bsf porta,2 ;ブザー断続鳴動 ON movlw h'30' ;100msec 待ち(3C=60) movwf ccpr1h movlw h'd4' movwf ccpr1l bcf pir1,ccp1if bsf t1con,tmr1on nop bsf intcon,7 jump6 btfss chk,1 goto jump6 clrf chk bcf intcon,7 bcf porta,2 ;ブザー停止 movlw h'30' ;100msec 待ち(3C=60) movwf ccpr1h movlw h'd4' movwf ccpr1l - 58 - jump7 bcf bsf nop bsf btfss goto clrf bcf decf goto pir1,ccp1if t1con,tmr1on intcon,7 chk,1 jump7 chk intcon,7 value,f cntdwn ;VALUE-1 ;繰り返しへ ;******************** 高速表示 ************************* first call ledcnt ;LED 表示次へ bsf porta,2 ;ブザー連続鳴動 ON movlw h'04' ;20msec 待ち movwf ccpr1h movlw h'e2' movwf ccpr1l bcf pir1,ccp1if bsf t1con,tmr1on nop bsf intcon,7 jump8 btfss chk,1 goto jump8 clrf chk bcf intcon,7 decf value,f ;VALUE-1 goto cntdwn ;******************************************************* ; ; サブルーチン群 ; ;******************************************************* - 59 - ;******************************************************* ; 発光ダイオード制御サブルーチン ; 点灯の度に位置シフト ;******************************************************* ledcnt ;*************** 現在位置 LED 点灯制御 ******************* comf ledA,w btfsc porta,2 ;ブザーをチェック goto testset andlw b'11111011' ;ブザーを OFF goto next testset iorlw b'00000100' ;ブザーを ON next movwf porta comf ledB,w ;0,1 反転 movwf portb ;ポート B 制御 ;***************** LED 位置をシフト ********************* btfsc dir,0 ;回転判断 goto left ;左回転へ right rrf ledA,f ;ポート A を右にシフト rrf ledB,f ;ポート B を右にシフト btfss status,c ;キャリーの状態は? goto clr2 ;クリアされている bsf ledA,7 ;セット処理 goto next2 clr2 bcf ledA,7 ;クリア処理 btfss ledA,5 goto clr3 bsf ledA,1 goto next2 clr3 bcf ledA,1 next2 return left rlf ledB,f ;ポート B を左にシフト rlf ledA,f ;ポート A を左にシフト btfss status,c goto clr4 - 60 - clr4 clr5 clr6 next3 bsf goto bcf btfss goto bsf goto bcf return ledB,0 clr5 ledB,0 ledA,2 clr6 ledA,6 next3 ledA,6 ;ポート A の 2 ビット目は? ;クリアされている ;セット処理 ;クリア処理 ;******************************************************* ; interrupt rutine ;******************************************************* ccp1int movwf wsave movf status,w movwf stsave bcf pir1,ccp1if incf chk,f movf stsave,w movwf status swapf wsave,f swapf wreg,w retfie end - 61 - (7−2)リモコン送信部のプログラム ;************************************************************** ; 赤外線リモコン送信器プログラム ; 送信信号フォーマットは1ビットが 600μsec の幅である ; 送信データは 16 ビットが意味のある信号であり、2連送する ; 詳細な送信フォーマットは 24 ビットで下記のようになっている。 ; "0"が 8 個,"1",C2,C1,C0,"0,1",D4,D3,D2,D1,D0,"1,0,0,0,0" ; C0toC2 is device code for 7 devices.(not used all 0) ; D0toD4 is switch data for 3X8=24 switches ; スイッチのチェックは 0.3 秒ごとに繰り返すので、連続押下も可能 ;************************************************************** list include p=pic16f628 "p16f628.inc" ;************************************************************** ; 変数の定義とレジスタ割付 ;************************************************************** sdata equ h'20' ;送信データ cnt1 equ h'21' ;Counter cnt2 equ h'22' ;Counter cnt3 equ h'23' ;Counter bitcnt equ h'24' ;Bit counter wcnt equ h'25' ;counter for 37.9kHz w6cnt equ h'26' ;counter for 600usec work equ h'27' ;work area device set h'60' ;preset device code ;************************************************************** org 0 ;reset ;************************************************************** ; - 62 - ; メインプログラム ;************************************************************** ;******************* 入出力ピン初期化 ************************ main call port_ini ;初期化 ;********************* メインループ *************************** loop call scan ;キースキャン call leed ;リーダー部送信 call send ;データ部送信 call send ;再送 call wait ;0.3 秒待つ goto loop ;繰り返し ;************************************************************** ; ; サブルーチン群 ; ;************************************************************** ;************************************************************** ; 入出力ピン初期化サブルーチン ; PORTA: RA0 出力で AM 送信機にデータを送る ; PORTB: すべて入力でプルアップ抵抗 ON ;************************************************************** port_ini bcf status,rp0 ;バンク 0 へ戻る movlw h'07' ;全てデジタル movwf cmcon bsf status,rp0 ;バンク 1 に切替 movlw b'11111110' ;RA0 のみ出力 movwf trisa ;PortA 0 set output movlw h'ff' ;PORTB すべて入力 - 63 - movwf trisb bcf option_reg,7 bcf status,rp0 return ;PortB set all input ;PORTB のプルアップ抵抗 ON ;バンク 0 へ戻る ;************************************************************** ; スイッチの入力チェックサブルーチン ; RB0 から RB7 を順次チェック ; キーコード部分の送信データは下記 ; C2,C1,C0,0,0,D2,D1,D0 ; D:PORTB bit loaction ; C:device code ;************************************************************** scan movf portb,w ;PORTB から入力 movwf work ;一時保存 comf work,f ;0to1 を反転 ;**************** チャッタリング回避 ************************* call time5m ;5msec 待ち comf work,w subwf portb,w ;再入力比較 btfss status,z ;同じか? gtoto scan ;違う、無視 ;************** fined key,convert to key code ***************** movf work,w ;再取り出し andlw h'0f' iorlw device ;デバイスコードと OR movwf sdata ;送信キーコードセット return ;戻る ;************************************************************** ; データ送信 s 部ルーチン ; 送信データは24ビットで、その詳細フォーマットは下記 - 64 - ; "0"X8bits,"1",C2,C1,C0,"0","1",D4,D3,D2,D1,D0,"1","0"x4bits ; C0toC2 is device code for 7 devices.(not used all 0) ; D0toD4 is switch data for 3X8=24 switches ; 送信データ1ビットは 600μsec 幅 ;************************************************************** ;************** リーダー部送信サブルーチン ******************* leed movlw 7 ;7 ビット分 movwf bitcnt ldlp call bit0 ;0 のデータ送信 decfsz bitcnt,f ;繰り返し goto ldlp return ;************************************************************** ; 16 ビットのデータ送信サブルーチン ; DATA:送信キーデータ ;************************************************************** send ;******************** スタートビットの送信 ******************* call bit1 ;send start bit ;******************** デバイスコードの送信 ******************** movlw 3 ;3 ビット分 movwf bitcnt dcode rlf sdata,f ;送信ビットをキャリーへ btfss status,c ;0 なら 0 送信へ call bit0 ;0 送信 btfsc status,c ;1 なら 1 送信へ call bit1 ;1 送信 decfsz bitcnt,f ;終了か? goto dcode ;次のビットへ call bit0 ;リーダ部送信 call bit1 ;第二スタートビット出力 - 65 - ;******************** キーコードの送信 ************************ movlw 5 ;5 ビット分 movwf bitcnt keycode rlf sdata,f ;送信ビットをキャリーへ btfss status,c ;0 なら 0 送信へ call bit0 ;0 送信 btfsc status,c ;1 なら 1 送信へ call bit1 ;1 送信 decfsz bitcnt,f ;終了か? goto keycode ;次のビットへ rlf sdata,f ;もとに戻す call bit1 ;ストップビット送信 ;******************** トレーラ部送信 ************************** movlw 4 ;4 ビット分 movwf bitcnt taril call bit0 ;0 を送信 decfsz bitcnt,f ;終了か? goto taril return ;************************************************************** ; 「0」送信サブルーチン ;************************************************************** bit0 bcf porta,0 ;******************** 600μsec タイマ ************************ movlw h'0c' ;600μsec 待ち movwf w6cnt bt01lp movlw h'0f' movwf wcnt - 66 - bt00lp decfsz wcnt,f goto bt00lp nop decfsz w6cnt,f goto bt01lp return ;3*15-1+2=46 ;(46+4)*12-1+5=604μsec ;************************************************************** ; 「1」送信サブルーチン ; "1" :13μsec "0":13μsec ;************************************************************** bit1 bsf porta,0 movlw h'0c' ;600μsec 分繰り返し movwf w6cnt bt_01lp movlw h'0f' movwf wcnt bt_00lp decfsz wcnt,f goto bt_00lp ;3*15-1+2=46 nop decfsz w6cnt,f goto bt_01lp return ;(46+4)*12-1+5=604μsec ;************************************************************** ; 0.3 秒待ちタイマサブルーチン ;************************************************************** wait movlw h'03' ;3 movwf cnt3 wtlp3 - 67 - movlw h'63' movwf cnt2 ;99 movlw h'64' movwf cnt1 ;100 wtlp2 wtlp1 decfsz cnt1,f goto wtlp1 ;3*100-1+2=301usec decfsz cnt2,f goto wtlp2 ;(301+3)*99-1+3=30098 decfsz cnt3,f goto wtlp3 return ;(30098+3)*3-1+4=90132=90msec ;************************************************************** ; Timer Routine ; TIME10 :10usec ; TIME100 :100usec ; TIME5M :5msec ;************************************************************** time100 ;100usec movlw h'09' movwf cnt1 tmlp1 call time10 ;2+(26+3)*9-1=262 decfsz cnt1,f goto tmlp1 return ;264*0.4=106usec(about) time10 ;10usec movlw h'07' movwf cnt2 tmlp2 decfsz cnt2,f ;2+3*7-1=22 goto tmlp2 return ;22+2=24 time5m ;5msec(about) - 68 - movlw movwf tmlp3 call decfsz goto return h'38' cnt3 time100 cnt3,f tmlp3 ;2+(266+3)*56-1=15065 ;15067 end - 69 - (7−3)リモコン戦車受信部のプログラム ;************************************************************* ; 赤外線受信機、モータ制御プログラム ; 2 個の DC モータの可変速制御が可能 ; 受信信号は、600μsec/bit ; データは 16 ビットで 2 連送され照合により誤りチェックをする ; 8 ビットのリーダ部+16 ビットデータの詳細フォーマットは下記 ; "0"が 8 個,"1",C2,C1,C0,"0,1",D4,D3,D2,D1,D0,"1,0,0,0,0" ; C0toC2 はデバイスコードで 7 個区別可能(000 は使わない) ; D0toD4 はスイッチコードで 32 個の区別が付く ;************************************************************* list include p=pic16f876 "p16f876.inc" ;************************************************************* ; 変数、定数定義とレジスタ割付 ;************************************************************* rdata1 equ h'20' ;受信データ1回目 rdata2 equ h'21' ;受信データ2回目 cnt1 equ h'22' ;タイマカウンタ cnt2 equ h'23' ;タイマカウンタ cnt3 equ h'24' ;タイマカウンタ bitcnt equ h'25' ;ビットカウンタ spd1 equ h'26' ;左モータ PWM の値 spd2 equ h'27' ;右モータ PWM の値 dir1 equ h'28' ;左モータの状態 dir2 equ h'29' ;右モータの状態 work equ h'2A' temp equ h'2B' mask1 equ mask2 equ b'00000011' b'00001100' ;下位 2bit を mask ;上位 2bit を mask - 70 - device set break set h'60' h'ff' ;デバイスコード定数 ;ブレーキデータ ;************************************************************* org 0 ;reset ;************************************************************* ; ; メインプログラム ; ;************************************************************* main call port_ini ;入出力モード初期設定 movlw h'0c' movwf ccp1con ;PWM モード ON movwf ccp2con ;PWM モード ON movlw b'00000001' ;TMR2 プリスケーラ 1:4 movwf t2con clrf tmr2 movlw h'a0' ;ダミーの PWM 設定値 movwf ccpr1l movwf ccpr2l bsf status,rp0 ;Bank1 に切り替え movlw h'ff' movwf pr2 ;PWM の周期設定 bcf status,rp0 ;Bank0 に戻す bsf t2con,2 ;TMR2 をオン clrf spd1 ;速度リセット clrf spd2 ;速度リセット clrf dir1 ;状態リセット clrf dir2 ;状態リセット bcf portc,0 bcf porta,5 ;************************************************************* - 71 - ; メインループ ;************************************************************* loop call recv ;データ受信 ;****************** デバイスコード比較 *********************** rcved bcf portc,0 bcf porta,5 movf rdata1,w ;データ取出し andlw h'e0' ;デバイスコード部取出し sublw device ;比較 btfss status,z ;同じか? goto loop ;違う、戻る ;******************* 受信コードの判定 ************************ left ;左モータの処理 bsf porta,5 movf rdata1,w andlw b'00000011' movwf temp sublw b'00000001' ;01 の判定 btfsc status,z goto back_01 movf temp,w sublw b'00000010' ;10 の判定 btfsc status,z goto go_10 movf temp,w ;00 の判定 btfss status,z goto right stop_00 ;00 の処理 movf spd1,w ;現在速度取り出し sublw h'70' btfss status,c ;spd1 が 70 より小さいか? goto stop_a ;70 より大きいとき - 72 - clrf clrf goto spd1 ccpr1l set0 ;PWM=0 とする stop_a decf movf movwf movf sublw btfsc goto goto back_01 movf btfss goto movlw movwf movwf goto back_a movf sublw btfss goto movlw movwf movwf goto back_b movf incf btfsc decf movf movwf spd1,f spd1,w ccpr1l dir1,w d'1' status,z set1 set2 dir1,w status,z back_a h'70' spd1 ccpr1l set2 dir1,w d'01' status,z back_b h'70' spd1 ccpr1l set2 spd1,w spd1,f status,z spd1,f spd1,w ccpr1l ;01 の処理 左後退 ;現在の左モータの方向を調べる ;dir1=0 とまっているときの処理 ;dir1=0 でない ;PWM の設定 ;それまでが前進か? ;それまでが後退のときの処理 ;現在速度取り出し ;速度+1 ;速度-1 - 73 - goto set2 go_10 movf btfss goto movlw movwf movwf goto dir1,w status,z go_a h'70' spd1 ccpr1l set1 movf sublw btfss goto movlw movwf movwf goto dir1,w d'02' status,z go_b h'70' spd1 ccpr1l set1 movf incf btfsc decf movf movwf goto spd1,w spd1,f status,z spd1,f spd1,w ccpr1l set1 ;10 の処理、左前進 ;現在の左モータの方向を調べる ;dir1=0 とまっているときの処理 ;dir1=0 でない ;PWM の設定 go_a ;それまでが後退か? ;それまでが前進のときの処理 go_b set0 ;速度-1 ;左モータ停止 movlw movwf clrf clrf bcf nop bcf goto set1 ;現在速度取り出し ;速度+1 d'0' dir1 spd1 ccpr1l portc,6 portc,7 right ;左モータ前進 - 74 - movlw movwf bcf nop bsf goto d'1' dir1 portc,6 portc,7 right set2 ;左モータ後退 movlw movwf bcf nop bsf movf movwf d'2' dir1 portc,7 portc,6 spd1, w portb right ;右モータの処理 bsf movf andlw movwf sublw btfsc goto movf sublw btfsc goto movf btfss goto portc,0 rdata1,w b'00001100' temp b'00000100' status,z go01 temp,w b'00001000' status,z back10 temp,w status,z loop stop00 movf sublw btfss goto clrf clrf spd2,w h'70' status,c stop_b spd2 ccpr2l ;01 の判定 ;10 の判定 ;00 の判定 ;00 の処理 ;現在速度取り出し ;spd2 が 70 より小さいか? ;70 より大きいとき ;PWM=0 とする - 75 - goto set_0 decf movf movwf movf sublw btfsc goto goto spd2,f spd2,w ccpr2l dir2,w d'1' status,z set_1 set_2 stop_b back10 movf btfss goto movlw movwf movwf goto dir2,w status,z back_c h'70' spd2 ccpr2l set_2 movf sublw btfss goto movlw movwf movwf goto dir2,w d'01' status,z back_d h'70' spd2 ccpr2l set_2 movf incf btfsc decf movf movwf goto spd2,w spd2,f status,z spd2,f spd2,w ccpr2l set_2 ;01 の処理、右後退 ;現在の右モータの方向を調べる ;dir2=0 とまっているときの処理 ;dir2=0 でない ;PWM の設定 back_c ;それまでが前進か? ;それまでが後退のときの処理 back_d go01 ;現在速度取り出し ;速度+1 ;速度-1 ;10 の処理 左前進 - 76 - movf btfss goto movlw movwf movwf goto dir2,w status,z go_c h'70' spd2 ccpr2l set_1 movf sublw btfss goto movlw movwf movwf goto dir2,w d'02' status,z go_d h'70' spd2 ccpr2l set_1 movf incf btfsc decf movf movwf goto spd2,w spd2,f status,z spd2,f spd2,w ccpr2l set_1 ;現在の左モータの方向を調べる ;dir2=0 とまっているときの処理 ;dir2=0 でない ;PWM の設定 go_c ;それまでが後退か? ;それまでが前進のときの処理 go_d set_0 ;現在速度取り出し ;速度+1 ;速度-1 ;右モータ停止 movlw movwf clrf clrf bcf nop bcf goto d'0' dir2 spd2 ccpr2l portc,4 portc,5 loop set_1 ;右モータ前進 movlw d'1' movwf dir2 - 77 - bcf nop bsf goto portc,4 portc,5 loop set_2 ;右モータ後退 movlw movwf bcf nop bsf goto d'2' dir2 portc,5 portc,4 loop ;************************************************************* ; ; サブルーチン ; ;************************************************************* ;************************************************************* ; 入出力モード初期化サブルーチン ; PORTA: RA0-RA2 -> スイッチ制御 ; RA3 -> AM 送信機のデータ受信 ; RA5 -> LED の制御 ; PORTB: RB0-RB7 -> LED の制御 ; PORTC: RC0 -> LED の制御 ; RC1,RC2 -> CCP1,CCP2 の制御 ; RC4,RC5 -> モータ 2 の速度制御 ; RC6,RC7 -> モータ 1 の速度制御 ;************************************************************* port_ini bsf status,rp0 ;Bank1 にする movlw h'07' ;全てデジタル movwf adcon1 movlw b'00001111' ;RA0-RA3 を入力 movwf trisa ;PortA の設定 clrf trisb ;PortB の設定 - 78 - clrf trisc bcf status,rp0 movlw d'0' movwf portc return ;PortC の設定 ;Bank0 に戻す ;速度設定 0 クリア ;全モータ停止制御 ;************************************************************* ; データ受信サブルーチン ; 8 ビットのリーダ部+16 ビットデータの詳細フォーマットは下記 ; "0"が 8 個,"1",C2,C1,C0,"0,1",D4,D3,D2,D1,D0,"1","0"が 4 個 ; C0toC2 はデバイスコードで7個区別可能(000 は使わない) ; D0toD4 はスイッチコードで 32 個の区別が付く ; 1回目の受信データは RDATA1 に格納、2回目は RDATA2 に格納. ; 両者を比較することで受信誤りチェック ; 受信方式は調歩同期式と同じ、最初スタートビットで最後ストップ ;************************************************************* recv call getdata ;1 回目受信 movf work,w movwf rdata1 ;RDATA1 に格納 call getdata ;2 回目受信 movf work,w movwf rdata2 ;RDATA2 に格納 subwf rdata1,w ;比較 btfss status,z ;同じか? goto recv ;違う、受信し直し movf rdata1,w movwf portb return ;受信完了戻り ;************************************************************* ; 16 ビットデータ受信サブルーチン ;************************************************************* getdata ;****************** スタートビット待ち ********************** btfsc porta,0 ;前のスイッチを調べる - 79 - goto call btfsc goto ushiro wait10m porta,0 ushiro ;10msec 待つ ;************** 前のスイッチが押された処理 ******************* call modoru clrf portb clrf work return ushiro btfsc porta,1 goto strtbit call wait10m ;10msec 待つ btfsc porta,1 goto strtbit ;************** 後ろのスイッチが押された処理 ***************** call susumu clrf portb clrf work return strtbit btfsc porta,3 ;RA3 を入力 goto strtbit ;データ無し戻る call wait300 ;データ有り、300usec 待つ btfsc porta,3 ;RA3 再入力、スタート確認 goto getdata ;スタートビットで無い ;****************** デバイスコード部受信 ********************* clrf work ;受信バッファクリア movlw 3 ;ビットカウンタ 3 にセット movwf bitcnt cdlp call wait600 ;600usec 待つ btfsc porta,3 ;データ 0 か? - 80 - bcf btfss bsf rlf decfsz goto status,c porta,3 status,c work,f bitcnt,f cdlp ;Carry リセット ;データ1か? ;Carry セット ;Carry を WORK へシフト ;全ビット終了か? ;繰り返し ;******************* セパレータテスト *********************** call wait600 ;1 ビット分待つ btfss porta,3 ;"0" か? goto strtbit ;エラー受信し直し call wait600 btfsc porta,3 ;"1" か? goto strtbit ;エラー受信し直し ;******************* 受信データ部の処理 ********************** movlw 5 ;カウンタを 5 にセット movwf bitcnt dtlp call wait600 ;1 ビット分待つ btfsc porta,3 ;データ 0 か? bcf status,c ;Carry リセット btfss porta,3 ;データ1か? bsf status,c ;Carry セット rlf work,f ;Carry を WORk へシフト decfsz bitcnt,f ;終了か? goto dtlp ;繰り返し ;************* ストップシーケンスの受信(1,0,0) *************** call wait600 btfsc porta,3 ;"1"か? goto strtbit ;誤り受信し直し call wait600 ;次のビット待ち btfss porta,3 ;"0" か? goto strtbit ;誤り受信し直し call wait600 ;次のビット待ち - 81 - btfss porta,3 goto strtbit return ;"0" か? ;誤り受信し直し ;***************** 前・後のスイッチ処理 ********************** modoru movlw h'a0' movwf spd1 movwf spd2 movwf ccpr1l movwf ccpr2l movlw b'01010110' movwf portc movlw d'150' movwf cnt2 tmlp call wait10m decfsz cnt2,f goto tmlp clrf spd1 clrf spd2 clrf ccpr1l clrf ccpr2l clrf dir1 clrf dir2 movlw b'00000000' movwf portc return susumu movlw h'a0' movwf spd1 movwf spd2 movwf ccpr1l movwf ccpr2l movlw b'10100110' movwf portc movlw d'150' - 82 - movwf tmlp2 call decfsz goto clrf clrf clrf clrf clrf clrf movlw movwf return cnt2 wait10m cnt2,f tmlp2 spd1 spd2 ccpr1l ccpr2l dir1 dir2 b'00000000' portc ;************************************************************* ; ソフトタイマーサブルーチン ; WAIT300 : 300usec ; WAIT600 : 600usec ; WAIT10M : 10msec ;************************************************************* wait300 movlw h'f9' ;249 movwf cnt1 ;1+1=2 lp1 decfsz cnt1,f goto lp1 ;3*249-1+2=748 return ;750*0.4usec=300usec wait600 movlw h'02' ;2 movwf cnt1 ;1+1=2 lp2 movlw h'f7' ;247 movwf cnt2 lp3 decfsz cnt2,f goto lp3 ;3*247-1+2=742 - 83 - decfsz goto return wait10m movlw movwf lp4 movlw movwf lp5 decfsz goto decfsz goto return cnt1,f lp2 ;(742+3)*2-1+2=1491 ;1493*0.4usec=600usec h'22' cnt1 ;34 ;1+1=2 h'f4' cnt3 ;244 cnt3,f lp5 cnt1,f lp4 ;3*244-1+2=733 ;(733+3)*34-1+2=25025 ;25025*0.4usec=10010=10msec end - 84 -