PICチュートリアル-レジスタから割り込みまで

問題を排除するために楽器を試してください





PICプログラミングの詳細に入る前に、いくつかの優れたプログラミング方法を学ぶことが最初に重要です。

レジスターを理解する

まず、プログラムの任意の場所で(セミコロン)を入力すると、このセミコロンの後に続くものはすべて、もちろんキャリッジが元の位置に戻るまで、コンパイラによって無視されます。



上記の機能を使用すると、コメントやコメントを追加して、プログラムの一部にならないようにすることができますが、その横にあるコメントを使用してプログラムを識別しやすくなります。 ICをプログラミングするときは、コメントを付けることをお勧めします。

このコースで次に重要なことは、さまざまな定数に名前を割り当てることです(後で詳しく説明します)。このasoを使用すると、含まれている数値と混同することなく、何が書き込まれているのか、または関連する値に関して理解しやすくなります。



上記は、COUNTなど、すぐに認識できるように実際の名前の形式で行う必要があります。ここでは、区別するためにすべて大文字が使用されており、定数値であることを示していることに注意してください。


ご覧のとおり、上記はセミコロンで作られたボックスの形で行われているため、見た目がすっきりします。さらに、プログラムを紙に文書化してみてください。この方法は、段階的に物事を理解するのに役立ちます。

2.レジスター。

PIC内のレジスタは、書き込まれた詳細を受け入れ、そこから読み取ることもできる領域です。内容を視覚化して上に書くことで追加できる一枚の紙と比較することができます。

次の図は、PIC16F84に埋め込まれた一般的なレジスタファイルマップを示しています。このフォーマットは、実際にPIC内で設定されるものではなく、単にビットがチップ内でどのように配置されるかを示し、関連するコマンドのいくつかを理解するためのものです。

基本的にバンク0とバンク1に分割されていることがわかります。バンク1は、PICの実際の動作を制御する役割を果たします。たとえば、ポートAのどのビットが入力として割り当てられ、どのビットが出力として割り当てられているかをPICに通知します。

バンク2は情報を操作するためだけのものです。

次の例でこれを理解しましょう。

PortAをHighに1ビット割り当てたいとします。このためには、最初にバンク1に移動して、ポートAの指定されたビットまたはピンを出力の形式で設定する必要があります。この後、バンク0に戻り、ロジック1(ビット1)をその特定のピンに配信します。

バンク1で使用したい最も一般的なレジスタは、STATUS、TRISA、およびTRISBです。

STATUSはバンク0に戻るのに役立ち、TRISAはポートAのどのピンが出力で、どのピンが入力になるかを選択できます。TRISBは、ポートBの出力ピンと入力ピンのどちらかを選択できます。BANK0のSELECTレジスタにより、ユーザーはバンク1に切り替えます。

次の説明で全体の概念を要約しましょう。

状態:

バンク0からバンク1に切り替えるために、STATUSレジスタにコマンドを送信します。これは、STATUSレジスタのビット#5を1に設定することで実装されます。バンク0に戻るために、STATUSレジスタのビット5を0に割り当てます。STATUSレジスタはアドレス03hに配置され、ここでhは番号を示します。 16進数である可能性があります。

TRISAとTRISB:

これらはそれぞれアドレス85hと86hにあります。ピンを出力または入力としてプログラミングする場合、レジスタの特定のビットに0または1を供給するだけです。これは、バイナリまたは16進数の2つの方法で実行できます。パラメータを変換できない場合は、値を実装するための関数電卓を利用できます。

これで、ポートAに5つのピンがあり、これは5つのピンに対応します。ピンの1つを入力として固定する場合は、特定のビットに「1」を付けます。

ピンの1つを出力として割り当てたい場合は、特定のピンを「0」に設定します。ビットは、ビットに正確に対応して支援されます。より正確には、ビット0はRA0、ビット1はRA1、ビット2 = RA2などになります。このように理解しましょう:

RA0、RA3、およびRA4を出力として固定し、RA1 / RA2をi / psとして固定したい場合は、00110(06h)を送信してこれを行います。ここに示されているように、ビット0が右側にあることを確認してください。

ポートAピンRA4RA3 RA2 RA1 RA0

ビット番号43 2 1 0

バイナリ00 1 1 0

同じことがTRISBにも当てはまります。

PORTAとPORTB

出力ピンの1つをHighにするために、PORTAまたはPORTBレジスタのそれぞれのビットに「1」を提供するだけです。 TRISAレジスタとTRISBレジスタについても、同じ手順に従うことができます。最初のコーディング例に進む前に、さらに多くのレジスタ、つまりwとfのクーペについて理解しましょう。

WとF

Wレジスタは、任意の値を割り当てることができる通常のレジスタです。 Wに大きさを割り当てるとすぐに、これを別の値に追加するか、単に移動することができます。別の値が割り当てられると、詳細は単にWに上書きされます。

Fレジスタは、その記述内容をレジスタに転送します。このFレジスタは、レジスタに値を割り当てる必要があります。STATUSまたはTRISAレジスタに値を割り当てることはできないため、これらのレジスタに値を直接割り当てることはできません。サンプルプログラム

次のサンプルコードを調べてみましょう。これは、上記の手順がどのように実装されているかを示し、コース内のいくつかの手順も確認します。

上記のようにポートAを修正することから始めましょう。

このために、バンク0からバンク1にシフトする必要があります。これは、アドレス03h、ビット5から1にあるSTATUSレジスタを設定することによって行われます。

BSF 03h、5

BSFはビットセットFを意味します。この命令の後に、STATUSレジスタアドレスである03hとビット番号に対応する番号5の2つの番号を使用しています。

つまり、「アドレス03hのビット5を1に設定する」ということです。

現在、銀行1にいます。

MOVLW 00110b

バイナリ値00110(文字bは数値がバイナリであることを意味します)を汎用レジスタWに入れています。もちろんこれを16進数で行うこともできます。その場合、命令は次のようになります。

MOVLW 06h

どちらも機能します。 MOVLWは、「リテラル値をWに移動する」を意味します。これは、英語では、後続の値をWレジスタに直接入れることを意味します。

次に、この値をTRISAレジスタに入力して、ポートを設定する必要があります。

MOVWF 85h

この命令は、「Wの内容を後続のレジスタアドレスに移動する」ことを示します。この場合、アドレスはTRISAを参照します。

この時点でのTRISAレジスタには、図00110が付いているか、グラフィカルに表示されます。

ポートAピンRA4RA3 RA2 RA1 RA0

バイナリ00 1 1 0

入出力OO I I O

これでポートAピンができたので、バンク0に戻って情報の1つを調整する必要があります。

BCF 03h、5

この命令は、BSFの逆を実行します。 「ビットクリアF」を意味します。対応する数字のペアは、レジスタのアドレス(ここではSTATUSレジスタ)とビット図(この場合はビット5)です。私たちが現在完了しているのは、私たちのビット5で定義されていることです。

ステータスレジスタを0に

この時点で、バンク0に戻りました。
以下は、すべて1つのブロックに含まれるコードです。

BSF 03h、5銀行1に移動
MOVLW 06h00110をWに入れる
MOVWF 85h00110をTRISAに移動します
BCF 03h、5バンク0に戻る

最後の説明の中で、PICのIOポートピンを入力または出力できるように確立する方法を確認しました。

このコースを通じて、ポートへのデータ送信を支援します。

ポートへのデータの送信

次のチュートリアルでは、完全なプログラムの詳細と簡単な回路図で構成されるLEDを点滅させて完了させ、PICが期待どおりに動作していることを確認できるようにします。

以下の結果は単なる図であるため、PICをまとめてプログラムしようとしないでください。最初に、ポートAビット2を出力として確立します。

これは、前の説明から認識できる可能性があります。唯一の違いは、トライステートレジスタに0hを配信することにより、出力としてAのピンのすべてのビットを固定したことです。だから今彼がしなければならないことはLEDをオンにすることです。

これを実現するには、ピンの1つ(LEDがリンクされているピン)をハイにスケジュールします。別の言い方をすれば、ピンに「1」を適用します。これはまさにそれが実行される方法です(すべての行の説明のためにコメントを観察してください):

したがって、これで達成したのは、LEDを一度オンにしてからオフにすることです。私たちが望んでいるのは、LEDが継続的にオンになり、その後オフになることです。

これは、最初に戻るプログラムを入手することで実現します。これは、プログラムの最初にタグを最初に確立し、その後、プログラムにそこに戻るように通知することによって実現します。タグは非常に簡単に指定します。

STARTなどの用語を入力し、次にコードを入力します。

示されているように、最初にプログラムの最初に「開始」という表現について言及しました。

次に、プログラムの最後に、「gotoStart」とはっきりと述べました。 「goto」命令は、宣言されたとおりに実行されます。

このプログラムは、回路の電源を入れるたびに常にLEDのオンとオフを切り替え、電気を抜くとオフになる傾向があります。プログラムをもう一度確認する必要があるかもしれません。

確かにコメントは省略していますが、指示と番号は確認できます。

これは、後でプログラムのトラブルシューティングを試み、コードを記述しているときにすべてのアドレスを記憶している場合に、少し困惑する可能性があります。

コメントはまだ置かれているかもしれませんが、少し雑然となる可能性があります。これには番号に名前を付ける必要があり、追加の命令によって実行される場合があります。'equ''equ '命令は、あるものが別のものと等しい可能性があることを示唆しています。

PICの指示ではなく、アセンブラの指示である可能性があります。この命令により、レジスタアドレスの場所に名前を割り当てたり、プログラミング用語に定数を割り当てたりすることが容易になります。

プログラムの定数をいくつか確立し、プログラムの読み取りがどれほど簡単かを確認します。

これで定数値が修正されたので、プログラムに設定して続行できます。定数値は、使用する前に指定する必要があります。

したがって、必ずプログラムの最初に配置してください。以前のラベリングと最新のラベリングを比較するために、コメントを除いたプログラムをもう一度書き直します。

定数によってプログラムが少しわかりやすくなっていることに気付くかもしれませんが、まだコメントがないので心配はいりません。まだ終わっていないからです。

LEDの点滅プログラムには小さな欠点があるかもしれません。
すべての命令は、終了するために1クロックシーケンスを必要とします。 4MHzの水晶を使用している場合、すべての命令は1 / 4MHz、つまり1uSで終了する必要があります。

たった5つの命令を採用しているので、LEDは5uSでアクティブになってからオフになります。これは、人々が気付くには速すぎる可能性があり、さらに、LEDが完全にオンになっているように見えます。

代わりに達成すべきことは、LEDをオンにすることとオフにすることの間の抑制を生み出すことです。抑制の理論は、以前の量からカウントダウンするというものです。したがって、ゼロになったら、カウントを終了します。

ゼロ値は遅延の終了を意味し、プログラム全体を通してプロセスを継続します。したがって、最初に行う必要があるのは、カウンターとして使用する定数を決定することです。

この定数をCOUNTと呼びましょう。その後、カウントを開始する数値の重要度を判断する必要があります。確かに、含めることができる最大の数値は255、つまり16進数でFFhです。前のチュートリアルで説明したように、equ命令はレジスタの状況に式を割り当てます。

これは、COUNTを割り当てた数量に関係なく、レジスタの項目と一致することを意味します。値FFhを指定しようとすると、プログラムをコンパイルすると間違いが発生します。

場所FFhである理由は、そのため、アクセスできません。したがって、どのように本物の番号を指定する必要がありますか?確かに、それは少量の横方向の熟考を必要とします。

たとえば、COUNTをアドレス08hに指定すると、これは基本的な目的レジスタの宛先を示します。デフォルトでは、手つかずの領域はFFhに設定されています。したがって、COUNTが08hにつながる場合、最初に電源を入れたときにFFhの値に遭遇します。それでも、COUNTを別の数値に固定するにはどうすればよいですか?適用するのは、最初に評価をこの宛先に「移動」することだけです。

例として、COUNTに85hの値を持たせたいと仮定すると、COUNT equ 85hはポートAのトライステートレジスタの位置であるため、言及できません。正確に達成することは次のとおりです。movlw85hFirst put Wレジスタの85hの値movwf08h

次に、それを08hレジスタに移動します。続いて、COUNT equ 08hを表す場合、COUNTは値85hと一致します。デリケートですね!したがって、最初に定数を決定します。COUNTequ 08h次に、このCOUNTをゼロになるまで1つ減らす必要があります。

「goto」とタグを使用して、これを実現するために設計された1つの命令が存在するのは単純なことです。

適用する命令は次のとおりです。DECFSZCOUNT、1この命令は、「レジスタ(ここではCOUNT)をコンマを追跡する数だけデクリメントします。ゼロに達した場合は、2スポット先に進みます。」コースに配置する前に、まず実際に動作していることを確認しましょう。

実行したのは、最初に定数COUNTを255に設定することです。後続のセグメントは、LABELと呼ばれるタグをdecfsz命令の近くに配置します。

decfsz COUNT、1は、COUNTの値を1つ減らし、最終結果を直接COUNTに保持します。さらに、COUNTの値が0であるかどうかを確認します。

そうでない場合は、その場合、プログラムは次の行にシフトするようにトリガーされます。これで、decfsz命令に戻る「goto」宣言ができました。

COUNTの値が等しい場合、decfsz命令により、プログラムは2スポット先にジャンプし、「Carryonhere」と主張した場所に送信されます。

そのため、ご観察いただけるように、あらかじめ決められた時間、1か所に座るプログラムを実施しました。これは、遅延ループと呼ばれることがあります。

遅延ループを理解する

より大きな遅延が必要な場合は、次のループごとに1つのループを追跡できます。余分なループは、遅延を延長しました。 LEDフラッシュを観察したいと仮定して、少なくとも2つしましょう。これらの遅延ループをプログラムに配置し、コメントを導入して本物のプログラムにすることで達成します。

このプログラムをコンパイルしてから、PICをプログラムすることができます。明らかに、回路を試して、実際に機能するかどうかを確認してください。以下は、PICをプログラムしたらすぐに作成する必要のある回路図です。


よくできました。実際に最初のPICプログラムを作成し、LEDを点滅させる回路を作成することもできます。これまで、これらのコースを受講した場合、35のうち全体で7つの命令を学習した可能性がありますが、これまでのところ、間違いなくI / Oポートを制御している可能性があります。

LEDフラッシュをより速くレンダリングするために遅延ループを変更しようとしますか?本質的にLEDフラッシュを確認するためのCOUNTの最小値は何に見えますか?または、LEDを安定させるために、最初のループの後に3番目または補足の遅延ループを含めることをお勧めします。各遅延ループの一意の定数。

次に、遅延ループを実際にいじって、LEDフラッシュを特定の速度で、たとえば1秒後にレンダリングする可能性があります。次の説明では、サブルーチンと呼ばれるものを利用して、プログラムをコンパクトで基本的なものに維持する方法を見てみましょう。サブルーチンは、コードまたはプログラムの不可欠な部分であり、必要なときに参照される場合があります。サブルーチンは、同じ機能を頻繁に実行する場合に使用されます。

サブルーチンとは

サブルーチンを使用する利点は、プログラム全体で10回ではなく、サブルーチン内で1回値を変更する方が簡単であるだけでなく、プログラムが内部で消費するメモリのレベルを大幅に削減できることです。 PIC。サブルーチンをチェックアウトします。

最初に、サブルーチンに指定を指定する必要があります。この状況では、ROUTINEを選択しました。その後、通常どおりに実行するコードを入力します。そのため、点滅するLEDプログラムの遅延を選択しました。最後に、RETURN命令を入力してサブルーチンを終了します。

プログラムのどこからでもサブルーチンを開始するには、命令CALLをすばやく入力してから、サブルーチンの指定を入力します。

これについてもう少し詳しく検討します。 xxxがサブルーチンの名前であるCALLxxxというプログラムのセクションに到達すると、プログラムはサブルーチンxxxがインストールされている場所にジャンプします。サブルーチン内の命令が実行されます。

命令RETURNが実行されるたびに、プログラムは、CALLxxx命令に続く命令にジャンプしてプリンシパルプログラムに戻ります。

同様のサブルーチンを何度でも呼び出すことができます。これは、サブルーチンを使用するとプログラムの一般的な期間が短くなる理由を説明しています。

それでも、知っておくべき要素がいくつかあります。最初に、私たちの主要なプログラムと同様に、特定の定数を使用する前に、それらを確認する必要があります。

これらは、サブルーチン自体の中で、またはプリンシパルプログラムの開始時に直接確認される可能性があります。私はあなたがあなたのメインプログラムの始めにすべてを認めることをあなたに提案します、それ以来あなたは物事が同じ位置にあることを認めます。次に、メインプログラムがサブルーチンをスキップすることを確認する必要があります。

これが意味するのは、プライマリプログラムの最後に直接サブルーチンを配置する必要があるということです。ただし、「Goto」宣言を使用してサブルーチンの場所から飛び降りる場合、プログラムは続行して、サブルーチンを実装します。にそれを要求するか、そうでなければ。

PICは、サブルーチンとプリンシパルプログラムを区別しません。点滅するLEDプログラムを確認しますが、今回は遅延ループのサブルーチンを使用します。理想的には、プログラムがどれほど複雑でないかを発見し、サブルーチンが実際にどのように適用されるかを発見するかもしれません。

最終的に、遅延ループのサブルーチンを利用することで、プログラムの次元を縮小した可能性があることがわかります。

LEDがオンまたはオフの場合など、遅延が必要になるたびに、基本的に遅延サブルーチンを呼び出します。サブルーチンの終わりに、プログラムは「Call」命令に続く行に戻ります。上の図では、LEDをオンにしています。

その後、サブルーチンに連絡します。その後、プログラムが戻ってきて、LEDをオフに切り替えることができます。サブルーチンが完了した可能性がある場合に備えて、サブルーチンをもう一度呼び出します。プログラムが戻ってきて、プログラムが認識する後続の命令は「gotoStart」です。興味をそそられるかもしれない人のために、私たちの最初のプログラムは120バイトの長さでした。

サブルーチンを使用することで、プログラムのサイズを103バイトに減らすことができました。これはそれほど素晴らしいとは思えませんが、PIC内には全体で1024バイトしかないという事実を考えると、少しでもメリットがあります。

次の説明では、ポートからの読み取りを確認しましょう。

これまで、LEDのオンとオフを切り替えることができるようにポートAに構成してきました。この時点で、ポートのI / Oピンをどのように読み取るかを確認します。

入力/出力ポートの読み取り

これは、外部回路をリンクし、それが提供する特定の出力に影響を与えることができるようにするためです。

以前のコースを覚えている場合、I / Oポートを確立する場合は、バンク0からバンク1にジャンプする必要がありました。最初にそれを実行します。

この時点で、ポートAのビット0を入力に固定しました。ここで、ピンが高いか低いかを調べる必要があります。これを達成するために、2つの指示のうちの1つだけを利用することができます:

BTFSCおよびBTFSS。

BTFSC命令は、「レジスタと指定したビットでビットテストを実行する」ことを意味します。

0の場合は、後続の命令を省略します。 BTFSSは、「レジスタと確立したビットでビットテストを実行する」ことを意味します。 1に設定されている場合は、後続の命令をバイパスします。

どちらを利用するかは、入力を調査するときにプログラムがどのように応答するかによって正確に決まります。例として、入力が1になるのを待っている場合は、次の方法でBTFSS命令を利用できる可能性があります。

ここのコード:

BTFSS PortA、0Goto startここで実行します:

PortAのビット0が1にスケジュールされている場合、プログラムは「Carryonhere」に移行します。

現在、LEDを1つの速度でプロンプトするプログラムを作成しますが、スイッチが制限されている場合は、LEDの点滅が2倍遅くなります。

このプログラムを自分で実行することはおそらく可能ですが、それでも私たちは何とかしてリストを組み込んでいます。

原則を理解しているかどうかを確認するために、プログラム全体を試して作成することができます。 PICのRA0に接続されたスイッチと電源の正のレールを含めて、以前と同等の回路を使用します。

ここで達成したことは、LEDをオンにすることです。その後、スイッチが閉じているかどうかを判断します。

制限されている場合は、次に遅延サブルーチンに接続します。これにより、以前と同等の遅延が発生しますが、この時点で2回連絡しています。

LEDがオフのときはいつでも同じことが当てはまります。スイッチが閉じられていない場合は、以前にオンとオフの期間が記録されています。

これらのレッスンを最初から続けてきたのであれば、PIC16F84の35の指示のうち10を現在発見していることを理解しようとしているかもしれません。そして、これらのすべてのビットは、LEDのオンとオフを切り替えるだけで学習されます。

これまで、PICがLEDを点滅させるように構成してきました。

その後、スイッチを含めることでPICを使用できるようになり、フラッシュ速度を変更できました。

メモリスペースを効率的に使用する

唯一の問題は、プログラムが非常に長く、メモリスペースがかなり非効率的であるということです。初めてコマンドを含めたときは問題ないように見えましたが、もっと簡単な方法で実行できるはずです。確かに、LEDのオンとオフを文字通り切り替えていた方法を分析します。

movlw 02hmovwf PORTAmovlw 00hmovlw PORTA

最初にwレジスタに02hを詰め込み、その後それをPortAレジスタに転送してLEDをオンにしました。スイッチをオフにするために、wに00hをパックした後、PortAレジスタにシフトしました。

これらすべてのルーチンの間に、LEDの点滅を確実に観察できるように、サブルーチンに連絡する必要がありました。

したがって、2セットの情報を2、3回(1回はwレジスタに、次にPORTAに)転送し、サブルーチンを2回(1回はオン、次に1回はオフ)呼び出す必要がありました。したがって、効率を高めてこれをどのように達成できるでしょうか。とてもシンプルです。

XORFと呼ばれる別の命令を使用します。 XORF命令は、提供する情報で指定するレジスタで排他的論理和関数を実行します。続行する前に、排他的論理和が世界で何であるかを明確にする必要があると思います。 2つの入力と1つの出力がある場合、2つの入力が異なる場合、入力は1になります。それらは同じですが、出力はおそらく0になります。以下は、これらをチェックすることを選択した個人向けの真理値表です。

A B F0 0 00 1 11 0 11 1 0

この時点で、Bを以前の出力と同じようにレンダリングし、Aの値を変更した場合に何が起こるかを確認します。

A B F
0 0 0
0 0 0
1 0 1
1 1 0
1 0 1

Aの値を1と同じに維持し、それを出力と排他的論理和すると、出力が切り替わります。真理値表からこれに気付かない場合は、バイナリを利用して以下を確認できます。

0電流出力
EX-OR 11個の新しい出力
EX-ORと10の新しい出力

出力を1と排他的にORすることで、出力を0から1、0に切り替えることができるかもしれません。
したがって、LEDのオンとオフを切り替えるには、数文しか必要ありません。

MOVLW 02h
XORWFドア、1

正確に達成するのは、02hでwレジスタを追加することです。その場合、PortAに何があるかに関係なく、この番号を排他的にORします。ビット1が1の場合、0に変更されます。ビット1が0の場合、1に変更されます。このコードを1〜2回調べて、バイナリの実行方法を表示します。

ドア
00010
xorwf 00000
xorwf 00010
xorwf 00000
xorwf 00010

実際には毎回同じ値をwレジスタにロードする必要はないため、最初にこれを1回実行して、トグルコマンドに戻るだけで済みます。さらに、PortAレジスタの値を修正する必要はありません。理由?確かに、電源投入時は1なので、簡単に切り替えることができます。私は、あるいは電源投入時に0で、今でもそれを切り替えます。

したがって、新しく作成されたコードを見たいと思うでしょう。最初のコードは点滅しているLEDコードを表し、2番目のコードはスイッチが追加されたコードを示しています。

1つの簡単な指示を使用するだけで、プログラムの規模が縮小されたことを確認できれば幸いです。真実は、プログラムをどれだけ削減できるかを表示するために、2つのプログラム、構成されたもの、およびそれらの寸法を次の表に示しました。

プログラム変更寸法(バイト)
LEDオリジナル120の点滅
LEDサブルーチンの点滅103を追加
使用されたLEDXOR機能の点滅91
スイッチオリジナル132付きLED
使用スイッチXOR機能付きLED124。

したがって、いくつかの新しい命令を発見しただけでなく、スクリプトのサイズも確実に縮小しました。

以下では、個々のビットを小刻みに動かし、特定の簡単な演算を実行する方法と、データテーブルを分析します。

論理マネージャー

前回のチュートリアルでは、排他的論理和演算について説明しました。 ExOR関数は、論理演算子として理解されます。

このチュートリアルでは、PICが促進する追加の論理演算子について説明します。ポイントプログラムでは、どのような場合もありませんが、コードの小さな領域を適用することで、演算子を使用する簡単な方法を学習します。

AND AND関数は、基本的に2つのビットを分析し、それらが同じである場合は1を、異なる場合は0を提供します。たとえば、1 AND 1について言及した場合、結果は1ですが、1 AND 0と宣言した場合、結果は0になります。

言うまでもなく、単語を評価することもできます。また、AND関数が実行するのは、2つの用語を少しずつ確認することだけです。以下の例は、2つの8ビットワードが製品とAND演算されることを示しています。

11001011
および10110011
10000011に等しい

私はあなたが同意することを願っています、結果は2つの単語のペアで互いに手をつないでいるときはいつでも1を単に所有するでしょう。たとえば、AND関数を使用してポートを検証できます。

回路にリンクされているいくつかのI / Oピンをチェックしている場合、ピンのいくつかだけがハイである特定の状況に注意する必要があります。その場合、ほとんどの読み取りが可能です。ポート、その後、上記のインスタンスと同じ、調査した条件の結果。

PICは、ANDの2つの要素を提供します。
ANDLWとANDWFです。 ANDLWを使用すると、Wレジスタの詳細と指定した量を使用してAND関数を実行できます。

構文は次のとおりです。ANDLWここで、これはまさにWの内容とのANDになります。

AND関数の結果は、Wレジスタに直接格納されます。
ANDWFを使用すると、Wレジスタと別のレジスタ(たとえばPORT)でAND関数を実行できます。構文は次のとおりです。ANDWF、dこれは、私たちが熱心に取り組んでいるレジスタです。 PORTA、およびdは、結果を配置する必要があるPICを示します。 d = 0の場合、結果はWレジスタに格納され、d = 1の場合、最終結果は指定したレジスタに保存されます。以下のコードの2つの部分は、各AND関数の良い例を示しています。

最初は、PORTAのステータスを調べることです。ここで、入力が1100であるかどうかを確認する必要があります。結果をWレジスタに戻すことができます。

movlw 1100
ANDWF 05h、0 2番目の図は、Wレジスタの内容を確認する場合があります。
ANDLW 1100

または

正確にはXORである1つのOR関数を発見しました。 2つのビットが同じではなく、異なる場合、これは1に発展します。包括的ORであるIORと呼ばれる別のOR関数を見つけることができます。この関数は、いずれかのビットが1の場合、さらに各ビットが1の場合、1を生成します。以下は、これを説明するための明確な真理値表です。

A B O / P
0 0 0
0 1 1
1 0 1
1 1 1

算術演算子とは

追加

この関数は、通常主張していることを実現します。それは2つの数字に貢献します! 2つの数字を加算した結果が8ビットを超える場合、その場合はCARRYフラグが設定される可能性があります。 CARRYフラグはアドレス03hビット0にあります。

このビットがスケジュールされているとき、2つの数字は8ビットを超えました。 0の場合、その結果は8ビット以内にあります。以前と同様に、PICは2つのスタイルのADD、具体的にはADDLWとADDWFを提供します。ご想像のとおり、これは上記の関数とまったく同じです。 ADDLWは、私たちが規定するWレジスタの内容を提供します。構文は次のとおりです。ADDLWADDWFは、Wレジスタと指定したその他のレジスタの内容を追加します。

構文は次のとおりです。ADDWF、dはここにあります

サブ

現時点では、この関数が何を実行するかを推測することはできないと思います。確かに、あなたはそれを疑った、この機能
あるビットを別のビットから減算します。ここでも、PICはSUBLWとSUBWFの2つのテイストを提供します。構文は、明らかにADDの代わりにSUBと入力することを除けば、ADD関数の構文とまったく同じです。

インクリメントPICに1から数字を含めたい場合は、絶対にADD機能を利用して、数字の1を利用することができます。 〜これの難しさは、最初にFigureをWレジスタに配置し、次にADDLW1コントロールを使用してそれをインクリメントする必要があることです。レジスターに1を含めたい場合は、さらに悪化する可能性があります。最初に番号1をWレジスタに配置し、その後ADDWF、1を使用する必要があります。したがって、たとえば、場所0Cに1を含めるには、スクリプトの次の部分を所有する必要があります。

movlw 01
addwf 0c、1

これを行うためのより簡単な方法があります。コマンドINCFを実行できます。構文は次のとおりです。INCF、dここで、は関係するレジスタまたは場所であり、dは結果を配置する必要があるPICを示します。 d = 0の場合、結果はWレジスタ内にあり、d = 1の場合、結果は指定したレジスタに設定されます。

この個別の命令を利用することで、実際にコーディングの50%を実行できます。結果をWレジスタに復元したい場合、その場合は上記のインスタンスを使用して、0Cの項目をWレジスタに戻すための追加のコマンドを含める必要があり、その後、0Cレジスタをnoに戻します。それが何であったかは関係ありません。

インクリメントコマンドがあります。 INCFSZです。このコマンドは、指定したレジスタをインクリメントする場合がありますが、インクリメント後にレジスタが0に等しい場合(1から127を含めるときに発生します)、その後、PICはおそらく後続の命令を渡します。以下のコードの部分はこれを反映しています。

ループincfsz0C
後藤ループ


プログラムの残り。

コードの上記の部分では、0Cが1ずつインクリメントされます。次に、PICにLoopという名前のタグに戻り、0Cを再び1インクリメントするように通知する命令を所有します。これは、0Cが127に等しくなるまで続きます。この状況では、0Cを1インクリメントすると、0Cは0に一致します。INCFSZ命令は、PICに後続の命令(この場合はgoto宣言)を省略するように通知できます。したがって、PICはプログラムの残りの部分を進めます。

デクリメント

これまでのトレーニングでデクリメント関数について説明したので、これ以上修正しません。

補体

この議論の最後の命令は、私たちが規定するレジスタのすべてのビットを逆にします。構文は次のとおりです。COMF、dここで、

ビット演算を理解する

これは、たとえば、ポートのピンを出力から入力にすばやく交換するためなどに利用できます。ビット関数を使用すると、式内で1つのビットを形成できます。それらは、私たちが規定するレジスタまたは数値の単一ビットを続行、設定、および削除することを可能にします。

このコースの終わりに、順方向に進み、次に逆方向に進むシーケンスライトのセットを作成するように設計されたプログラムを開示します。これは、ポートを式で排他的論理和する排他的論理和関数を調べたときに、以前に達成されたことを確認しました。これまで、PICでポートを確立するときに、いくつかのビット機能に気づきました。

ここでそれらの利用を繰り返します。

BCF

この命令は、指定したレジスタに規定されているビットを消去します。構文
は:
BCF、

以前、これを使用して、STATUSレジスタのビットを削除することにより、ページ1からページ0に変更しました。同様に、これを使用して、任意の異なるレジスタ/場所でビットを0に固定することができます。たとえば、セクション0Cに保存されている11001101の3番目のビットを0に設定したい場合は、次のようになります。
インサート:

BCF 0C、03

BSF

この命令は、指定したレジスタの1に指定したビットを修正します。これを以前に使用して、ページ0からページ1に進みました。構文はBSF 、、であり、上記のBCFとまったく同じ方法で使用されます。

BTFSCこれまで、レジスタのビットを設定またはクリアすることができました。しかし、基本的にビットがレジスタの1か0かをチェックする必要があるかどうか想像してみてください。

確かに、BTFSCを使用することは可能です。ビットテストレジスタFと記載されており、クリアされている場合はスキップします。この命令は、レジスタで指定したビットを分析します。ビットが0の場合、命令はPICに後続の命令をバイパスするように通知します。

キャリーフラグなどのフラグをチェックしたい場合は、この命令を利用できます。これにより、STATUSレジスタを読み取り、個々のビットを検索して、どのフラグが修正されているかを知る必要がなくなります。 29たとえば、2つの数字を追加した後で、キャリーフラグが1に設定されているかどうかを確認したい場合は、次のように入力できます。

BTFSC 03h、0
1に設定されている場合は、ここで続行します
または0に設定されている場合はここ

ビットのステータスが1の場合、BTFSCに続く命令が完了します。 0に設定されている場合、後続の命令はスキップされます。コードの次の部分は、それが使用される可能性があることを示しています。

ループ:


BTFSC 03,0
後藤ループ

上記のコードでは、STATUSレジスタのビット0(またはキャリーフラグ)が0に定義されている場合、PICは単にループから抜け出します。そうでない場合、gotoコマンドが実行されます。

BTFSS

この命令は、ビットテストレジスタF、および設定されている場合はスキップを示します。これは、評価しているビットが0ではなく1に設定されている場合、PICが後続の命令を省略することを除けば、BTFSC命令に匹敵する可能性があります。

CLRF

この命令は、レジスタの詳細全体を0に修正します。構文は次のとおりです。

CLRF
CLRF 85hを適用することにより、以前にこれを使用してポートの出力を0に設定しました。さらに、CLRFを利用して、出力するすべてのピンを含むようにポートを固定するために使用しました。
05時間。

CLRW

これは、Wレジスタをクリアすることを除いて、CLRF命令に似ている可能性があります。構文は非常に単純です。

CLRW

RLFとRRF

これらの方向は、レジスタ内のビットをレジスタ内の左(RLF)または右(RRF)に1つのスロットで転送します。たとえば、00000001が必要でRLFを使用した場合、その場合は00000010を所有する可能性があります。この時点で、10000000があり、RLF命令を適用した場合はどうなりますか?確かに、1はキャリーフラグに配置されます。 RLF命令をもう一度適用した場合、最初に1が再び表示されます。 RRF命令についても同様ですが、逆になります。以下の例は、RLF命令の場合を示しています。ここでは、レジスタの8ビットとキャリーフラグを確認できます。

C 87654321
0 00000001
RLF 0 00000010
RLF 0 00000100
RLF 0 00001000
RLF 0 00010000
RLF 0 00100000
RLF 0 01000000
RLF 0 10000000
RLF 1 00000000
RLF 0 00000001

サンプルプログラム

これから、コンパイルして駆動できるサンプルコードを見ていきます。 PortAビット0から始まり、PortBビット8に進み、シーケンスライトを生成します。
その後、戻ります。
各ポートピンにLEDを接続します。私たちは少し持っているでしょう
このチュートリアルで指摘されている手順。

TIME EQU9FH遅延ループの変数。
PORTB EQU06HポートBアドレス。
TRISB EQU86HポートBトライステートアドレス。
PORTA EQU05HポートAアドレス。
TRISA EQU85HポートAトライステートアドレス。
STATUS EQU03Hページ選択レジスタ。
COUNT1 EQU0CHループレジスタ。
COUNT2 EQU0DHループレジスタ。

BSFステータス、51ページに移動
MOVLW00Hとセットアップ
MOVWFTRISBポートAとBの両方
MOVLW 00Hを出力し、
MOVWF TRISAは、
BCFステータス、5ページ0。
MOVLW00HポートAをクリアします。
MOVWFドア

メインプログラムの開始

RUNMOVLW
01H最初のビットを設定MOVWF
ポートB.CALLのPORTB
遅延しばらく待つCALL
ディレイ
ポートBのビットを左に移動してから、pause.RLF
PORTB、1CALL
DELAYCALL
DELAYRLF
PORTB、1CALL
DELAYCALL
DELAYRLF
PORTB、1CALL
DELAYCALL
DELAYRLF
PORTB、1CALL
DELAYCALL
DELAYRLF
PORTB、1CALL
DELAYCALL
DELAYRLF
PORTB、1CALL
DELAYCALL
DELAYRLF
PORTB、1CALL
DELAYCALL
DELAYRLF
PORTB、1これはビットをキャリーフラグに移動します
次に、ポートAに移動し、ビットを左に移動します。RLF
PORTA、1これにより、ビットがゼロフラグからPortACALLに移動します。
DELAYCALL DELAYRLF
ドア、1CALL
DELAYCALL
DELAYRLF
ドア、1CALL
DELAYCALL
DELAYRLF
ドア、1CALL
DELAYCALL
ディレイ
ポートARRFにビットを戻します
ドア、1CALL
DELAYCALL
DELAYRRF
ドア、1CALL
DELAYCALL
DELAYRRF
ドア、1CALL
DELAYCALL
DELAYRRF
PORTA、1これにより、ビットがゼロフラグに移動します。ビットを移動します。
ポートBRRFに戻る
PORTB、1CALL
DELAYCALL
DELAYRRF
PORTB、1CALL
DELAYCALL
DELAYRRF
PORTB、1CALL
DELAYCALL
DELAYRRF
PORTB、1CALL
DELAYCALL DELAYRRF
PORTB、1CALL
DELAYCALL
DELAYRRF
PORTB、1CALL
DELAYCALL
DELAYRRF
PORTB、1CALL
DELAYCALL
DELAYさあ、始めたところに戻ってきました、GOTO
RUNまた行きましょう。

トレーニングセットには、データテーブルを利用できる優れたオプションがあります。

データテーブルは、データ引用の単なるリストであり、いくつかの考慮事項に基づいてすべてが調べられます。
たとえば、入力ピンが1秒間にハイになるインスタンスの数をカウントするPICを利用する回路を作成できます。その後、7セグメントディスプレイに番号を表示できます。

タイミングが開始されるとすぐに、PICはピンがハイになる回数のカウントを開始します。 1秒後、テーブルにアクセスしてデータを一瞥し、ピンが高くなった状況の量を表す番号をディスプレイに表示する必要があります。 PICが見積もりを完了するまで、数値がどうなるかを判断できないため、これは有益な場合があります。

表を利用することで、PICがどの図を描くかを決定することができます。この時点で、データテーブルがどのように機能するかを説明する前に、PICがプログラムの動作中に、プログラム内の所在のパスを維持していることをお伝えする必要があるかもしれません。

これは、BASICで特定のプログラミングを実行したことがある人にとっては便利です。それ以外の場合は、心配しないでください。理論について学び続けることをお勧めします。以下に示すようなBASICプログラムがあると想像してください。

10年K = 0
11 K = K + 1
12 K> 10の場合THENGOTO 20 ELSE GOTO 11
20プリントK
21終了

プログラムは10行目から始まります。Kが0にスケジュールされるとすぐに、次に11行目に進みます。Kに1を含めた後、12行目に進みます。

この時点で、Kが10より大きいかどうかが気になるかもしれません。そうである場合は、次に20行目に進むか、11行目に戻ります。

20行目はKを文書化し、21行目はプログラムを終了します。 BASICは、ラベルが許可されていないため、プログラマーが問題の場所を記録するのを支援するためにライン統計を採用しています。 PICは目的地間を脱出するためにラベルを採用しています-それとも本当にできますか?

ラベルを使用して、問題がどこにあるかを認識し、検索する場所を簡単な方法でPICに通知できるようにします。

正確に発生するのは、PICがプログラムカウンタと呼ばれる内部ラインカウンタを利用することです。現在の命令があるメモリ宛先のプログラムカウンタ(PCと略記)トレイル。

選択したラベルにアクセスするようにPICに通知するたびに、PICはメモリスポットを理解するため、そのメモリの宛先を確認するまでPCを拡張します。これは、上記のBASICプログラムをチェックするのとまったく同じ方法です。以下は、すべての命令の横にあるメモリスペースまたはPCのアイテムを含むコードのセグメントです。

PC命令0000movlw 03
0001 movwf 0C
0002ループdecfsc0C
0003gotoループ
0004終了

上記のデモンストレーションでは、PCを0000に固定しました。これには、命令movlw 03があります。PICがこのデータを実装すると、後続の命令がスキャンされるようにPCがインクリメントされます。この時点で、PICはmovwf0Cを表示します。 PCは再びインクリメントされます。

現在、PICはdecfsc0Cを研究しています。 0Cの詳細が0でない場合、PCは1ずつインクリメントされ、次の命令goto Loopは、PCに位置0003に戻るように通知します。このループがあります。 0Cの詳細が0の場合、PCは2ずつインクリメントすることをお勧めします。単に、後続の命令を省略してください。

データテーブルを理解する

これにより、PCが位置0004に配置され、プログラムが終了します。宛先はアセンブラーによって固定されており、通常、PCが何を達成しているかを気にする必要はありません。それまでは、データテーブルを利用するときと同じように制御する必要があります。データテーブルがどのように機能するかを説明する最も便利な方法は、図から始めることです。

PC equ 02
movlw 03
コールテーブル

テーブルaddwfPC
retlw 01
retlw 02
retlw 03
retlw 04
retlw 05
retlw 06
retlw 07
戻る

最初の命令は、ラベルPCにプログラムカウンタ(02h)のアドレスを割り当てることです。 03hの値をwレジスタに入れてすぐになります。その後、テーブルに連絡します。サブルーチンテーブルの最前行は、Wレジスタ(03h)の詳細をプログラムカウンタに追加します。

これにより、プログラムカウンタが3上昇するか、別の言い方をすれば、プログラムカウンタが3行下に進むように刺激されます。カウンターが3行下に到着すると、PICは命令retlwを認識します。このコマンドは、それに続く値をWレジスタに送信し、その後、サブルーチンから返されます。 RETLWは基本的に、Return、Literal toWを意味します。

Returnという単語の後にコンマを置いたのを見てください。サブルーチンに入っているので、その表面にReturn命令が必要です。したがって、命令のRET。 RETLW命令の後には数値があり、これはまさにWレジスタに入れられるものです。

この例では図3です。この図がテーブルサブルーチンのプログラムカウンタと組み合わされている限り、Wレジスタに任意の数量を指定できます。retlw命令を検出します。上の図では、これは1から7までの任意の数を所有できることを意味します。サブルーチンを通過すると、プログラムの追加セクションの実行を終了できる場合があります。このため、通常、PICプログラムの最後に正確にデータテーブルを配置するのは賢明な方法です。したがって、その場合にオーバーシュートを実行すると、とにかくプログラムの最後に到達します。

割り込みのトピックは、通過するのに最も長く、最も困難になる可能性があります。

割り込みを詳細に説明する単純な方法は見つかりませんが、このパートの終わりに少し運が良ければ、独自のプログラムに割り込みを適用できる可能性があります。
セクションを2つの段階に分けました。これは、トピックをセクションに分割できるようにすることと、理解しやすいように便利なプリットアップを提供することです。

割り込みとは正確には何ですか?確かに、この用語が示すように、割り込みは、マイクロプロセッサ/マイクロコントローラが何か別のことが起こる可能性があることを実行することを妨げる技術または信号です。

毎日のイラストをあげさせてください。自分の家でリラックスして、他の人と会話していると思います。突然電話が鳴ります。

あなたは話すのをやめ、電話をつかんで発信者と話します。電話でのやり取りが終わったら、電話が鳴る前に個人との会話に戻ることにします。あなたが誰かとチャットしている間、主要なルーチンを考えることは可能です、電話の呼び出し音はあなたの会話を混乱させる原因になります、そしてルーチンの中断は電話で話す方法です。

電話での話し合いが終了すると、チャットの主要なルーチンに戻ります。この図は、まさにプロセッサに割り込みをかけてアクションを実行する方法です。

プライマリプログラムは動作しており、回路内で特定の機能を実行していますが、中断が発生すると、別のルーチンが実行されている間、プライマリプログラムは停止します。ルーチンが終了すると、プロセッサは前と同じようにプライマリルーチンに戻ります。

割り込みを理解する

PICには4つの割り込みソースがあります。それらはいくつかのグループに分けることができます。 2つはPICの外部で利用できる割り込みのソースであり、他の2つは内部プロセスです。ここで2つの外部タイプを明確にしましょう。他の2つは、タイマーに到達してデータを保存したら、さまざまなチュートリアルで説明します。

PICのピン配列を確認すると、ピン6がRB0 / INTであることがわかります。この時点で、RB0は明らかにポートBのビット0です。INTは、外部割り込みピンとしても構成できることを示します。さらに、ポートBのピン4〜7(ピン10〜13)も割り込みに使用できます。 INTまたは別のポートBピンを使用する前に、2つのタスクを実行する必要があります。まず、割り込みを利用することをPICに通知する必要があります。

次に、I / Oピンとしてではなく割り込みとして使用するポートBピンを指定する必要があります。 PIC内には、INTCONと呼ばれる、アドレス0Bhにあるレジスタがあります。このレジスタには、有効または無効にできる8ビットがあります。 INTCONのビット7はGIEとして知られています。これは、Global InterrnguptEnableです。これを1に修正すると、割り込みを使用することがPICに通知されます。

INTCONのビット4は、INTE、INTerruptEnableとして知られています。このビットを1にすると、RB0が割り込みピンになることをPICに伝えます。 RBIEと呼ばれるビット3を構成すると、ポートBのビット4〜7を使用することがPIcに通知されます。この時点で、PICはこのピンがハイまたはローになる可能性があることを理解し、実行中の動作を停止して割り込みを続行する必要がありますルーチン。この時点で、割り込みが信号の立ち上がりエッジ(0Vから+ 5V)または立ち下がりエッジ(+ 5Vから0V)に変換される可能性があるかどうかをPICに通知する必要があります。

簡単に言えば、信号が低から高に、または高から低に移動するたびにPICが割り込みをかけるようにしますか。延滞により、これは立ち上がりエッジに配置されるように確立することができます。

エッジの「トリガー」は、アドレス81hのOPTIONレジスタと呼ばれる追加のレジスタでスケジュールされます。私たちが熱心に取り組んでいるビットはビット6で、しばしばINTEDGと呼ばれます。

これを1に設定すると、PICが取り付けエッジで中断するようにトリガーされ(デフォルト状態)、0に設定すると、PICがスライドエッジで中断するように刺激されます。 PICを立ち上がりエッジでアクティブにしたい場合は、このビットに対して何もする必要はありません。

この時点で、悲しいことに、オプションレジスタはバンク1にあります。つまり、バンク0からバンク1に変更して、オプションレジスタのビットを設定し、その後バンク0に戻します。ここで重要なのはすべてのビットを実行することです。バンク1のレジスタは、たとえばポートピンの確立など、1回のストライキで登録され、その後、完了したらバンク0に戻ります。

その結果、どのピンがおそらく割り込みになるのか、どこでトリガーするのか、割り込みが発生するたびにプログラムとPICで何が起こるのかをPICに通知しました。いくつかのことが起こります。最初に、「フラグ」がスケジュールされます。

これにより、PICの内部プロセッサに割り込みが発生したことが通知されます。次に、プログラムカウンタ(前のチュートリアルで説明しました)は、PIC内の特定のアドレスにヒントを提供します。これらすべてを個別にすばやく確認しましょう。割り込みフラグINTCONレジスタのビット1は、INTFと呼ばれる割り込みフラグです。この時点で、割り込みが発生するたびに、このフラグは1に固定される可能性があります。

割り込みがない場合、フラグは0に設定されます。それだけでなく、ほぼすべてが達成されます。この時点で、「ポイントは何ですか?」と考えているかもしれません。確かに、このフラグが1にスケジュールされていても、PICは別の割り込みに反応できず、反応しません。したがって、割り込みが発生することを表現しましょう。フラグは1に固定される可能性が高く、PICは割り込みを処理するためにルーチンに移動する可能性があります。

このフラグが1に固定されておらず、PICが割り込みへの応答を継続することを許可されている場合、ピンを継続的にパルスすると、PICは割り込みルーチンの最初に戻る可能性があり、決して完了しません。電話のイラストに戻ると、電話を持ち上げるのと似ています。話し合いを始めるとすぐに、別の人があなたと話したいので、もう一度鳴り始めます。

1つのダイアログを完了してから、もう一度電話を取り、次の個人と話すことをお勧めします。このフラグには小さな問題があります。 PICはこのフラグをすぐに1に設定しますが、再び0に設定することはありません。そのアクティビティは、プログラマー、つまりあなたが実行する必要があります。私は確かに推測しているので、これは簡単に実行でき、PICが割り込みルーチンを実行した後に実行する必要があります。

メモリの場所最初にPICの電源を入れたとき、またはリセットが存在する場合は常に、プログラムカウンタは0000hに対処するように指示します。これは、プログラムメモリの最初にすぐに発生する可能性があります。ただし、割り込みが発生した場合、プログラムカウンタはアドレス0004hを示します。

したがって、割り込みを含むプログラムを作成している間、最初にPICにアドレス0004hをホップオーバーするように通知し、プログラムの残りの部分とは別のアドレス0004hで始まる割り込みルーチンを維持する必要があります。

これは手間をかけずに実行できます。最初に、ORGと呼ばれるコマンドでプログラムを開始します。このコマンドは、起点または開始を示します。私たちはそれに住所を付けます。 PICはアドレス0000hで始まるため、ORG0000hと入力します。その後、アドレス0004hをバイパスする必要があります。これは、プライマリプログラムのヒントとなるラベルを付けたGOTO命令を付けることで実現します。

その後、もう1つのORGを使用してこのGOTOコマンドを順守します。この瞬間、アドレスは0004hです。このコマンドの後に、割り込みルーチンを挿入します。この時点で、2番目のORGコマンドの直後に割り込みルーチンを入力できるか、割り込みルーチンを指すGOTOステートメントを配置できる可能性があります。

それは本当にあなたの側のオプションに関連しています。割り込みルーチンの終わりに到達したことをPICに通知するには、コマンドRTFIEをルーチンの終わりに向けて配置する必要があります。このコマンドは、割り込みルーチンからの復帰を意味します。 PICがこれに気付いている間、プログラムカウンタは、割り込みが発生する前のPICの最終位置を示します。上記を表示するためのコードの簡単なセクションを以下に示します。

割り込みを利用する際に通知する必要のある事項がいくつかあります。最初は、プライマリプログラムと割り込みルーチンで同じレジスタを使用している場合、割り込みが発生するとレジスタの詳細が変わる可能性が高いことに注意してください。

たとえば、wレジスタを利用してデータをポートAプライマリプログラムに転送しましょう。したがって、割り込みルーチンでwレジスタをさらに利用して、データをある宛先から別の宛先にシフトすることができます。

注意しない場合、wレジスタには、割り込みルーチンにある間に受信した最後の値が含まれるため、割り込みから戻ると、この情報は以前に所有していた値ではなく、ポートAに配信されます。割り込みが発生しました。

これを回避する手段は、割り込みルーチンで再度使用する前に、wレジスタの詳細を一時的に保存することです。 2つ目は、1つの割り込みが発生してから次の割り込みが発生するまでの間に遅延が見られるという事実です。ご存知のとおり、PICには外部クロックがあります。これは、水晶または抵抗とコンデンサの組み合わせである可能性があります。

このクロックの周波数に関係なく、PICはそれを4で除算し、その後、これを内部タイミングに使用します。たとえば、PICに4MHzの水晶がリンクされている場合、その場合、PICは1MHzで命令を実行します。この内部タイミングは、命令サイクルとして知られています。この時点で、データシートには、割り込み間で3〜4回の命令ラウンドを有効にする必要があると(間違いなく小柄に印刷されています)と記載されています。

私は4ラウンドを有効にすることです。遅延の背後にある理由は、PICが割り込みアドレス、フラグにジャンプし、割り込みルーチンから離れて到着するのに時間がかかるためです。したがって、代替回路を使用してPICの割り込みをアクティブにする場合は、このことに注意してください。

この時点でのポイントは、ポートBのビット4〜7を割り込みとして使用する場合です。ポートBの特定のピンを選択して割り込みとして機能させることはできません。

したがって、これらのピンを許可した場合、それらはすべて入手可能である可能性があります。したがって、たとえば、ビット4と5を単純に持つことはできません。ビット6と7は同時に権限を与えられる可能性があります。割り込みを表す4ビットを取得する目的は正確には何ですか?確かに、4つの回線のいずれかがハイになった場合に備えて、回路がPICに接続されている可能性があります。その場合、これはPICに即座に影響を与える必要がある問題である可能性があります。

この一例は、4つのセンサーがポートBのピン4〜7にリンクされているホームセキュリティアラームです。特定のセンサーは、PICにアラームをトリガーするように促すことができ、アラーム信号ルーチンは割り込みルーチンです。これにより、ポートを常にチェックする必要がなくなり、PICはさまざまな問題を続行できます。次のチュートリアルでは、割り込みを管理するプログラムを作成します。

前回のチュートリアルでは多くの基本を扱ったので、最初のプログラムを作成する時が来たと感じています。

私たちが書くプログラムは、スイッチをオンにした回数を数え、その数を表示します。

プログラムは0から9までカウントされ、バイナリ形式で4つのLEDで表示でき、入力または割り込みはRB0で実行される可能性があります。

私たちが実行しなければならない最も重要なことは、割り込みが発生するたびにプログラムカウンタが指すアドレスを飛び越えるようにPICに通知することです。

16進数を表示する独自の方法を採用していることがわかります。私が起こる前に、hが16進数を示すF9hを適用しました。これを0xF9と書くことができます。これは、これから採用する構造です。

次に、割り込みを使用することをPICに通知する必要があり、RB0ピン6を割り込みピンとして使用しています。

bsf INTCON、7GIE –グローバル割り込みイネーブル(1 =イネーブル)
bsf INTCON、4INTE-RB0割り込みイネーブル(1 =イネーブル)
万が一に備えて割り込みフラグをクリアします(何も信用しません!)
bcf INTCON、1INTF-万が一の場合に備えてフラグビットをクリアします

現在、2つのポートを確立する必要があります。現在RB0を割り込みピンとして使用しているため、これを入力として確立する必要があることに注意してください。

COUNTという変数を使用して、スイッチカウントの数を格納します。ポートAの値を単純にインクリメントすることもできますが、割り込みルーチンを作成するときに変数を使用している理由がわかります。

したがって、主要なプログラムが構成され、この時点で、割り込みが発生するたびにどのように進めるかをPICに通知する必要があります。この例では、割り込みはおそらくスイッチになります。 PICに求めているのは、スイッチが制限されるたびに調整可能なCOUNTの1つです。

それでも、スイッチが0から9にシャットダウンする回数を示したいだけです。上記では、割り込みが発生するたびにポートAの値を単純にインクリメントできる可能性があると述べました。ただし、ポートAには5ビットがあるため、ポートを単純にインクリメントした場合は、31の最大カウントを取得します。31まで移動しないことを選択した理由はいくつかあります。

最初は、7セグメント画面を使用します。これは最大で0から15(16進数で0からF)までしか移動できません。次に、過去数回のレッスンで遭遇した算術コマンドのいくつかをさらに紹介したいと思います。

したがって、割り込みルーチンを続行します。現在、最初に達成しなければならないのは、COUNTの内容をPORTAにシフトするためにこれを適用しているため、wレジスタの詳細を簡単に保存することです。保存しない場合は、算術演算により、まったく異なる数値を配信できる可能性があります。したがって、最初にそれを達成しましょう。

この時点で、COUNTの値が9以上であるかどうかがわかります。ここで実行する必要があるのは、COUNTが9を超える場合、0に戻すか、メインプログラムに戻って、ポートAに配信できることを確認することです。BTFSSコマンドは、後続の
キャリーフラグがスケジュールされている場合の命令、つまりCOUNT = 10:

今やるべきことは、まとめて入力することと、定数の値を決定することだけです。これは、プログラムの開始時に実行できます。

スイッチをオンにするたびに、LEDは0000から1010までバイナリでカウントアップし、その後0000に戻ります。

次の図は、上記で説明したコードと互換性のある回路図を示しています。興味深いことに、タイミングコンデンサが設計に含まれていることがわかります。これは、その間にコンデンサがない場合に備えて、コンデンサが含まれないようにする自由を手に入れるためのちょっとした策略です。

ここで、容量は、発振器のピンとグランド間の浮遊容量を介して作用します。
もちろん、漂遊値は特定の条件によって異なる可能性があるため、実際にはコンデンサを回避するための非常にインテリジェントな方法ではないように思われるかもしれません。

回路で目撃できるもう1つのセクションは、スイッチ全体のネットワークの非難です。これにより、機械的な切り替え中の干渉が防止され、切り替えが単一のトグルまたは複数のトグルであった場合にPICが混乱するのを防ぎます。




前:プログラム可能な双方向モータータイマー回路 次へ:昇降圧​​回路のしくみ