[PR]100万円が無料で当たる!:今すぐ応募して現金を当てよう!


LED ON・OFFの実験 2006.01.03(火)〜
作成 2004.06.18(金) 中野 良知 編集 2006.01.04(水) アセンブリ言語のステップ数削減の記述を削除。 2006.04.12(水) 概要、目次、サンプルプログラムの項目を追加。 概要 EZ-USBマイコンでLEDの点滅を行います。 目次 1. 接続図 2. 開発環境のインストール 3. サンプルプログラム 4. プログラムの実行 5. LedOnOff.cのフローチャート 6. 点滅が見えるようにする 6.1. フローチャートは 6.2. 変数loop_countの働き 6.3. 変数loop_countのチェック 6.4. プログラムの編集 6.5. コンパイル 6.6. ループの所要時間について 1. 接続図 ┏━━━━━━┓ ┏━━━━━━┳━━┓+┌──┬┐− ┃ ┃ USBケーブル ┃MINI ┃B9 ┠─┤LED │├─┐ ┃Windows PC ┣━━━━━━━┫EZ-USB ┃ ┃ └──┴┘ │ ┃ ┃ ┃キット ┃ ┃ ┌───┐ │ ┃ ┃ ┃ ┃B13 ┠─┤220Ω ├─┘ ┗━━━━━━┛ ┗━━━━━━┻━━┛ └───┘ ↑ コネクタ コネクタの端子番号 B9 には、EZ-USBマイコンのポートBのビット0(PORTB-0)がプリ ント基板内で接続されています。 2. 開発環境のインストール Windows PC に Cypressからダウンロードした、Cypress EZ-USB Development Kit を インストールします。 インストール手順はこちらを参照して下さい。 3. サンプルプログラム サンプルプロジェクト をダウンロードし、解凍します。 解凍した「LedOnOff」フォルダーを D:\Cypress\USB\Myprogramのサブフォルダーに 移動します。 移動したフォルダーのパスです。 D:\Cypress\USB\Myprogram\LedOnOff\ ドライブ D:は、Cypress EZ-USB Development Kit のインストール先により変わりま す。 4. プログラムの実行 「スタート」→「プログラム」→「Cypress」→「USB」→「EZ-USB control panel」 を順にクリックしてください。 開いたEZ-USBコントロールパネルの「DownLoad」釦をクリックし、解凍したサンプル プログラムの"LedOnOff.hex"を選択し「開く」釦をクリックしてください。 PCからMINI EZ-USBキットへプログラム転送が行われます。 プログラムの転送が終了するとMINI EZ-USBマイコンが、今転送したプログラムを実行 し、LEDが点灯します。 EZ-USBコントロールパネルの「HOLD」釦と「RUN」釦を交互にクリックしてください。 「RUN」を押すとLEDが点灯します。 「HOLD」を押すタイミングによってLEDが消灯する場合があります。 「RUN」を押した時の B9 の出力波形 LED ON ┌───┐LED OFF ┌───┐ ┌───┐ ───┘ └────┘ └────┘ └─── │←─→│←──→│ 1.36μsec 2.32μsec 「HOLD」を押した時の B9 の出力波形1 LED ON ┌───┐LED OFF ───┘ └───────────────────── ↑ ここで「HOLD」釦を押したとき 「HOLD」を押した時の B9 の出力波形2 LED ON ┌───┐LED OFF ┌──────────────── ───┘ └────┘ ↑ ここで「HOLD」釦を押したとき EZ-USBコントロールパネルの「HOLD」釦を押したことにより、LEDを接続したポートの 出力を1または0の状態に保持したままEZ-USBマイコンは動作を停止します。 5. LedOnOff.cのフローチャート ┌───────┐ │ スタート │ └───┬───┘ │ ┌───┴──────┐ │PORTB-0を出力に設定 │ └───┬──────┘ ├←───────┐ ┌───┴─────┐ │ │PORTB-0に1を出力 │ │ └───┬─────┘ │ │ │ ┌───┴─────┐ │ │PORTB-0に0を出力 │ │ └───┬─────┘ │ │ │ └────────┘ 6. 点滅が見えるようにする LED のON/OFFを目に見えるようにしたいと思います。 1)loop_countという名前の変数を用意します。 ソースコードで long loop_count; と記述すると、整数型32ビット長(4バイト)の変数名 loop_count が使用できるよ うになります。 6.1. フローチャートは ┌───────┐ │ スタート │ └───┬───┘ ┌───┴───────┐ │変数 loop_count を用意│ └───┬───────┘ ┌───┴───────┐ │変数 loop_count = 0 │ └───┬───────┘ ┌───┴──────┐ │PORTB-0を出力に設定 │ └───┬──────┘ ↓ ├←────────────────────┐ │ │ ───┴────────── 1 │ < 変数 loop_count のビット17 >──┐ │ ───┬────────── │ │ │0 │ │ ┌───┴─────┐ ┌───┴─────┐ │ │PORTB-0に0を出力 │ │PORTB-0に1を出力 │ │ └───┬─────┘ └───┬─────┘ │ ├─────────────┘ │ ┌───┴────────────┐ │ │変数 loop_count = loop_count +1 │ │ └───┬────────────┘ │ │ │ └─────────────────────┘ 6.2. 変数loop_countの働き 変数 loop_count の内容は、ループ1回ごとにカウントアップします。 loop_countの内容を2進数で表現すると、初期値は 31 30 29 28 18 17 16 5 4 3 2 1 0 ┌─┬─┬─┬─┬ ─ ─┬─┬─┬─┬ ─ ─ ┬─┬─┬─┬─┬─┬─┐ │ 0│ 0│ 0│ 0│ │ 0│ 0│ 0│ │ 0│ 0│ 0│ 0│ 0│ 0│ └─┴─┴─┴─┴ ─ ─┴─┴─┴─┴ ─ ─ ┴─┴─┴─┴─┴─┴─┘ です。途中を省略しています。 ループ内の処理1回の最後の 変数 loop_count = loop_count + 1により 31 30 29 28 18 17 16 5 4 3 2 1 0 ┌─┬─┬─┬─┬ ─ ─┬─┬─┬─┬ ─ ─ ┬─┬─┬─┬─┬─┬─┐ │ 0│ 0│ 0│ 0│ │ 0│ 0│ 0│ │ 0│ 0│ 0│ 0│ 0│ 1│ └─┴─┴─┴─┴ ─ ─┴─┴─┴─┴ ─ ─ ┴─┴─┴─┴─┴─┴─┘ ループ2回目 31 30 29 28 18 17 16 5 4 3 2 1 0 ┌─┬─┬─┬─┬ ─ ─┬─┬─┬─┬ ─ ─ ┬─┬─┬─┬─┬─┬─┐ │ 0│ 0│ 0│ 0│ │ 0│ 0│ 0│ │ 0│ 0│ 0│ 0│ 1│ 0│ └─┴─┴─┴─┴ ─ ─┴─┴─┴─┴ ─ ─ ┴─┴─┴─┴─┴─┴─┘ ... ... ループ131031回目 31 30 29 28 18 17 16 5 4 3 2 1 0 ┌─┬─┬─┬─┬ ─ ─┬─┬─┬─┬ ─ ─ ┬─┬─┬─┬─┬─┬─┐ │ 0│ 0│ 0│ 0│ │ 0│ 0│ 1│ │ 1│ 1│ 1│ 1│ 1│ 1│ └─┴─┴─┴─┴ ─ ─┴─┴─┴─┴ ─ ─ ┴─┴─┴─┴─┴─┴─┘ ループ131032回目 31 30 29 28 18 17 16 5 4 3 2 1 0 ┌─┬─┬─┬─┬ ─ ─┬─┬─┬─┬ ─ ─ ┬─┬─┬─┬─┬─┬─┐ │ 0│ 0│ 0│ 0│ │ 0│ 1│ 0│ │ 0│ 0│ 0│ 0│ 0│ 0│ └─┴─┴─┴─┴ ─ ─┴─┴─┴─┴ ─ ─ ┴─┴─┴─┴─┴─┴─┘ ↑ ビット17 ... ... ループ262064回目 31 30 29 28 18 17 16 5 4 3 2 1 0 ┌─┬─┬─┬─┬ ─ ─┬─┬─┬─┬ ─ ─ ┬─┬─┬─┬─┬─┬─┐ │ 0│ 0│ 0│ 0│ │ 1│ 0│ 0│ │ 0│ 0│ 0│ 0│ 0│ 0│ └─┴─┴─┴─┴ ─ ─┴─┴─┴─┴ ─ ─ ┴─┴─┴─┴─┴─┴─┘ ↑ ビット17 ビット17はループ回数が131032回ごとに値が変化します。 1回のループが9μsecであった場合、131032回ループの所要時間は、 9μsec * 131032 = 1.18sec です。 変数 loop_count のビット17の値によりプログラムの流れを変えることにより LEDを約 1.2秒間隔でON・OFFさせることが出来ます。 一回のループ時間 9μsecの出所は、このテキストの最後を参照してください。 6.3. 変数loop_countのチェック loop_countのビット17の値は以下のようにして判定します。 loop_count の値 00000000000000011111111111111111 (131031=0x0001FFFF) 論理積) 00000000000000100000000000000000 (131032=0x00020000) ------------------------------------------------------- 00000000000000000000000000000000 → 答えは0になります loop_count の値 00000000000000100000000000000000 (131032=0x00020000) 論理積) 00000000000000100000000000000000 (131032=0x00020000) ------------------------------------------------------- 00000000000000100000000000000000 → 答えは0以外になります C言語で記述すると if( loop_count & 0x00020000 ){ /* 結果が0以外なら、LEDをONにします。 */ }else{ /* 結果が0なら、LEDをOFFにします。 */ } です。 6.4. プログラムの編集 「スタート」→「プログラム」→「Keil uVision2」を順にクリックします。 Keil uVision2パネルの「Project」→「Open Project」をクリックし、 解凍したフォルダの \LedOnOff.Uv2 を選択して「開く」をクリックします。 プロジェクトフレームの[Source Group1][LedOnOff.c]をダブルクリックします。 LedOnOff.cのソースコードが表示されます。 //-------------------------------------------------------------------------- #include #include main() { OEB = 1; // POATB BIT0:OUTPUT while(TRUE){ OUTB |= bmBIT0; // LED ON OUTB &= ~bmBIT0; // LED OFF } } //-------------------------------------------------------------------------- を //-------------------------------------------------------------------------- #include #include main() { long loop_count; loop_count = 0; OEB = 1; // PORTB BIT0:OUTPUT while(TRUE){ if( loop_count & 0x20000 ){ OUTB |= bmBIT0; // LED ON }else{ OUTB &= ~bmBIT0; // LED OFF } loop_count++; // loop_count = loop_count + 1 } } //-------------------------------------------------------------------------- に書き換えます。 6.5. コンパイル │↓│ Keil uVision2パネルの └─┘ マークの釦をクリックしてください。 コンパイルが始まり、LedOnOff.hex が更新されます。 EZ-USB Control Panelの[DOWN LOAD]釦をクリックし、更新した"LedOnOff.hex"を選択 し、「開く」釦を押してください。 プログラムのダウンロード後、EZ-USBマイコンがプログラムを実行し、約1.2秒ごとに LEDがON・OFFします。 6.6. ループの所要時間について 以下は、LedOnOff.cをコンパイルして生成したアセンブリ言語プログラムで、 main()関数の部分です。 ----------------------------------------------------------------------------- ASSEMBLY LISTING OF GENERATED OBJECT CODE ; FUNCTION main (BEGIN) ; SOURCE LINE # 16 ; SOURCE LINE # 17 ; SOURCE LINE # 20 0000 E4 CLR A 0001 F500 R MOV loop_count+03H,A 0003 F500 R MOV loop_count+02H,A 0005 F500 R MOV loop_count+01H,A 0007 F500 R MOV loop_count,A ; SOURCE LINE # 22 0009 900000 E MOV DPTR,#OEB 000C 04 INC A 000D F0 MOVX @DPTR,A 000E ?C0001: ; SOURCE LINE # 24 ; SOURCE LINE # 25 000E E4 CLR A 000F FF MOV R7,A 0010 FE MOV R6,A 0011 E500 R MOV A,loop_count+01H 0013 5402 ANL A,#02H 0015 FD MOV R5,A 0016 E4 CLR A 0017 FC MOV R4,A 0018 ED MOV A,R5 0019 6009 JZ ?C0003 ; SOURCE LINE # 26 001B 900000 E MOV DPTR,#OUTB 001E E0 MOVX A,@DPTR 001F 4401 ORL A,#01H 0021 F0 MOVX @DPTR,A ; SOURCE LINE # 27 0022 8007 SJMP ?C0004 0024 ?C0003: ; SOURCE LINE # 28 0024 900000 E MOV DPTR,#OUTB 0027 E0 MOVX A,@DPTR 0028 54FE ANL A,#0FEH 002A F0 MOVX @DPTR,A ; SOURCE LINE # 29 002B ?C0004: ; SOURCE LINE # 30 002B E4 CLR A 002C FA MOV R2,A 002D F9 MOV R1,A 002E F8 MOV R0,A 002F E500 R MOV A,loop_count+03H 0031 2401 ADD A,#01H 0033 F500 R MOV loop_count+03H,A 0035 EA MOV A,R2 0036 3500 R ADDC A,loop_count+02H 0038 F500 R MOV loop_count+02H,A 003A E9 MOV A,R1 003B 3500 R ADDC A,loop_count+01H 003D F500 R MOV loop_count+01H,A 003F E8 MOV A,R0 0040 3500 R ADDC A,loop_count 0042 F500 R MOV loop_count,A ; SOURCE LINE # 31 C51 COMPILER V6.10 LEDONOFF 06/18/2004 15:46:18 PAGE 3 0044 80C8 SJMP ?C0001 ; FUNCTION main (END) ----------------------------------------------------------------------------- このなかで、while文の先頭からPORTB-0に1を出力し、while文に戻るまでの流れは以 下のようになります。上から順に実行します。 000E ?C0001: 000E E4 1 CLR A ;while文の先頭 000F FF 1 MOV R7,A 0010 FE 1 MOV R6,A 0011 E500 R 2 MOV A,loop_count+01H 0013 5402 2 ANL A,#02H ;loop_countのビット17を判定 0015 FD 1 MOV R5,A 0016 E4 1 CLR A 0017 FC 1 MOV R4,A 0018 ED 1 MOV A,R5 0019 6009 3 JZ ?C0003 ;loop_countのビット17が0なら?C0003へ 001B 900000 E 3 MOV DPTR,#OUTB 001E E0 2 MOVX A,@DPTR 001F 4401 2 ORL A,#01H 0021 F0 2 MOVX @DPTR,A 0022 8007 3 SJMP ?C0004 ;loop_countのビット17が1なら?C0004へ 002B ?C0004: 002B E4 1 CLR A 002C FA 1 MOV R2,A 002D F9 1 MOV R1,A 002E F8 1 MOV R0,A 002F E500 R 2 MOV A,loop_count+03H ;loop_countをインクリメント 0031 2401 2 ADD A,#01H 0033 F500 R 2 MOV loop_count+03H,A 0035 EA 1 MOV A,R2 0036 3500 R 2 ADDC A,loop_count+02H ;loop_count内2バイト目へ桁上げ 0038 F500 R 2 MOV loop_count+02H,A 003A E9 1 MOV A,R1 003B 3500 R 2 ADDC A,loop_count+01H ;loop_count内3バイト目へ桁上げ 003D F500 R 2 MOV loop_count+01H,A 003F E8 1 MOV A,R0 0040 3500 R 2 ADDC A,loop_count ;loop_count内4バイト目へ桁上げ 0042 F500 R 2 MOV loop_count,A 0044 80C8 3 SJMP ?C0001 ;while文の先頭へジャンプ ↑ は1命令の実行サイクル数を追記しました。 命令の実行サイクル数の合計は54命令サイクルです。 54命令サイクルの所要時間は 54[命令サイクル] * (1 / 24MHz)[クロック周期] * 4[クロック数/命令サイクル] = 9μsec です。 ここで (1 / 24MHz)[クロック周期]は、マイコンの源発振周波数の1クロック時間を示しま す。 4[クロック数/命令サイクル]は、1命令サイクルがマイコンの源発振周波数の4クロ ックであることを示します。 C言語で書くと簡単なプログラムも、アセンブリ言語に置き換えると多くのステップで 出来ていることが分かると思います。
Topへ

[PR]話題の新車を無料プレゼント中:必ず当る抽選会!今すぐ応募で簡単GET