目次>6章 第3ステップ(実用品)>PICテストボード(スイッチ,LED)>ソース
PICテストボード(スイッチ,LED)(ソース)
更新日2006.10.21
以下のソースを取り込んで、アセンブル→PIC書き込み→実行して下さい。
; ========================== ここから ============================== ; CLOCK 20MHz ; PORTA RA2〜4:プッシュボタンスイッチ ; PORTB RB0〜7:LED赤 ; ; ; LIST P=PIC16F84A ; LIST宣言で、使用するPICをPIC16F84Aと定義する INCLUDE P16F84A.INC ; 設定ファイルp16f84a.incを読み込む __CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF save_w EQU 0Ch ; W save save_st EQU 0Dh ; STATUS save t_add EQU 0Eh ; t_widthを可変にする時、t_widthに加算する数(+−) t_width EQU 0Fh ; PWMの幅(0〜63 ×4) t_count EQU 010h ; 0.1mS毎のカウンタ(0〜63 4ずつ加算,0になったら1サイクル) tc1 EQU 011h ; 1mSカウンタ(10) tc10 EQU 012h ; 10mSカウンタ(98) tc100_1 EQU 013h ; 100mSカウンタ1(122) tc100_2 EQU 014h ; 100mSカウンタ2(8) tc500_2 EQU 015h ; 500mSカウンタ2(40) timer EQU 016h ; タイマ割込みフラグ tm01 EQU 01h ;0.1mS tm1 EQU 02h ;1mS tm10 EQU 03h ;10mS tm100 EQU 04h ;100mS tm500 EQU 05h ;500mS mode1 EQU 017h ; mode1 処理 ; 0 なにもしない(LEDの表示は直前のまま)。 ; 1 初期状態。RB0を0.5秒毎に点滅,RB7を点灯。 ; 2 RA2SWが押された。RA2SWを押す毎にLEDを1つ点灯移動。 ; 4 RA3SWが押された。8個のLEDを2進数として100mS毎に+1した結果を表示する。 ; RA3SWもう一度押すと全てのLEDを消灯する。 ; 8 RA4SWが押された。LED1つを100ms毎に点灯移動する。 ; 16 RA4SWをもう1回押すと、その時ONだったLEDを徐々に暗くし徐々に明るくを繰り返す。 RA2stat EQU 018h RA3stat EQU 019h RA4stat EQU 01Ah ; RA*のスイッチ状態(チャタリングキャンセル用) ; 00000000 初期状態(スイッチは押されていない) ; 00000001 スイッチが押された(チャタリングキャンセル開始) ; 00000010 スイッチが押された後、10mS割込み1回経過(チャタリングキャンセル待ち) ; 10000010 スイッチが押された後、10mS割込み2回経過(確定) ; 11000010 スイッチON処理済み PBwork EQU 01Bh ; ============= 処理開始 ======================================= ORG 0 ; リセットベクタ(0番地)を指定する。 GOTO INIT ; 初期処理に行く ; ============= TMR0割込み処理 ================================= ORG 4 ; 割込みベクタ(4番地)を指定する。 BCF INTCON,T0IF ; 割込みフラグクリア MOVWF save_w ; W-regセーブ SWAPF STATUS,W MOVWF save_st ; STATUSレジスタセーブ BSF timer,tm01 ; 0.1mSフラグセット DECFSZ tc1,F GOTO T0_10 BSF timer,tm1 ; 1mSフラグセット MOVLW d'10' MOVWF tc1 ; 1mSカウンタ(10) T0_10 DECFSZ tc10,F GOTO T0_100 BSF timer,tm10 ; 10mSフラグセット MOVLW d'98' MOVWF tc10 ; 10mSカウンタ(98) T0_100 DECFSZ tc100_1,F GOTO T0EXIT MOVLW d'122' MOVWF tc100_1 ; 100mSカウンタ1(122) DECFSZ tc100_2,F GOTO T0_500 BSF timer,tm100 ; 100mSフラグセット MOVLW d'8' MOVWF tc100_2 ; 100mSカウンタ2(8) T0_500 DECFSZ tc500_2,F GOTO T0EXIT MOVLW d'40' MOVWF tc500_2 ; 500mSカウンタ2(40) BSF timer,tm500 ; 500mSフラグセット T0EXIT SWAPF save_st,W MOVWF STATUS ; STATUSレジスタロード SWAPF save_w,F SWAPF save_w,W ; W-regロード RETFIE ; 割込み許可にしてリターン ; ここまでTMR0割込み処理 ; ============= 初期処理 ================================= INIT ; << ポートの初期化 >> BSF STATUS,RP0 ; ■バンク1 MOVLW 0FFh MOVWF TRISA ; PORTAは全て入力 CLRF TRISB ; PORTBは全て出力 BCF STATUS,RP0 ; ■バンク0 ; << TMR0割込みの初期化 >> BSF STATUS,RP0 ; ■バンク1 MOVLW 080h ; OPTIONレジスタの設定 MOVWF OPTION_REG ; PORTBプルアップなし ,TMR0クロック:内部 ,プリスケーラ:TMR0で2 BCF STATUS,RP0 ; ■バンク0 MOVLW 0A0h ; INTCONの設定 MOVWF INTCON ; GIE:1 ,T0IE:1 CLRF TMR0 ; TMR0をクリア ; << カウンタの初期化 >> CLRF PORTB ; RB0-7:OFF CLRF t_width CLRF t_count MOVLW d'10' MOVWF tc1 ; 1mSカウンタ(10) MOVLW d'98' MOVWF tc10 ; 10mSカウンタ(98) MOVLW d'122' MOVWF tc100_1 ; 100mSカウンタ1(122) MOVLW d'8' MOVWF tc100_2 ; 100mSカウンタ2(8) MOVLW d'40' MOVWF tc500_2 ; 500mSカウンタ2(40) ; << 初期動作設定 >> MOVLW 01h MOVWF mode1 ; RB0のLEDを0.5秒毎に点滅 BSF PORTB,7 ; RB7のLEDを点灯 ; ============= メイン処理 ================================= LOOP BTFSC timer,tm01 CALL St01 ; 0.1mS経過処理 BTFSC timer,tm1 CALL St1 ; 1mS経過処理 BTFSC timer,tm10 CALL St10 ; 10mS経過処理 BTFSC timer,tm100 CALL St100 ; 100mS経過処理 BTFSC timer,tm500 CALL St500 ; 500mS経過処理 BTFSS PORTA,2 CALL RA2on ; RA2 ON処理 BTFSS PORTA,3 CALL RA3on ; RA3 ON処理 BTFSS PORTA,4 CALL RA4on ; RA4 ON処理 GOTO LOOP ; ============= 0.1mS割込み処理 ================================= St01 BCF timer,tm01 BTFSS mode1,4 ; mode1=16? GOTO St01_20 ; No MOVLW 04h ADDWF t_count,F BTFSS STATUS,Z ; 1サイクル終了? GOTO St01_10 ; No ; Yes MOVF PBwork,W MOVWF PORTB MOVF t_add,W ADDWF t_width,F ; パルス幅にt_add(+-あり)を加算 BTFSS STATUS,Z ; パルス幅0? GOTO St01_10 ; No ; t_addの+-反転 MOVLW 0FFh XORWF t_add,F INCF t_add,F St01_10 MOVF t_count,W SUBWF t_width,W BTFSS STATUS,Z ; t_count = t_width ? GOTO St01_20 ; No MOVF PBwork,W XORWF PORTB,F St01_20 RETURN ; ============= 1mS割込み処理 ================================= St1 BCF timer,tm1 RETURN ; ============= 10mS割込み処理 ================================= St10 BCF timer,tm10 ; <RA2のチャタリングキャンセル処理> MOVF RA2stat,W ; RA2statは BTFSC STATUS,Z ; 0? GOTO St10RA3 ; Yes BTFSS RA2stat,0 ; チャタリングキャンセル開始? GOTO St10RA2_1 ; No MOVLW 02h ; RA2statを、b'00000010'にする MOVWF RA2stat ; (チャタリングキャンセル待ち) GOTO St10RA3 St10RA2_1 BTFSS RA2stat,1 ; チャタリングキャンセル待ち? GOTO St10RA3 ; No BTFSS PORTA,2 ; RA2 on? GOTO St10RA2_2 ; Yes CLRF RA2stat GOTO St10RA3 St10RA2_2 BSF RA2stat,7 ; RA2 on 確定 St10RA3 ; <RA3のチャタリングキャンセル処理> MOVF RA3stat,W ; RA3statは BTFSC STATUS,Z ; 0? GOTO St10RA4 ; Yes BTFSS RA3stat,0 ; チャタリングキャンセル開始? GOTO St10RA3_1 ; No MOVLW 02h ; RA3statを、b'00000010'にする MOVWF RA3stat ; (チャタリングキャンセル待ち) GOTO St10RA4 St10RA3_1 BTFSS RA3stat,1 ; チャタリングキャンセル待ち? GOTO St10RA4 ; No BTFSS PORTA,3 ; RA3 on? GOTO St10RA3_2 ; Yes CLRF RA3stat GOTO St10RA4 St10RA3_2 BSF RA3stat,7 ; RA3 on 確定 St10RA4 ; <RA4のチャタリングキャンセル処理> MOVF RA4stat,W ; RA4statは BTFSC STATUS,Z ; 0? GOTO St10_10 ; Yes BTFSS RA4stat,0 ; チャタリングキャンセル開始? GOTO St10RA4_1 ; No MOVLW 02h ; RA4statを、b'00000010'にする MOVWF RA4stat ; (チャタリングキャンセル待ち) GOTO St10_10 St10RA4_1 BTFSS RA4stat,1 ; チャタリングキャンセル待ち? GOTO St10_10 ; No BTFSS PORTA,4 ; RA4 on? GOTO St10RA4_2 ; Yes CLRF RA4stat GOTO St10_10 St10RA4_2 BSF RA4stat,7 ; RA4 on 確定 St10_10 RETURN ; ============= 100mS割込み処理 ================================= St100 BCF timer,tm100 BTFSS mode1,2 ; mode1=4? GOTO St100_10 ; No INCF PBwork,F MOVF PBwork,W MOVWF PORTB GOTO St100_exit St100_10 BTFSS mode1,3 ; mode1=8? GOTO St100_20 ; No BCF STATUS,C RLF PBwork,F BTFSS STATUS,C GOTO St100_11 MOVLW 01h MOVWF PBwork St100_11 MOVF PBwork,W MOVWF PORTB GOTO St100_exit St100_20 St100_exit RETURN ; ============= 500mS割込み処理 ================================= St500 BCF timer,tm500 BTFSS mode1,0 ; mode1=1? GOTO St500E ; No MOVLW 01h XORWF PORTB,F ; RB0の出力を反転 St500E RETURN ; ============= RA2 on処理 ================================= RA2on MOVF RA2stat,W ; RA2statは BTFSS STATUS,Z ; 0? GOTO RA2on_1 ; No BSF RA2stat,0 ; チャタリングキャンセル開始 GOTO RA2on_exit RA2on_1 BTFSS RA2stat,7 ; スイッチ押下確定? GOTO RA2on_exit ; No BTFSC RA2stat,6 ; スイッチ押下処理済み? GOTO RA2on_exit ; Yes BSF RA2stat,6 ; スイッチ押下処理済みセット BTFSC mode1,1 ; mode1=2? GOTO RA2on_10 ; Yes MOVLW 02h MOVWF mode1 ; mode1=2 MOVLW 080h MOVWF PBwork RA2on_10 BCF STATUS,C RLF PBwork,F BTFSC STATUS,C BSF PBwork,0 MOVF PBwork,W MOVWF PORTB RA2on_exit RETURN ; ============= RA3 on処理 ================================= RA3on MOVF RA3stat,W ; RA3statは BTFSS STATUS,Z ; 0? GOTO RA3on_1 ; No BSF RA3stat,0 ; チャタリングキャンセル開始 GOTO RA3on_exit RA3on_1 BTFSS RA3stat,7 ; スイッチ押下確定? GOTO RA3on_exit ; No BTFSC RA3stat,6 ; スイッチ押下処理済み? GOTO RA3on_exit ; Yes BSF RA3stat,6 ; スイッチ押下処理済みセット BTFSS mode1,2 ; mode1=4? GOTO RA3on_10 ; No CLRF mode1 CLRF PORTB GOTO RA3on_exit RA3on_10 MOVLW 04h ; mode1=4 MOVWF mode1 CLRF PBwork RA3on_exit RETURN ; ============= RA4 on処理 ================================= RA4on MOVF RA4stat,W ; RA4statは BTFSS STATUS,Z ; 0? GOTO RA4on_1 ; No BSF RA4stat,0 ; チャタリングキャンセル開始 GOTO RA4on_exit RA4on_1 BTFSS RA4stat,7 ; スイッチ押下確定? GOTO RA4on_exit ; No BTFSC RA4stat,6 ; スイッチ押下処理済み? GOTO RA4on_exit ; Yes BSF RA4stat,6 ; スイッチ押下処理済みセット BTFSS mode1,3 ; mode1=8? GOTO RA4on_10 ; No BTFSS mode1,4 ; mode1=16? GOTO RA4on_20 ; No CLRF mode1 CLRF PORTB GOTO RA4on_exit RA4on_10 MOVLW 08h ; mode1=8 MOVWF mode1 MOVLW 01h MOVWF PBwork GOTO RA4on_exit RA4on_20 MOVLW 010h ; mode1=16 MOVWF mode1 MOVLW 0FCh MOVWF t_add MOVWF t_width CLRF t_count GOTO RA4on_exit RA4on_exit RETURN END ; =========================== ここまで ===============================