PIC FAQのページ 

PIC-MLで出た話題を適当に整理してみました。(回答者氏名が不明な場合はご容赦を)
PIC-MLへの参加、脱退方法については、 後閑さんのHP か、小林さんのHP を見て下さい

小林さんのHPは事故によりサーバー内のサービス内容の大半が失われてしまった様です。
(2001/7現在)現在は http://www.mars.dti.ne.jp/~itow/PIC/ で新しいMLが立ち上がってい
ます。



 

尚、当ページの内容については構成の都合上MLの回答をベースに私が勝手に編集しておりますので、ご容赦を。
当ページへのご意見、要望、苦情がありましたら、こちら へどうぞ。(特に内容に間違いがありましたら、具体的に指摘して頂けると幸いです)
MLに書く場合の注意  質問内容は整理して具体的に(トラブルの状態、疑問点など)書いたほうが、回答も得やすいと思いますよ!

Q1 PICの資料は何処から入手できるの?
Q2 ソフトウエアリセットはできるか?問題点は?
Q3 電池駆動で消費電力を抑えるためクロックをコントロールしたい。

Q4  PIC16F877等(ADコンバーターのあるタイプ全般)でTRISAで出力に設定してもPORTAが使えない。
Q5 割込み時のレジスタの退避先は?退避するレジスタは?
Q6 MPASMでコンフィグレーションビットを設定する方法は?
Q7  PIC16F877でプログラムを書き込んで、実行すると暴走します、またはプログラムが消えます。
Q8  PIC16F877でAD変換のデーターがやたら大きな値になります。
Q9  PIC16F84で電源OFF時に不安定になります。
Q10 EEPROM内蔵のPIC(877,84)の初期データーの書き込みの方法。
Q11  MPLABでhexファイルをアセンブラ表示させたい。
Q12  MPLABでデバッキング中に入力したい。
Q13 MPASMで秋月のアセンブラみたいにレジスタを予約したい。
Q14 PICにスピーカーや圧電素子をつないで音を出したい。
Q15  PIC12C509などでRETURNがなくRETLW kという命令しかないが、RETLWは普通どんな使い方があるのか?
Q16 RETLW命令を使ったテーブル(表)参照で、ジャンプ先から戻ってこなくなるのは何故?
Q17  プログラムをアセンブルしたらIllegal opcodeとかmissing operatorだのエラーメッセージが出ます。
Q18 PIC16F84-10が10MHz動作で電源電圧5V時は正常に動くのですが4.3V程度ではうまく動きません。
Q19  PIC18シリーズとは?またどこで入手できますか?
Q20 PIC16F877のA/Dに可変抵抗(50k Bカーブ)で分圧して入力しているのですが変換結果がとても不安定なのです。
Q21 16ビットバイナリーからBCD変換のアルゴリズムは?
Q22 PC-UNIX(Linux、FreeBSD)での開発ツールは?
Q23 PIC16F87xのデバッグモードについて解説している資料はありますか?
Q24 シリアルEEPROM(IIC)のアクセスがうまくいきません。
Q25 アセンブラの乗算、除算のしかたを教えてください。
Q26 FSRの有効な使用方法は?
Q27  コードを追加するたびに新しくCALL、GOTO文に「Message[]:Crossing page boundary」ってエラーが出るんですけどなんとかなりませんか?
Q28 割込み処理中に別の割込みが入ったらどうなりますか?(多重割り込みの処理)
Q29 パラレルスレーブポートの用途は?
Q30 PIC16C73の替わりにPIC16F873を使いたいのですがどこが違いますか?
Q31 BSF,BCF命令などでポートのビットをセットした時に不安定な動作になるときがあるんですが?
Q32 TMR0割り込みを使って制御したいのですが、割り込みがかかるタイミングが1ステップずれる事があります。誤差になりませんか?
Q33 PIC内のプログラムを読み出す事はできますか?
Q34 16F84でPORTBを入力にして外部回路に接続していますが、外部回路の電源を入れるとPIC側の電源を入れないでも動作してしまいます。
Q35
Q36
Q37
Q38
Q39
Q40
Q41
Q42
Q43
Q44
Q45
Q46
Q47
Q48
Q49
Q50
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Q1 PICの資料は何処から入手できるの?

マイクロチップのWebサイトにあります。米国本社 http://www.microchip.com 日本支社 http://www.microchip.co.jp です。和文の資料も一部ですがあります。また、あなたが英語に堪能なら本家FAQ集が ここ にあります。(本家日本語FAQ集 もどうぞ)
(回答者 吉田氏)

Q2 ソフトウエアリセットはできるか?問題点は?

ソフトウエアリセットに関する資料は、micriochipの日本支社のウエブサイトのセミナー資料を参照すると良いでしょう。PICシリーズのスタックカウンターはリング状なのでスタックのオーバーフローに関しては特に考慮する必要が無いのですが、ソフトウエアリセットではI/Oやレジスタの初期化は行われませんので、その点は考慮しなくてはいけないかも知れません。わざとWDTリセットを作動させると言う手もあります。
(回答者 吉田、小倉氏)

Q3 電池駆動で消費電力を抑えるためクロックをコントロールしたい。

この方法もセミナーの資料にあります。CR発振回路の時定数RをI/Oポートでコントロールします。
    Vcc
     T         PICmicro
     l       +---------+
     R1      |         |
     |       |         |   I/OをHiにすると、Rが小さくなり周波数がUPする
     +---R2--+ I/O     |
     |       |         |
     |       |         |
     +-------+ OSC1    |
     |       |         |
     C       |         |
     |       +---------+
     V
    Gnd
(回答者 小倉氏、セミナー資料)

Q4  PIC16F877等(ADコンバーターのあるタイプ全般)でTRISAで出力に設定してもPORTAが使えない。

ADコンバータを内蔵するPICはADCON1レジスタでデジタルとアナログで使うビットを指定する必要があります。デジタルに設定したビットの入出力の設定はTRISAレジスタで行います。
(回答者 飯田氏)

Q5 割込み時のレジスタの退避先は?退避するレジスタは?

PICには全てのバンクで同一のRAMにアクセスできる領域(share領域)がありますので、割込み時のレジスタ等の退避先に設定すると便利です。退避するレジスタはWreg、STATUSの他、割込み先で変更される変数などです。間接アドレッシングを使うならFSRも退避が必要です。PCLATHはプログラム全体が2Kを超える様なら退避する必要があるでしょう。
(回答者 伊藤、落合氏)

Q6 MPASMでコンフィグレーションビットを設定する方法は?

コンフィグレーションビットの設定の書式は __CONFIG   _CP_OFF & _WDT_OFF & _HS_OSC & _BODEN_ON & _PWRTE_ON & __WRT_ENABLE_ON & LVP_OFF & _DEBUG_OFF & _CPD_OFF などと書きます。因みに CONFIGの前の'_'は2個です。
(回答者 田辺、さかい、高原氏)

Q7  PIC16F877でプログラムを書き込んで、実行すると暴走します、またはプログラムが消えます。

LVP(低電圧プログラミング)がONの場合、RB3/PGMをプルダウンしておかないと、プログラムが書き換わったり、消えたりして暴走状態になる場合があります。 またLVPを一旦OFFにして書き込んだ場合LVPをONに戻す事は出来ません。(マイクロチップFAQより)(戻せるそうです。2001/03/10確認)

Q8  PIC16F877でAD変換のデーターがやたら大きな値になります。

PIC16F877のADコンバーターは10bitなのでAD変換データーはADRESHとADRESLに格納されますが、ADCON1レジスタの7bit目のADFMが0の時にはADRESHの上位からデーターが格納されADRESLの下位6bitには全て0が入りますので、ADRESH,ADRESLを16bitデーターとして処理すると、AD変換値の64倍のデーターになります。ADFM=1とするか64分の1のデーターに変換しなくてはいけません。

Q9 PIC16F84で電源OFF時に不安定になります。

ON時の立ち上がり、OFF時の立下りの電源電圧が動作範囲外の条件で不安定になります。16F84はPOR、PWRT、OSTの設定でパワーアップ時は対応できますが16F877の様にBOR(ブラウンアウトリセット)の機能が無いので、パワーダウン時は不安定になる可能性があります。パワーダウン時に不安定になっても良いアプリケーションでは考慮する必要はありませんが、問題であれば対策しなくてはいけません。
リセット回路を工夫して動作が不安定になる電圧まで電源電圧が低下する前にリセットを掛けるのが上策だと思います。(これがブラウンアウトリセット)専用のICもあるのでそれを利用する手もあります。PIC16C84の日本語データーシート(DS30081D-J00 page18)に電圧低下対策の回路が紹介されています。

Q10 EEPROM内蔵のPIC(877,84)の初期データーの書き込みの方法。

MPASMではDE命令を使ってライターで書き込み時にEEPROMに初期値をセットできます。
-------------
ORG H'2100'
DE H"E0"
DE ......
-------------
(回答者 井上、星、伊藤氏他)

Q11  MPLABでhexファイルをアセンブラ表示させたい。

まずデバイスを選択する、FileのImportのImport To MemoryでHEXファイルを指定することによってプログラムメモリ上に読み込みます、そしてWindowのProgram moryで、それを表示します。ウインドウの左上をクリックすると、メニューの中に16進、マシン語、ディスアセンブリで表示形式で指定できます 。16進はダンプリスト、マシン語は、PICのニーモニックの割り当て。そしてディスアセンブリを選択すると、自動的にそのデバイスの、スペシャルファンクションレジスタの名称を使ってオペランドを表示してくれます。インポートしたプログラムはPICStartPlusで書くこともできます。
(回答者 小倉氏)

 

Q12  MPLABでデバッキング中に入力したい。

DebugメニューのSimulator Stimulusを使う、Asynchronus Stimulusでは、12個のスイッチの並んだダイアログボックスのスイッチ毎にピンを割り当てて、パルス、ロー、ハイ、トグルのアクションを割り当てる事ができます。割り当てはボタンを右クリックしてAssign Pinで行います。(注意、スイッチを押した後に1ステップ命令を実行した後でないと変化が有効にならない)また、Pin Stimulusは拡張子がstiのファイルを作って、クロックにあわせて入力を変化させてやります。 
-----------------
CYCLE   RB1    RB0
20      0       0
41      1       0   ; RB1をHに
52      0       1   ; RB1をL、RB0をHに
55      1       1
60      0       0
65      1       0   ; セミコロンと、
76      0       1   ! エクスクラメーションマーク以降は行末までコメント
-------------------
クロックスティミュラスは、ポートに対して、一定の周波数、一定のデューティサイクルの信号を与えます。 レジスタースティミュラスは、たとえばシミュレートできないA/DコンバータやUSARTなどに使うのですが、レジスタを読み出すたびに引っ張ってくる値をファイルで作ってやります。
(回答者 小倉、佐合氏)

Q13 MPASMで秋月のアセンブラみたいにレジスタを予約したい。

CBLOCK命令を使えば秋月のような書き方で、変数の先頭アドレス、変数名のリストという形で定義できます。(アセンブラの扱いはconstantになりますが)
--------------
CBLOCK  0x0c
ch
cn
rs
ENDC
--------------
(回答者 伊藤氏)

Q14 PICにスピーカーや圧電素子をつないで音を出したい。

PICのI/Oの出力電流は16F84でドレン、シンク共25mAなので、圧電素子程度なら問題なくドライブ可能です。大きな音を出したい場合やスピーカーを使いたい場合はトランジスターを使ってドライブします。
                          Vcc
                            T
                            |
                            +-----+
                        |    |
                        L   ---
                        L   === 圧電スピーカ
                       L   --- (共鳴ケース入り)
                            |   |
                           +-----+
                           |
                           |C
--> Snd OUT >-----RRR------K     Tr:2SC1815 他
                         B  |E
                            |
                            |
                           V
                           GND
 R:抵抗(1k?100kΩ)
 L:インダクタ(30m?300mH?)
(回答者 osamu-o、藤原氏)

Q15  PIC12C509などでRETURNがなくRETLW kという命令しかないが、RETLWは普通どんな使い方があるのか?

RETLW命令はCALL命令でサブルーチンコールされて戻る時にWregにリテラル値k返して戻ります。14bitPICには他にWregに値を返さないRETURN命令があります。一般にRETLW命令は、テーブルで値を返す場合に使用されます。
たとえば
------
TABLE
    ADDWF  PCL,F
    RETLW  'H'
    RETLW  'e'
    RETLW  'l'
    RETLW  'l'
    RETLW  'o'
    RETLW  '.'
-------
といったコードでWregに値を入れてTABLEをコールすると文字コードを返すといったものです。上記のコードはMPLABでしたら、上のコードは
------
TABLE
    ADDWF  PCL,F
    DT     'H','e','l','l','o','.'
------
といったコードと同じでMPLABでもRETLWをこの使い方に意識しているのかなあ、と思います。(DT以下がRETLWに変換されます)ただし、PCLは8bitなので0x00?0xff,0x100?0x1ffといった境界を超えるテーブルは上記のほうほうではできません。org命令でコード開始番地を管理する必要があります。
(回答者 さかい氏)

Q16 RETLW命令を使ったテーブル(表)参照で、ジャンプ先から戻ってこなくなるのは何故?

PIC16シリーズのプログラムカウンター(PC)は13bit幅ですが、そのうち直接読み書きできるのは下位8bitのPCLのみで上位5bitのPCHは直接操作できません。PCHへのアクセスはPCLATH(ProgramCounterLATchHigh)レジスターによって操作されます。PCLATHからPCHへの転送は、演算などによってPCLに書き込みがあった場合に行われます。そのため、Q15のようなTABLEの参照の場合ADDWF命令実行後演算結果がPCLに取り込まれる際にPCLATHの値がTABLEのアドレスの上位5bitと異なる場合、予期しないアドレスにジャンプする事があります。これを避けるためには、ORG命令でTABLEの開始番地を管理するか、TABLEをコールする前にHIGH命令でTABLEの上位5bitの値をPCLATHに転送しておく必要があります。
--
movlw    high table        ;tableの開始アドレスの上位5bitをPCLATHへ
movwf    pclath
..
movlw    n
call        table
--
また、GOTO命令やCALL命令でジャンプする際PCLATH<4:3>の2bitがPC<12:11>に取り込まれますので、2Kを超えるジャンプの場合ジャンプ先のバンクをあらかじめ知っておく必要もあります。
スタックは13bit幅なのでRETURN,RETLW,RETFIE命令で戻る際にPCLATHを考慮する必要はありません。詳細は“Implementing a Table Read” (AN556)を参照すると良いでしょう。
(回答者 小倉氏)

Q17  プログラムをアセンブルしたらIllegal opcodeとかmissing operatorだのエラーメッセージが出ます。

ソースを再検討してもバグが発見できない場合は全角スペースがソースプログラムに含まれているかもしれません。MPASMは半角スペースやTABは無視してくれますが、全角スペースは「文字」として認識しますので、コメント以外の部分にある全角スペースはソースプログラムの一部であると解釈してしまいます。これを防ぐにはプログラムを書く際にスペースを使用しないでTABのみを使うか、全角スペースを半角スペースに変換するフィルターなどを使用するという方法もあります。
(回答者 坂井氏、小倉氏、その他回答多数)

Q18 PIC16F84-10が10MHz動作で電源電圧5V時は正常に動くのですが4.3V程度ではうまく動きません。

PIC16F84-10は10MHz動作時(HS)の動作保証電源範囲は4.5Vから5.5Vまでです。4.3Vでの動作は保証されていません。規格表(2000年5月現在)によればPIC16F84/83-10の動作周波数と電源電圧の関係はRC/XT/HSの時4.5から5.5V、PIC16F84/83-04の場合はRC/XT/LPの時4.0から6.0V、HSの時4.5から5.5V、PIC16LF84/83-04の場合はRC/XT/LPの時2.0から6.0Vになりますので、10MHz動作時の電源電圧は4.5から5.5Vの範囲でないといけません。またPIC16F84-10はPIC16F84-04の検査品(つまり製造プロセスは同じ)であるとの指摘もあるので、RC/XT/LPで4.0から6.0Vで動作する可能性はあります。詳細は英文のデーターシート(30430C-Page76)を参照してください。
(回答者 石垣氏、要旨)

Q19 PIC18シリーズとは?またどこで入手できますか?

PIC18は新しいPICの名称でPIC18C242,PIC18C252,PIC18C442,PIC18C452があるようです。16CXX上位互換、10MHzクロックで4倍速PLLで見た目1クロック1サイクルになるようにしているなど。秋葉ではアイコー電子(http://www.aikoh-d.co.jp/)で取り扱っているとの事。
(回答者、福山氏、石垣氏)

Q20 PIC16F877のA/Dに可変抵抗(50k Bカーブ)で分圧して入力しているのですが変換結果がとても不安定なのです。

PIC16F87Xデータシート(和文) DS30292A-Jによれば、「アナログソースの最大推奨インピーダンスは10k Ωです。」これ以上のインピーダンスではホールド用のコンデンサーのチャージ時間が長くなるため、正確な測定ができなくなる恐れがあります。(チャージ時間を考慮したプログラムも必要です)アナログインピーダンスが高い場合にはバッファを入れる必要があります。
(回答者 石垣氏、他)

Q21  16ビットバイナリーからBCD変換のアルゴリズムは?

Bin->BCD変換の原理はバイナリー値を各桁毎に2のN桁乗で十進加算してやればよいのですが、十進カウンターでカウントする方法はAN526の8bit->2桁BCD変換で使用されている方法で、この方法で10ビットのBCD変換しか思いつかなかった人間が ここ に居ます。
閑話休題、AN526に紹介されている16ビットからBCDに変換方法は以下の通り
A=a15 a14a 13a12 .......a3 a2a 1a0  (Bin)をBCD変換するには A=a15 x215+ a14x2 14+a 13x213 +a12 x212+.......+ a3x2 3+a 2x22 +a1 x21+ a0を十進数で計算すれば良いことになります。この式はA=((((....((( a15x2+ a14)x2+ a13)x2+ a12)+.....)x2+ a3)x2+ a2)x2+ a1)x2+ a0と変形できるので、各桁加えながら16回2倍してかつその結果にBCD補正を施せば良い事がわかります。

 
実際にはPICの命令の関係上次のような手順で上の式の計算を行っています。

 
1.) 次の様にBin値(H_BYTE,L_BYTE)からBCD値(DEC_1,DEC_2,DEC_3)へ左シフト(2倍)します。
 (DEC_1) <- (DEC_2) <- (DEC_3) <- (H_BYTE) <- (L_BYTE) <-ゴミ
|                              |                      |
+-------------BCD--------------+----------BIN---------+
※最下位からゴミが入ってきますが、16ビットしかシフトしないので変換結果には影響しません。

 
2.) シフト毎にDEC_1から3の各バイトを10進補正する。
L_BYTEから順にシフトする事によって、DEC_3をシフトする時に前の値を2倍すると同時にLSBにキャリーから下位の桁が加算される。この前処理として10進補正が行われるが、左シフトを考慮した補正が行われる。この操作を16回繰り返すとBCD値が得られる。

 
このプログラムの考え方として以下の様に考えると理解しやすいと思います。
・BCDとBINの間に小数点がある。
・変換する値を1/65536倍して小数部にセットする。
・2倍を16回繰り返すと65536倍されて変換値は整数部に得られる。

 
BIN部での2倍は左シフトですが、BCD部では左シフトに加え、各桁のBCD補正演算が行われる。ただPICにはキャリーを含めて加算する命令やBCD加算補正命令等が無いため2倍演算後にBCD補正値が得られる様に補正を行っているので、一般的なBCD補正と違ってキャリーを含め、全体が右に1ビットずれた形で補正しているため、一般的な補正値6でなく半分の3を使っています。

 
BCD部を左シフトしてもBIN部の様に2倍演算になるのかについては以下の様にシフト後にBCDの値が崩れない様にして補正しています。

 

 C <- UUUU LLLL <- X
 

 U <- UUUL  LLLC

 
Xは前回のシフトでMSBがキャリーに入っています。ローテート命令なのでLSBから入って来ます。補正する時はシフトを考慮して下位4ビットの下3ビット(bit0-2)とBIN部のシフトのキャリーの値(X)を加えた4ビットをセットとしてBCD補正しておきます。下位4ビットの最上位ビットは(bit3)はハーフキャリーとして3を加えて7を越えれは補正が必要なのでその判定に使えます。上位4ビットも同様に、下3ビット(bit6-4)と下位1ビット(bit3)をセットとして補正します。bit7はキャリーに入るので特別に処理しません。補正した値を1回シフトするとBCD値が得られます。
(回答者、伊藤氏、さかい氏、石垣氏)

Q22  PC-UNIX(Linux、FreeBSD)での開発ツールは?

アセンブラについては、http://www.cc.jyu.fi/~trossi/ より picasm というものが配布されており、Unix で利用できます。書き込みについては、宣伝になりますが、 http://www2.osk.3web.ne.jp/~nkon/elec/pic/ にて拙作を公開しています。FreeBSD と PC9801(パラレルポート接続で、#ACKを使う書き込み機)については、
対応パッチを頂いてマージしてあります。
(回答者、近藤氏)

Q23  PIC16F87xのデバッグモードについて解説している資料はありますか?

無いみたいですね。でも手がかりは入手できるんです。海外というか英語圏でもPICのメーリングリストがあって、そこが情報源。方針としては、無料で入手できる情報という事に絞ると、
・MPLAB-ICDのユーザーズマニュアル(DS51184B)にある、回路図。
・MPLABの5.00のMPLAB-ICDサポートファイルを選択するとインストールされるらしい、MPL876.HEX。
があればとりあえず資料一式は揃いますよね。これを解析するなりクローンしちゃうなりという感じです。私もやってみようかと考えているところ。とりあえず趣味を兼ねてMPL876.HEXを解析しようかなぁと。そうそう、そのMLは、 http://www.piclist.com/ で、Free ICDプロジェクトが、http://www.piclist.com/freeicd あと、そのMLのログが、 http://www.infosite.com/~jkeyzer/piclist/index.htmlhttp://www.iversoft.com/piclist/ あたり。
みんな同じこと考えてるんですね。英文に拒否反応を示さず一度「ICD」をキーワードに探して読んでみると楽しいですよ。
(回答者、石垣氏)

Q24  シリアルEEPROM(IIC)のアクセスがうまくいきません。

回路上の不備はありませんか?プルアップ抵抗の値は適当ですか?(SCL,SDAを1KΩでVDDにプルアップ)スタートコンディションを発行しても、SCLがLOWだとバスコンフリクトでBCLIFがセットされて即座にIICのシーケンスは終了します。そのためその後何をしてもIICは動きません。その後のシーケンスでもBFだけでなくバスラインがアイドルモードになっているのを確認してから次のコマンドを発行しないとやはりコンフリクトを起こします。これはNOPをちょっといれたぐらいではだめです。R_W(シフトイン/アウト中)とイネーブル(バス調停中)フラグがみんな(自動的に)クリアされるのを確認してください。データシートには、(MSSP I2C Operation) Before selecting any I2C mode, the SCL and SDA pinsmust be programmed to inputs by setting the appropriate TRIS bits. Selecting an I2C mode, by setting the SSPEN bit, enables the SCL and SDA pins to be usedas the clock and data lines in I2C mode.とあるので、II2Cモードに入る前にSCLとSCAを入力に設定して適当な時間を置いてから(25μs程度?)BFをチェックしてから実行してみては?

 
資料  http://www.microchip.com/10/Lit/Memory/IC/64to128/21203/index1.htm
(回答者、まるとも氏、田部氏、他多数)

Q25 アセンブラの乗算、除算のしかたを教えてください。

アセンブラの乗算については、シフト命令(ビットローテート)と、加算命令を組み合わせて行います、例えば8x8ビットの乗算の場合A=11011101(x0DD) B=00010111(0x17) の場合その積を計算する方法は、AにBの各桁を掛けたものを加算(16bit)してやれば良いが、2のべき乗の計算は単に左シフトするのみで良いので、8回シフトしてBの該当する桁が1の時のみ、シフトした結果を加算してやれば良い。

 
                  1 1 0 1 1 1 0 1     DD(HEX)
                x) 0 0 0 1 0 1 1 1     17(HEX)
                -------------------
                   1 1 0 1 1 1 0 1
                 1 1 0 1 1 1 0 1 0     <--左シフト
               1 1 0 1 1 1 0 1 0 0     <--左シフト
             0 0 0 0 0 0 0 0 0 0 0
           1 1 0 1 1 1 0 1 0 0 0 0     <--左シフト
         0 0 0 0 0 0 0 0 0 0 0 0 0
       0 0 0 0 0 0 0 0 0 0 0 0 0 0
  +) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
   --------------------------------
     0 0 1 0 0 1 1 1 1 0 1 1 0 1 1   13DB(HEX)

 
実際はシフトを8回行って、Bの0の桁の場合は加算操作をスキップする様にプログラムします。除算の場合はシフトして減算するという操作を組み合わせて行います。実際のプログラムでは除数をシフトして割る数から減算した結果が負になるまで行い、負になったシフト数の桁の商のビットを1にしてその余りに対して同様の操作を繰り返して、余りが除数より小さくなるまで行って、論理和をとって商を求めます。

 
                  1 1 0 1 1 1 0 1     DD(HEX)
               ÷) 0 0 0 1 0 1 1 1     17(HEX)
                -------------------

 
                 1 1 0 1 1 1 0 1
                -) 1 0 1 1 1 0 0 0     <--左シフト3回 (00001000)
               -------------------
                   0 0 1 0 0 1 0 1

 
                   0 0 1 0 0 1 0 1       <--シフト無し  (00000001)
                -) 0 0 0 1 0 1 1 1
                 -----------------
                 0 0 0 0 1 1 1 0      E(HEX) <---余り

 
                   0 0 0 0 1 0 0 0
              OR)  0 0 0 0 0 0 0 1
                ------------------
                   0 0 0 0 1 0 0 1      9(HEX) <---商

 
除算の場合は例外処理(置数が0、除数が0の場合)があるので、その後に上記操作を行うルーチンを書きます。
具体的には[pic 2892]で伊藤氏が乗算ルーチンを公開されているので、 ここ で検索してみるのも良いでしょう。また、マイクロチップのWebページ http://www.microchip.com/10/Appnote/Category/PIC16/index.htm のAN526に各種演算ルーチンが紹介されているので、参照してみると良いでしょう。
(回答者 伊藤氏、岡野氏他多数)

Q26  FSRの有効な使用方法は?

PIC16シリーズのFSRは1つしかないので、サブルーチンに引数を引き渡すとか、メモリーのブロック転送に使う場合には処理が煩雑になって効率が悪くなります。サブルーチンの引数の引渡しなどを高速に処理するのは固定変数を使用するのが良いと思われます。汎用化にはマクロを利用するのが良いかも知れません。
FSRの利用法として考えられるのは、I/Oからメモリー上のバッファ領域や、変数に連続して値を転送する場合や、EEPROMなどから連続して値を読み出してデーターをメモリー上にコピーするなど、特定のアドレス(I/O)から連続したRAM領域に転送する場合などが考えられます。ちなみにPIC18シリーズはFSRを2個持っています。
(回答者 多数、趣意)

Q27  コードを追加するたびに新しくCALL、GOTO文に「Message[]:Crossing page boundary」ってエラーが出るんですけどなんとかなりませんか?

PIC16F87xなどの複数のページをもった機種では、GOTO命令やCALL命令を使う際、HIGH擬似命令を使ってPCLATHをセットしてやるのが基本です。サブルーチンを同じバンクに集めてorg命令でアドレスを固定してしまう手もあります。またリローケータブル命令を使用してサブルーチンをリロケータブルに書けばMPASMが処理してくれます。
(回答者 後閑氏、他)

Q28 割込み処理中に別の割込みが入ったらどうなりますか?(多重割り込みの処理)

普通は割込み処理中に他の割込みを受け付けない様にINTCON REGISTERのGIE,RBIE,RBIFを操作します。割込みのプライオリティ(優先順位)によっては割り込み中に他の割込みを受け付ける事もできますが、PICはスタックが8段しかないので、あまり深いネスティングは取れないので注意が必要です。(一度に3つも4つも割込みを受け付けるのはトラブルの元)できれば、割り込み処理が終わってから次の割り込みを受け付けるようにプログラムするのが良いと思われます。
(回答者 村上、趣意)

Q29 パラレルスレーブポートの用途は?

PICは元来Peripheral Interface Controlerの名の通り周辺機器のための汎用コントローラーとして設計されたので、マイクロプロセッサー同士でなく、一般的な8/16bitCPUとのバス接続型インターフェースとして使用できる機能がついています。8/16bitCPUから見たら、8255とかの周辺LSIと同じものに見えるという事です。使う信号は、D0?7の8bitデータ部と、~CS、~WR、~RDで、8/16bitCPU側は、まず~CSをアクティブにし、8/16bitCPUから書き込みたいなら~WR、読みたいなら~RDをアクティブにし、D0?7から、データを読み書きします。
(回答者 石垣氏)

Q30 PIC16C73の替わりにPIC16F873を使いたいのですがどこが違いますか?

両者の資料は http://www.microchip.com/10/Lit/PICmicro/Japan/index.htmhttp://www.microchip.co.jp/docj.htm であたりの和文データシートをたどるのがよろしいかと・・・具体的にはPIC16F87X Datasheet (Japanese) PIC16C7X Datasheet (Japanese) で、違いがわかると思います。1999 Product Selection Guide Japanese) には、違いが一覧表になっていたと記憶しています。なおCCS Cでのソースをコンパイルする際は以下の変更が必要です。

 
1.includeファイルの変更
  #include <16f873.h>
2.TRIS指定の前にアナログを使わないという指定が必要

 
    setup_adc_ports(NO_ANALOGS);   ← ここです。
    set_tris_c(0);
    set_tris_b(0xFF);
    set_tris_a(0xFF);

 
(回答者 Ishihara氏、後閑氏)

Q31 BSF,BCF命令などでポートのビットをセットした時に不安定な動作になるときがあるんですが?

同一ポートに対してBSF,BCF命令を連続して使用すると条件(負荷が重い、動作周波数が高い)によって出力が不安定になります。これは出力の際に一旦ポートの入力を読み込むために生じる現象です。(PICの仕様) 具体的な理由及び回避方法については、マイクロチップジャパンのFAQに詳しく解説されております。 http://www.microchip.co.jp/faqs/ioport_rmw.htm を参照下さい。
(回答者 神山、藤田氏、原@1号氏)

Q32 TMR0割り込みを使って制御したいのですが、割り込みがかかるタイミングが1ステップずれる事があります。誤差になりませんか?

なりません。タイマーをリセットしない(もしくは止めない)限りタイマーの割り込み周期は一定です。処理時間がタイマー割り込みの発生周期より短ければ累積誤差は出ません。しかし、TMR0を設定しなおすとプリスケラーがリセットされますので、その分誤差になる場合がありますので注意しましょう。割り込みの発生タイミングによってジャンプするタイミング1ステップ(サイクル)ずれる事は2サイクル命令がある関係上どうしようもないので、「どうしても1サイクルずれるのは嫌!」という場合(笑)は割り込みルーチン側でTMR0の値から補正する必要があります。この場合も上記の点を注意して処理しなければいけません。
(回答者 多数)

Q33 PIC内のプログラムを読み出す事はできますか?

コードプロテクトが掛っていなければ読み出せます。コードプロテクトが掛っている場合はEEPROMタイプ(F)ではコードプロテクトをOFFにするとプログラムが消去されOTPタイプでは書き込めなくなります。UVEPROMタイプ(窓付)も同様です。
(回答者 多数)

Q34 16F84でPORTBを入力にして外部回路に接続していますが、外部回路の電源を入れるとPIC側の電源を入れないでも動作してしまいます。

PICのPORTは一部を除いて下の図の様に電源範囲を超えた入力電圧から入力を守るための保護ダイオードがVDDとGNDにそれぞれ入っています。
 
 VDD
 _
 A (Diode)
--+---- >I/O
 _
 A
 GND
 
そのため外部電圧入力がVDDより高ければ保護ダイオードを介して入力からVDDに電流が流れるためCMOSの様に消費電力の小さなデバイスでは動作してしまいます。(但し不安定)またPORTBには Weak プルアップ用のFETが入っていますので、これからも電流が流れます。入力から電流が流れない様にするためには、相手側の出力回路をオープンコレクタ(ドレイン)にするか、フォトカプラーで絶縁して電源の回りこみが起きないようにしなくてはなりません。アプリケーションによっては入力電圧を利用して電源を得るという事も出来ます。(FED PIC Cのマニュアル参照)
(回答者 Oba 伊藤氏他多数)