PICでCの練習 2007.04.29〜 LessonC_03。 LEDを1msec毎に点滅。
著作者名: 中野 良知 作成開始: 2007.04.29(日) 更新 : 2007.04.29(日) : 2007.05.01(火) 回路図を巻末へ移動 : 2007.05.14(月) ソースコードでconfigのXTALをHSに変更。 : 実験回路図に電源パスコンを追加。 : 発振子のGNDと5PIN(GND)を直近に変更。
目次 1. 目的 2. フローチャート 3. プログラムソースコード 4. キーワード 4.1. unsigned int 4.2. while(cnt1--); 5. アセンブリリスト 6. 出力周期の概算 7. 実行結果 8. 実験回路 1. 目的 1msecの遅延時間をwhile文で作り、LEDを1msec毎に点滅させます。 2. フローチャート (main) ↓ ポートの初期化 ↓ ├←────────────┐ ↓ │ ポートBのビット0に1を出力 │ ↓ │ 1msec遅延 │ ↓ │ ポートBのビット0に0を出力 │ ↓ │ 1msec遅延 │ ↓ │ └─────────────┘ 3. プログラムソースコード //***************************************************************************** // タイトル: LesssonC_03 // 作者 : ioio // 目的 : while文でLEDを1msec毎に点滅させます。 // 機能 : ポートBのビット0に接続したLEDを点滅させます。 // マイコン: PIC16F84A // クロック: 20MHz // Config : PROTECT=OFF, WDTE=OFF, XTAL // Compiler: PICC Lite(V9.6)。 HI-TEC software製。 // : >picl -16f84a lesson.c //***************************************************************************** // 変更履歴 // 2007.04.29(日) 作成 // 2007.05.14(月) configでXTALをHS_OSILLATORに変更 //***************************************************************************** #include "pic.h" // デバイス関連の定義を展開 __CONFIG(0x3FFA); // PROTECT=OFF, WDTE=OFF, HS_OSILLATOR void main(void) { unsigned int cnt1; // 遅延用カウンタ TRISB = 0xFE; // PortB b0=Out. b1,b2,b3,b4,b5,b6,b7=In // 繰り返し実行 while(1){ // 繰り返し // LED ON RB0 = 1; // Port b0=1 // ソフト遅延 cnt1 = 500; while(cnt1--); // 約1msecの遅延 // LED OFF RB0 = 0; // Port b0=0 // ソフト遅延 cnt1 = 500; while(cnt1--); // 約1msecの遅延 } } //***************************************************************************** //***************************************************************************** 4. キーワード 4.1. unsigned int unsigned int cnt1; // 遅延用カウンタ 符号無しの整数型の変数を宣言します。 unsigned 符号無し。 int 整数として指定します。ビット長は16ビットです。 cnt1 変数名です。0から65535の数値が使えます。 unsigned int cnt1 = 0; と記述すると、変数宣言と同時にcnt1に0を代入します。 参考) int cnt1; は符号付の整数型の変数宣言です。 -32768から+32767の数値が使えます。 4.2. while(cnt1--); while文の繰り返しの中で、cnt1をデクリメントします。 cnt1が0になるとwhile文を終了します。 5. アセンブリリスト コンパイルオプションに --ASMLIST を使用して、コンパイラーが生成したアセンブ リリストの一部です。 コンパイル書式例: >picl -16f84a --ASMLIST lessonC_01.c アセンブリリストからcnt1=500とwhile(cnt1--)部分の抜粋です。 LINE ADDR- HEX No ESS CODE MNEMONIC CODE ----+------+------+------------------------------------------------------- 30 ;lesson.c: 31: cnt1 = 500; 31 03E4 30F4 movlw 244 32 03E5 008C movwf ?a_main 33 03E6 3001 movlw 1 34 03E7 008D movwf ?a_main+1 35 ;lesson.c: 32: while(cnt1--); 36 03E8 l5 37 03E8 080C movf ?a_main,w 38 03E9 1903 btfsc 3,2 39 03EA 038D decf ?a_main+1 40 03EB 038C decf ?a_main 41 03EC 0A0C incf ?a_main,w 42 03ED 1903 btfsc 3,2 43 03EE 0A0D incf ?a_main+1,w 44 03EF 1D03 btfss 3,2 45 03F0 2BE8 goto l5 cnt1はRAMのアドレス?a_mainに下位桁が、?a_main+1に上位桁が割付けられています。 ?a_main ?a_main+1 下位1バイト 上位バイト ┌──────┬─────┐ │ 244(0xF4) │ 1=(0x01) │ =0x01F4=500 └──────┴─────┘ while(cnt1--) ├←────────┐ │ no │ < 下位桁=0? >→───┐ │ ↓yes │ │ 上位桁=上位桁-1 │ │ ├←──────┘ │ 下位桁=下位桁-1 │ ↓ no │ < 下位桁=0xFF? > →───┤ ↓yes no │ < 上位桁=0xFF? > →───┘ ↓yes while終了 while文は()の判定式が0以外ならば繰り返しを続け、0ならばwhile文を終了します。 コンパイラーはcnt1が0の判定を変数をデクリメントして0xFFFFになったところで while文を終了するようにアセンブリコードを生成しています。 cnt1の下位桁をインクリメントし結果をWレジスターに代入します。cnt1の値に変化 はありません。 Wが0x00ならばゼロフラグがセットされます。 更に、cnt1の上位桁も同様な演算をしてゼロフラグがセットされればcnt1は0xFFFFで 終了の条件が成立します。 6. 出力周期の概算 while文のなかで繰返される処理の命令サイクル数を数えます。 36 03E8 l5 37 03E8 080C 1 1 movf ?a_main,w 38 03E9 1903 2 1 btfsc 3,2 39 03EA 038D 1 decf ?a_main+1 40 03EB 038C 1 decf ?a_main 41 03EC 0A0C 1 1 incf ?a_main,w 42 03ED 1903 2 1 btfsc 3,2 43 03EE 0A0D 1 incf ?a_main+1,w 44 03EF 1D03 1 1 btfss 3,2 45 03F0 2BE8 2 2 goto l5 ↑ ↑ @ A 命令サイクル数 cnt1の下位桁からボローが発生しない場合は@のルートです。 cnt1の下位桁からボローが発生する場合はAのルートです。 どちらも 1回の繰り返しの命令サイクル数=10 500回の繰り返しのループ命令サイクル数合計=10×500=5000 1命令サイクル=1/20MHz×4=0.2μsec 遅延時間=5000×0.2μsec=1msec です。 Lの幅のwhile文は、LEDの点灯へ戻る goto l3 命令をスキップするため、1命令サイ クル多くなっています。 62 03FD 1903 2 btfsc 3,2 63 03FE 2BE2 goto l3 64 03FF 2BF6 2 goto l8 1回の繰り返しの命令サイクル数=11 500回の繰り返しのループ命令サイクル数合計=11×500=5500 遅延時間=5500×0.2μsec=1.1msec 出力の周期=1msec+1.1msec=2.1msec です。 7. 実行結果 Hの幅=1msec。 Lの幅=1.1msec。 出力の周期=2.1msec 8. 実験回路 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