平成 18 年 5 月 25 日(木) LEDルーレットの製作 1.概要 PIC マイコンは発光ダイオード(LED)をポートに接続し、点灯させることが可能だ。 PIC のソフトウェアからはポートを High 状態にすればよいだけなので、PIC の入門用 工作では LED フラッシャーが題材としてよく取り上げられている。この工作では単な る LED フラッシャーではなく通常の LED と 7 セグメント LED の点灯制御を行い、割 り込み処理を使った電子ルーレットを製作する。 2.7セグメントLEDの点灯制御 7 セグメント LED は、電卓やデジタル時計などに見られる7つの線(セグメント)を 組み合わせて 0 から 9 までの数字を表示できる部品である。今回入手したものは三洋電 機 SL-1199 で、内部では8つの LED(うち1つは小数点用)のアノード側が接続され共 通端子として、各 LED のカソード側がそれぞれ部品底面から出ている。各セグメント の LED を点灯するためには PIC のポートを出力に設定し、L レベルを出力することで そのポートに接続したセグメントが点灯する。以下の図は各端子と各セグメントの対応 を示したものである(図 1)。 a f 8 g e ba b fg com c d p pc 表示面 de 端子面 図1:7セグメントLED(SL-1199)の端子とセグメントの対応 数字を表示するためには各セグメントを組み合わせて点灯する。例えば 1 ならば、セ グメント b と c を点灯すればよい。以下に、数字とそれを表示するための各セグメント の組み合わせを示す(表1)。今回はこれをビットパターンに置き換え、ポートに出力す ることで表示を行う。実装にはテーブルルックアップを用いる。 数字 セグメント 数字 セグメント 0 a,b,c,d,e,f 5 a,c,d,f,g 1 b,c 6 a,c,d,e,f,g 2 a,b,d,e,g 7 a,b,c,f 3 a,b,c,d,g 8 a,b,c,d,e,f,g 4 b,c,f,g 9 a,b,c,d,f,g 表1:数字と各セグメントの組み合わせ -1- 3.プッシュスイッチによる割り込み処理 この装置ではルーレットのスタートボタンとしてプッシュスイッチを使う。PIC にス イッチを接続する場合、プルアップ接続をするのが一般的である。これはスイッチを接 続する PIC のポートを 10k オーム程度の抵抗を通して電源ラインと接続した上で、ス イッチを押した際にポートと抵抗の間と GND が接続されるようにスイッチを接続する ことである(図2)。このようにすることでスイッチをそのまま PIC に接続した場合と比 べ、電位の状態がはっきりする。注意すべき点はスイッチが ON の状態で入力電圧が L レベルとなり、OFF の状態で H レベルとなる点である。 VCC PICへ 図2:プルアップ接続 またこの工作ではスイッチの処理に RB0/INT 割り込み処理を利用している。これは PIC の PIC16F シリーズの標準機能で RB0 ポートの入力電圧が変化すると、PIC は現在 の処理を中断しプログラムメモリ4番地に書かれたプログラムから実行するというもの である。中断された処理は割り込みによって実行されたプログラムの最後の retfie 命令 を実行後に、プログラムメモリ上の元の場所に戻り処理が再開されるが、W レジスタ など SFR の内容は割り込み処理中に変化している。このため場合によっては割り込み 後の処理が正常に行われないこともあるため、割り込みが発生してから実際の割り込み 処理を開始する前にこれらの SFR の内容を別の場所に退避する必要がある。退避すべ き SFR は W、STATUS、PCLATH の三種類だが、退避処理の最中にこれらのレジスタ が変化してしまうことのないよう注意が必要である。この装置は電源投入後 LED フラ ッシャーとして動作しているが、スイッチを押すとスイッチが接続されたポートの電位 が変化、割り込みが発生し一定時間ルーレットとして動作する。 4.回路図 -2- 5.部品表 種類 型名 備考 抵抗 510 オーム(13 本) LED 電流制限用 10k オーム(3 本) プルアップ用 0.1uF 積層セラミック 47uF(耐圧 16V) 電解コンデンサ コンデンサ IC PIC16F648A 3端子レギュレーター 78L05 LED LED(6 個) SL-1199(7セグメント LED) アノードコモン その他 プッシュスイッチ 1回路1接点 ユニバーサル基盤 ICB288 サイズ IC ソケット(18 ピン用) 配線材等 ※部品の数量は特に指定がなければ各1個。 6.ハードウェア この回路の中心をなすのは 18 ピンの PIC16F648A である。今回の工作では必要なピ ンの数が多く、LED で 6、7 セグメント LED で 7、プッシュスイッチで 1 ピンの計 14 ピンが必要である。そのため PIC の内蔵オシレーターを使い、必要な出力ピン数を確 保した。RA4 ポートは内部がオープンドレイン構造のため High レベルを出力しても LED の電源電圧を確保できず、RA5 はもともと MCLR ピンであるため出力ピンには設 定できないため使用しなかった。なお RA5 は念のためプルアップしてある。 また 7 セグメント LED はアノードコモンタイプであるため、7 セグメント LED から PIC に電流が流れ込むようにしてやる必要がある。このためには PIC のピンを出力ピン に設定したうえで、電流を流し込みたいポートを Low レベルにすれば電流が PIC に流 れ込むようになり、7 セグメント LED の対応するセグメントが点灯する。消灯する場 合は High レベルを出力する。 LED は特に変わった回路ではないが、この装置のルーレットという性格のため、基 盤上の物理的な配置をなるべく円形になるよう配線を工夫している。 電源部はこの装置を持ち運ぶことも考慮し、小型で 9V の電圧が得られる 006P 型の 乾電池が使えるよう三端子レギュレーター 78L05 を採用した。 装置全体は小型となるよう名刺サイズのユニバーサル基盤上に組んである。 7.ソフトウェア 大まかな流れは PIC の初期化終了後、6 個の LED が接続されたポート A の内容を左 シフトして LED を順に点灯している。RA4 と RA5 は LED が接続されていないため、 RA4 にビットが立った場合、RA6 にビットが立つまで左シフトを繰り返し LED の点灯 が途切れないようにしている。また RA7 にビットが立った状態で左シフトをするとレ -3- ジスタは 0 になり、STATUS レジスタの C(キャリー)フラグに立つ。このままではどの LED も点灯しないため、C フラグにビットが立ったことを検出してもう一度左シフト をするようにする。こうすることでレジスタは 1 になり、LED が途切れることなく点 灯する(図3)。 LEDの点灯 ウェイト RA4 = 1? No Yes 左シフト2回 Cフラグが1? 左シフト ルーレットカウンタ カウントアップ処理 図3:main_loopフローチャート 先にも述べたがこの装置では割り込み処理を利用している。割り込み処理の説明はす でにし たが 、注 意点と して RB0/INT 割 り 込みの設 定項目 である OPTION_REG の INTEDG フラグを立てることが挙げられる。RB0 に接続されたスイッチはプルアップ接 続をしているため、ON 時に Low レベル、OFF 時に High レベルのように実際のスイッ チの状態とは逆の入力となっている。そのため割り込みを発生させるタイミングを入力 レベルが 5V から 0V に変化した場合に設定し、スイッチを押した瞬間に割り込みが発 生するようにする必要がある。この設定をしないと、スイッチを押した瞬間には割り込 みは発生せず、スイッチを離した瞬間に割り込みが発生するようになり操作レスポンス が悪くなる。 7 セグメント LED の点灯制御は複数のセグメントを同時に制御しなければならない 点と、アノードコモンであるためポートを Low レベルにした際にセグメントが点灯す るという点が通常の LED とは異なる。数字を点灯するためには先に(表1)で示したよ うにセグメントを点灯すればよい。なおアノードコモンタイプであるためこの表に示さ れているセグメントを Low レベルにし、それ以外のセグメントを High レベルにすると -4- いう点に注意が必要だ。また各ポートのレベルを一つずつ設定してゆくのは、煩雑で間 違いが起こりやすいため、あらかじめ各数字を表示するためのポート状態を列記した定 数テーブルを用意し、テーブルルックアップを用いてこれを参照している。テーブルル ックアップはテーブルルックアップ用サブルーチンを設け、その中でプログラムカウン タに W レジスタの内容を加えてその場所の定数を参照し、その値を W レジスタに入れ たまま呼び出し元に持ち帰るというものである。このプログラムでは count レジスタ内 の数字を W レジスタに代入し、テーブルルックアップルーチンをコール、その値に対 応する 7 セグメント LED 用のポート状態を持ち帰っている。ここで持ち帰った値はカ ソードコモンの 7 セグメント LED 用であるため、それを 0xFE(RB0 を除いている)と XOR 演算することで反転している。その値を PORTB に代入することで数字を表示し ている。 ルーレット動作はきわめて単純なアルゴリズムである。まず電源投入時からプッシュ スイッチが押されるまでは、点灯している LED をシフトするタイミングで count レジ スタの値を一つずつ増やしてゆき、6 を超えたらまた 1 から数え直すという動作をして いる。プッシュスイッチが押されると、カウントアップと LED を順送りする間隔が早 まりを、一定回数これを繰り返すとカウントアップと LED を順送りをやめ、LED と 7 セグメント LED の表示を一定時間持続した後、LED フラッシャーモードに復帰する。 8.動作 この装置は電源を投入するとすぐに LED フラッシャーとして動作し、6 つの LED が 順に点灯する。基盤上のプッシュスイッチを押すと 6 つの LED が点灯する間隔が速ま り、同時に 7 セグメント LED に数字がカウントアップされる様子が表示される。一定 回数(10 回)これを繰り返すと LED と数字のカウントアップは止まり、止まったときの 状態を一定時間(2000ms = 2 秒)維持した後に LED フラッシャーとしての動作を再開す る。 9.参考文献 ●「やさしい PIC マイコン プログラミング&電子工作」 高橋隆雄著 秀和システム ●「はじめての PIC アセンブラ入門」 光永法明・後田敏著 CQ 出版社刊 10.アセンブリソース list p=16f648A #include <p16F648A.inc> ; list directive to define processor ; processor specific variable definitions errorlevel -302 ; suppress message 302 from list file __CONFIG _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT -5- ;***** VARIABLE DEFINITIONS w_temp EQU 0x71 ; variable used for context saving status_temp EQU 0x72 ; variable used for context saving pclath_temp EQU 0x73 ; variable used for context saving count EQU 0x20 led EQU 0x21 segment EQ 0x22 cnt1 EQU 0x23 cnt2 EQU 0x24 r_cnt EQU 0x25 s_cnt EQU 0x26 ;***** CONSTATS DEFINITIONS ROTATE_NUM EQU 0x10 SHOW_TIME EQU 0x08 ; 250ms * SHOW_TIME ;****************************************************************** ORG 0x000 ; processor reset vector goto main ; go to beginning of program ORG 0x004 ; interrupt vector location movwf w_temp ; W の退避 movf STATUS,w movwf status_temp movf PCLATH,w movwf pclath_temp ; STATUS の退避 ; PCLATH の退避 ; isr code can go here or be located as a call subroutine elsewhere btfss INTCON, INTF goto main_loop clrf INTCON ;btfss PORTB, SW ;goto main_loop movlw ROTATE_NUM ; 二重割り込み禁止 ; チャッタリングチェック ; ルーレット動作 -6- movwf r_cnt call rotate_loop movlw SHOW_TIME movwf s_cnt call show_wait movlw 0x90 movwf INTCON movf pclath_temp,w movwf PCLATH movf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ; 表示を維持 ; GIE, INTE 割り込み許可 ; PCLATH の復元 ; STATUS の復元 ; W の復元 ; return from interrupt main bcf STATUS, RP0 ; BANK0 bcf STATUS, RP1 clrf INTCON ; 割り込み禁止 clrf PORTA ; ポート初期化 clrf PORTB bsf STATUS, RP0 ; BANK1 bsf PCON, OSCF ; INTOSC = HighSpeed(4MHz) movlw 0x00 ; I/O の設定 movwf TRISA movlw 0x01 movwf TRISB bsf OPTION_REG, INTEDG bc STATUS, RP0 ; BANK0 -7- movlw 0x00 movwf count movlw 0x01 movwf led movf led, W movwf PORTA movlw 0xfe movwf PORTB movlw 0x90 movwf INTCON ; ルーレットカウンターの初期化 ; GIE, INTE 割り込み許可 main_loop ; LED 表示のためのウェイト call dly_250ms call dly_250ms rlf led, F ; 左シフト btfsc STATUS, C ; C フラグが立った rlf led, F btfsc led, 4 call double_shift movf led, W movwf PORTA incf count, F movf count, W xorlw 0x07 btfsc STATUS, Z call rst_count goto main_loop ; RA4 にビットが立った ; ルーレットカウンターの処理 ; カウンターが 7 になった ; RA4 から RA6 までシフト double_shift rlf led, F rlf led, F -8- return ; ルーレットカウンターを 1 に rst_count movlw 0x01 movwf count return dly_250ms ; 250ms movlw 0xfa movwf cnt1 dlp1 ; 1ms movlw 0xf0 movwf cnt2 dlp2 nop nop decfsz cnt2, F goto dlp2 decfsz cnt1, F goto dlp1 return ; ルーレットを回す処理 rotate_loop call rotation decfsz r_cnt, F goto rotate_loop return ; ルーレットを一つ分動かす rotation call dly_250ms rlf led, F btfsc STATUS, C rlf led, F btfsc led, 4 call double_shift -9- movf led, W movwf PORTA incf count, F movf count, W xorlw 0x07 btfsc STATUS, Z call rst_count call segment_table xorlw 0xfe movwf PORTB ; ルーレットカウンター周りの処理 ; 出力ビットを反転 return show_wait call dly_250ms decfsz s_cnt, F goto show_wait movlw 0xfe movwf PORTB ; 7 セグメント LED 消灯 return org 0x100 ; 7 セグメント LED 用定数テーブル segment_table movlw 0x01 movwf PCLATH movf count, W andlw 0x0f addwf PCL, F retlw B'01111110' ;0 retlw B'00001100' ;1 retlw B'10110110' ;2 retlw B'10011110' ;3 retlw B'11001100' ;4 retlw B'11011010' ;5 retlw B'11111010' ;6 - 10 - retlw B'01001110' ;7 retlw B'11111110' ;8 retlw B'11011110' ;9 retlw B'11101110' ;A retlw B'11111000' ;b retlw B'01110010' ;C retlw B'10111100' ;d retlw B'11110010' ;e retlw B'11100010' ;F ; initialize eeprom locations ORG 0x2100 DE 0x00, 0x01, 0x02, 0x03 END ; directive 'end of program' - 11 -
© Copyright 2024 Paperzz