PICでCの練習 2007.04.28(土)〜 LessonC_01。 while()で繰り返し。
著作者名: 中野 良知 作成開始: 2007.04.27(金) 更新 : 2007.04.28(土) : 2007.05.01(火) 実験回路を巻末に移動。 : 2007.05.10(木) キーワード while(){} で誤記訂正。 : iが0になるまで処理Aを ⇒ nが0になるまで処理Aを : 2007.05.14(月) ソースコードでconfigのXTALをHSに変更。 : 実験回路図に電源パスコンを追加。 : 発振子のGNDと5PIN(GND)を直近に変更。
目次 1. 目的 2. フローチャート 3. プログラムソースコード 4. キーワード 4.1. #include "pic.h" 4.2. __CONFIG(0x3FF9); 4.3. void main(void){} 4.4. TRISB 4.5. PORTB 4.6. while(){} 5. アセンブリリスト 6. hexファイル 7. 実験回路 1. 目的 ポートBのビット0に接続したLEDをオンさせ、while文でプログラムの暴走を防ぎます。 2. フローチャート (main) ↓ ポートの初期化 ↓ ポートBのビット0に1を出力 ↓ 暴走? PICC Liteは、PIC16F84Aの命令コードを後詰めで生成します。 ポートBのビット0に1を出力する命令コードはPC(プログラムカウンタ)の0x03FF番地に 配置されている為、次の命令コードのラッチでPCがインクリメントされると、PC値は 0x0400になり、命令コードの無い領域を実行してしまいます。 mikrobasicコンパイラーは命令コードを前詰めで生成するため、バルク消去されてい れば「ADDLW k」命令の実行を、以前の命令コードが残っていればそのコードを実行し やがてROMアドレス0x0400以後の命令コードの無い領域を実行します。 main関数の終端(})から外へ出ないように、main関数内でループさせます。 (main) ↓ ポートBの初期化 ↓ ポートBのビット0に1を出力 ↓ ├←─┐ ↓ │繰り返し └──┘ 3. プログラムソースコード //***************************************************************************** // タイトル: LesssonC_01 // 作者 : ioio // 目的 : while文でmainから飛び出さないようにします。 // 機能 : ポートBのビット0に接続したLEDを点灯させます。 // マイコン: PIC16F84A // クロック: 20MHz // Config : PROTECT=OFF, WDTE=OFF, XTAL // Compiler: HI-TEC Software PICC Lite(V9.6) // : >picl -16f84a lesson.c //***************************************************************************** // 変更履歴 // 2007.04.28(金) 作成 // 2007.05.14(月) configでXTALをHS_OSILLATORに変更 //***************************************************************************** #include "pic.h" // デバイス関連の定義を展開 __CONFIG(0x3FFA); // PROTECT=OFF, WDTE=OFF, HS_OSILLATOR void main(void) { TRISB = 0xFE; // PortB b0=Out. b1,b2,b3,b4,b5,b6,b7=In PORTB = 0x01; // PortB b0=1 while(1); // while文を繰り返します } //***************************************************************************** //***************************************************************************** 応用1: 上記のソースリストの PORTB = 0x01; // PortB b0=1 を PORTB = 0x00; // PortB b0=0 と変更すると、ポートBのビット0に接続したLEDはオフします。 4. キーワード 4.1. #include "pic.h" pic1684.hをインクルードして、デバイス関連の定義を展開します。 TRIAB、PORTBや__CONFIG()などが定義され、コンパイラーがこれらを解釈します。 "pic1684.h"をテキストエディターで参照すると役に立つことがあると思います。 4.2. __CONFIG(0x3FFA); コンフィグレーションワードを設定します。 hexファイルのアドレス400E,400Fに"FA3F"(リトルエンディアン)形式で配置され ます。 4.3. void main(void){} リセットスタートで初めに実行されるプログラムです。 リセットスタートベクターのジャンプ命令でmain関数にジャンプします。 先頭のvoidは、戻り値がない事を表します。 ()のvoidは引数がない事を表します。 {}の中にプログラムを記述します。 4.4. TRISB PIC16F84Fが内蔵するレジスターで、ポートBの入出力の方向を設定します。 4.5. PORTB PIC16F84Fが内蔵するレジスターで、ポートBに接続されたレジスターです。 ポートBへの出力や、ポートBからの入力をこのレジスターを介して行います。 参考) RB0 = 1;と記述するとビットフィールドの"PORTB,0 = 1"に展開され、ポートBの ビット0に1が出力されます。 4.6. while(){} ()の中には判定文を記述します。 ()の中が0以外の場合は、{}の中を繰り返し実行します。 ()の中が0の場合は、{}をスキップします。 処理Aを永久に繰り返します。 while(1){ 処理A; } 処理Aを実行せずに{}をスキップします。 while(0){ 処理A; } nが0になるまで処理Aを繰返します n = 10; while(n){ 処理A; n--; // 変数nをデクリメントします。 } 変数のデクリメント n--;は、n=n-1;と同じ結果になります。(右辺の結果を左辺に代入)。 他に n-=1;も、n=n-1;と同じ結果です。 但し n-=2;は、n=n-2;と同じ結果になります。 変数のインクリメント n++;は、n=n+1;と同じ結果です。 n+=1;は、n=n+1;と同じ結果です。 n+=2;は、n=n+2;と同じ結果です。 5. アセンブリリスト コンパイルオプションに --ASMLIST を使用して、コンパイラーが生成したアセンブ リリストの一部です。 コンパイル書式例: >picl -16f84a --ASMLIST lessonC_01.c アセンブリリスト抜粋 LINE ADDR- HEX No ESS CODE MNEMONIC CODE ----+------+------+------------------------------------------------------- 17 psect text0 18 03F9 _main 19 ;lesson.c: 18: void main(void) 20 03F9 30FE movlw -2 21 03FA 1683 bsf 3,5 22 03FB 0086 movwf 6 ;volatile 23 ;lesson.c: 22: PORTB = 0x01; 24 03FC 3001 movlw 1 25 03FD 1283 bcf 3,5 26 03FE 0086 movwf 6 ;volatile 27 ;lesson.c: 24: while(1); 28 03FF l2 29 03FF 2BFF goto l2 30 31 psect config 32 2007 3FFA dw 16378 ;# 33 34 psect text1 20行目のアドレス0x03F9がmain関数の先頭です。 29行目のgoto l2が空のwhile文に相当します。 32行目にconfig wordがあります。 6. hexファイル コンパイラーが生成したインテル形式の16進数ファイルです。 :02000000F92BDA :0E07F200FE3083168600013083128600FF2B36 :02400E00FA3F77 :00000001FF 項目毎に区切りを入れました。 左から、 T=先頭文字、L=データ長、A=アドレス、C=コード、D=データ、S=チェックサムです。 T L A C D S -+--+----+--+----------------------------+---- : 02 0000 00 F92B DA : 0E 07F2 00 FE3083168600013083128600FF2B 36 : 02 400E 00 FA3F 77 : 00 0000 01 FF データはASCII文字の2文字で1バイトを表し、4文字の2バイトで1ワードです。 1ワードは下位1バイトが先行するリトルエンディアン(Little endian)形式で記述さ れています。 1行目のデータ"F92B"の命令コードは0x2BF9で、ニーモニックコードで"GOTO 0x3F9" に相当し、main関数の先頭アドレスへのジャンプ命令です。 2行目は、main関数の命令コードが14バイト(7ワード)あります。 3行目は、config word データで、値は0x3FFAです。 4行目は、hexデータの終了を表します。 アドレスは、データの先頭アドレスで1バイト単位で累積された値です。 1ワード単位のアドレスには、先頭アドレスの値を右シフト1回で変換します。 main関数の先頭アドレスは 0x07F2 → 0x03F9。 config wordのアドレスは 0x400E → 0x2007。 7. 実験回路 PIC16F84A ┌────┐14 │ VDD├──────●──────●────●──── +5V │ │ │ │0.1u │ │ │ R10K ┴ /50V │┴│100u/16V │ │4 │ 0.1u/50V ┬ └┬┘ │ -MCLR├──────●─┤├───●────┘ │ │ │ │ │16 ┌ ─ ─ ─ ┐ │ │ OSC1├───●─┤├──┐ │ │ │ │┴ ││ │ │ │ □ 20MHz │ │ │ │15 │┬ ││ │ │ OSC2├───●─┤├──● │ │ │ └ ─ ─ ─│┘ │ │ │5 ┌───────┘ │ │ Vss├─●───────────● │ │ │ │ │ LED │ │ │6 ┌─┬┐K │ │ RB0├──┤ │├─R220──● │ │ └─┴┘ │ │ │ │ └────┘ ┴ GND 0.1u/50VのコンデンサーはVDDとVssの近くに接続します。 発振子のGNDはVssの直ぐ近くに接続します。
LessonCのTopへ
サイトTopへ
法律条項 この資料により生じたいかなる障害や損害に対し、著者は全てを免責されるものとします。 この資料は、著作権法の下で保護され、入手先、著者、日付、法律条項を含んだ場合にのみ複製が可能です。
inserted by FC2 system