PIC16F648でタイマ機能を使うときに参考になるサイト
・電力線通信技術
家庭用PLC機器製品として2万円台で登場しているという
のを以前WEBニュースで見たことがありました。
LANケーブルや無線LANアンテナを別途に設置する必要がなく、
一般の人も知っている電源コンセントでインターネット
利用できるこの技術は、まだセキュリティになどの問題を残すと言われて
いても注目されているブースと感じました。
会場では、すでに大規模ビル設備のネット装置として紹介している
製品などもありました。今後、さまざまな分野で応用が期待される
技術と感じました。
・PICのタイマなどのモジュールに関する説明
http://www.picfun.com/module00.html
・PIC16F648データシート
http://ww1.microchip.com/downloads/en/DeviceDoc/40044F.pdf
・RETFIEというアセンブラ命令
http://cai.cs.shinshu-u.ac.jp/susi/Lecture/microcomp/d_03-02-12.html
LIST P=PIC16F84 ;CPUの指定 INCLUDE "P16F84.INC" ;定数ラベルファイル ORG 0 ;RESETの入口 GOTO MAIN ;メインルーチンへ ORG 4 ;割込みの入口 GOTO INTR ;割込み処理ルーチンへ MAIN BSF STATUS,RP0 ;ページ1に切替え MOVLW 087H ;256カウントモード指定 MOVWF OPTION_REG ;プリセットカウンタへ出力 BCF STATUS,RP0 ;ページ0に切替え MOVLW 03CH ;カウント値ロード MOVWF TMR0 ;TMR0へ出力 BSF INTCON,T0IE ;タイマ割込み許可 BSF INTCON,GIE ;全体割込み許可 IDLE NOP (他の処理) GOTO IDLE ;割込み待ちループ INTR BCF INTCON,T0I ;割込みフラグクリア MOVLW 03CH ;カウント値ロード MOVWF TMR0 ;TMR0へ出力 (他の処理) RETFIE ;割込み許可リター
http://homepage1.nifty.com/rikiya/software/314.TIMER1.htm
list p=16F648A ; list directive to define processor #include <P16F648A.INC> ; processor specific variable definitions __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC ;***** VARIABLE DEFINITIONS w_temp02 EQU 0x0C ; variable used for context saving cnt_data EQU 0x26 CE_data EQU 0x27 w_temp EQU 0x28 ; variable used for context saving w_PORTA_temp EQU 0x29 ;PORTAの入力値の一時保管 cnt_data02 EQU 0x2A w_PORTA_temp02 EQU 0x2B CNT2 EQU 0x2C OUT_SIG1 EQU 0x2D CNT1 EQU 0x2E count EQU 0x2F CNT3 EQU 0x30 time3 EQU 0FFh ;LED time3 sound1_val EQU B'00000000' sound2_val EQU B'00001101' sound3_val EQU B'00011010' ;********************************************************************** ORG 0x000 ; processor reset vector goto main_setting ; go to beginning of program org 0x04 ; 割り込みアドレス btfsc PIE1,TMR1IE ;タイマー1の割り込み? goto INT_TMR1 ; カウントを開始へジャンプ btfsc PIE1,TMR2IE ;タイマー2の割り込み? goto INT_TMR2 ;カウント設定へジャンプ btfsc INTCON,T0IF ;タイマー0の割り込み? goto INT_TMR3 retfie ; 別の割り込みなら戻る ; main_setting bsf STATUS,RP0 ;メモリーバンクを1にセット movlw 007h movwf TRISA ;ポートAをすべて入力に設定 ; movlw 000h movwf TRISB ;ポートBをすべて出力に設定 ; ; bsf PCON,3 ;内部クロックを4MHzに設定 bcf OPTION_REG,5 ;ICの14pinをCLKOUTに設定 bcf RCSTA,7 ;RCSTAレジスタの7ビット目(RB1ポート)のシリアル通信を無効にする。 movlw 000H ;Wレジスタに80Hをセット movwf OPTION_REG ;OPTION_REGに80Hをセット PORT-B PULL UPなし bcf STATUS,RP0 ;メモリーバンクを0にセット movlw B'00000111' movwf CMCON ;PORTAをI/Oピンに設定する。 movlw 020h movwf PORTB ;ポートBを全OFF状態にする。 bsf PORTB,5 bsf w_temp,5 bsf CE_data,5 bsf T1CON,TMR1ON ;タイマ1をON start bsf INTCON,T0IE ;タイマ0の割り込みを許可する。 bcf INTCON,GIE ; 全体の割り込みを禁止する bcf INTCON,RBIE ; ポートBの割り込みを禁止する bcf INTCON,RBIF ; ポートBの割り込みを削除する bcf INTCON,INTE ; RB0 の割り込みを禁止する bsf STATUS,RP0 ; レジスタバンク1を選択 BSF PIE1,TMR1IE ;TMR1オーバーフロー割り込み許可 bsf OPTION_REG,INTEDG ; 立ち上がりで割り込みが反応する bcf OPTION_REG,NOT_RBPU ; ポートBのプルアップを有効にする movlw B'11111111' ; movwf TRISB ; ポートBを全部入力用にする movlw B'00000' ; movwf TRISA ; ポートAを全部出力用にする bcf STATUS,RP0 ; レジスタバンク0を選択 MOVLW 30H ;Wレジスタに30Hをセット MOVWF T1CON ;T1CONレジスタ プリスケーラ1:8 停止 MOVLW 00H ;Wレジスタに00Hをセット MOVWF TMR1L ;TMR1Lに下位8ビットデータをセット MOVLW 00H ;Wレジスタに00Hをセット MOVWF TMR1H ;TMR1Hに上位8ビットデータをセット CLRF CNT1 ;CNT1変数を00Hにクリア bsf INTCON,PEIE ;タイマ1、タイマ2の割り込みを許可する。 bcf PORTA,4 ; 赤いLEDを消す bsf INTCON,GIE ; 全体の割り込みを許可する BSF T1CON,TMR1ON ;TMR1のTMR1ONビットをセット カウント開始 wait goto wait ; 割り込みを待つ setcount movf PORTB,0 ; PORTB -> W andlw B'11110000' ; 下位 4 ビットを 0 にする movwf count ; W -> count swapf count,1 ; 上位 4 ビットと下位 4 ビットを入れ替える movf count,0 ; count -> W movwf PORTA ; W -> PORTA bcf INTCON,RBIF ; 割り込みをリセット retfie ; 割り込み処理から復帰 count_begin clrw ; 0 -> W movwf PORTA ; LEDを消す bsf PORTA,4 ; 赤いLEDを点灯 goto wait ; 割り込みを無効にしたまま待つ INT_TMR1 MOVLW 00H ;Wレジスタに00Hをセット MOVWF TMR1L ;TMR1Lに下位8ビットデータをセット MOVLW 00H ;Wレジスタに00Hをセット MOVWF TMR1H ;TMR1Hに上位8ビットデータをセット BCF PIR1,TMR1IF ;オーバーフローフラグのクリア BSF STATUS,RP0 ;メモリーバンクを1にセット BSF PIE1,TMR1IE ;オーバーフロー割り込み許可 BCF STATUS,RP0 ;メモリーバンクを0にセット INCF CNT1,F ;変数CNT1に+1する。 MOVF CNT1,W ;WレジスタにCNT1の値をセット MOVWF PORTB ;PORTBへCNT1の値を出力 ;[ if _DATA1 < _DATA2 then goto Xxx ] movf CNT1,W subwf 0xFF,W btfss STATUS,C goto Xxx RETFIE Xxx COMF OUT_SIG1 RETFIE ;割り込みを許可してリターン INT_TMR2 ; MOVLW 00H ;Wレジスタに00Hをセット ; MOVWF TMR2L ;TMR1Lに下位8ビットデータをセット ; MOVLW 00H ;Wレジスタに00Hをセット ; MOVWF TMR2H ;TMR1Hに上位8ビットデータをセット BCF PIR1,TMR2IF ;オーバーフローフラグのクリア BSF STATUS,RP0 ;メモリーバンクを1にセット BSF PIE1,TMR2IE ;オーバーフロー割り込み許可 BCF STATUS,RP0 ;メモリーバンクを0にセット INCF CNT2,F ;変数CNT1に+1する。 MOVF CNT2,W ;WレジスタにCNT1の値をセット MOVWF PORTB ;PORTBへCNT1の値を出力 RETFIE ;割り込みを許可してリターン INT_TMR3 BCF INTCON,T0IF ;オーバーフローフラグのクリア BSF STATUS,RP0 ;メモリーバンクを1にセット BSF INTCON,T0IE ;オーバーフロー割り込み許可 BCF STATUS,RP0 ;メモリーバンクを0にセット INCF CNT3,F ;変数CNT1に+1する。 MOVF CNT3,W ;WレジスタにCNT1の値をセット MOVWF PORTB ;PORTBへCNT1の値を出力 RETFIE END
;********************************************************************** ; Filename: miracle.asm * ; Date: 2001/3/26 * ; File Version: * ;********************************************************************** list p=16F648A ; list directive to define processor #include <P16F648A.INC> ; processor specific variable definitions __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC ;***** VARIABLE DEFINITIONS w_temp02 EQU 0x0C ; variable used for context saving cnt_data EQU 0x26 CE_data EQU 0x27 w_temp EQU 0x28 ; variable used for context saving w_PORTA_temp EQU 0x29 ;PORTAの入力値の一時保管 cnt_data02 EQU 0x2A w_PORTA_temp02 EQU 0x2B CNT2 EQU 0x2C OUT_SIG1 EQU 0x2D CNT1 EQU 0x2E count EQU 0x2F CNT3 EQU 0x30 CNT5 EQU 0x31 CNT6 EQU 0x32 CNT7 EQU 0x33 SW_CNT EQU 0x34 OSC_001_WAVE EQU 0x35 OSC_002_WAVE EQU 0x36 OSC_003_WAVE EQU 0x37 DATA2 EQU 0x38 CNT8 EQU 0x39 OSC_004_WAVE EQU 0x3A DATA4 EQU 0x3B DATA5 EQU 0x3C DATA1 EQU 0x3D DATA3 EQU 0x3E time3 EQU 0FFh ;LED time3 sound1_val EQU B'00000000' sound2_val EQU B'00001101' sound3_val EQU B'00011010' ;********************************************************************** ORG 0x000 ; processor reset vector goto main_setting ; go to beginning of program org 0x04 ; 割り込みアドレス btfsc PIE1,TMR1IE ;タイマー1の割り込み? goto INT_TMR1 ; カウントを開始へジャンプ btfsc PIE1,TMR2IE ;タイマー2の割り込み? goto INT_TMR2 ;カウント設定へジャンプ btfsc INTCON,T0IF ;タイマー0の割り込み? goto INT_TMR3 retfie ; 別の割り込みなら戻る ; main_setting bsf STATUS,RP0 ;メモリーバンクを1にセット movlw 007h movwf TRISA ;ポートAをすべて入力に設定 ; movlw 000h movwf TRISB ;ポートBをすべて出力に設定 ; ; bsf PCON,3 ;内部クロックを4MHzに設定 bcf OPTION_REG,5 ;ICの14pinをCLKOUTに設定 bcf RCSTA,7 ;RCSTAレジスタの7ビット目(RB1ポート)のシリアル通信を無効にする。 movlw 000H ;Wレジスタに80Hをセット movwf OPTION_REG ;OPTION_REGに80Hをセット PORT-B PULL UPなし bcf STATUS,RP0 ;メモリーバンクを0にセット movlw B'00000111' movwf CMCON ;PORTAをI/Oピンに設定する。 movlw 020h movwf PORTB ;ポートBを全OFF状態にする。 bsf PORTB,5 bsf w_temp,5 bsf CE_data,5 bsf T1CON,TMR1ON ;タイマ1をON start bsf INTCON,T0IE ;タイマ0の割り込みを許可する。 bcf INTCON,GIE ; 全体の割り込みを禁止する bcf INTCON,RBIE ; ポートBの割り込みを禁止する bcf INTCON,RBIF ; ポートBの割り込みを削除する bcf INTCON,INTE ; RB0 の割り込みを禁止する bsf STATUS,RP0 ; レジスタバンク1を選択 BSF PIE1,TMR1IE ;TMR1オーバーフロー割り込み許可 bsf OPTION_REG,INTEDG ; 立ち上がりで割り込みが反応する bcf OPTION_REG,NOT_RBPU ; ポートBのプルアップを有効にする movlw B'00000000' ; movwf TRISB ; ポートBを全部入力用にする movlw B'00000' ; movwf TRISA ; ポートAを全部出力用にする bcf STATUS,RP0 ; レジスタバンク0を選択 MOVLW 30H ;Wレジスタに30Hをセット MOVWF T1CON ;T1CONレジスタ プリスケーラ1:8 停止 MOVLW 00H ;Wレジスタに00Hをセット MOVWF TMR1L ;TMR1Lに下位8ビットデータをセット MOVLW 00H ;Wレジスタに00Hをセット MOVWF TMR1H ;TMR1Hに上位8ビットデータをセット CLRF CNT1 ;CNT1変数を00Hにクリア bsf INTCON,PEIE ;タイマ1、タイマ2の割り込みを許可する。 bcf PORTA,4 ; 赤いLEDを消す bsf INTCON,GIE ; 全体の割り込みを許可する BSF T1CON,TMR1ON ;TMR1のTMR1ONビットをセット カウント開始 movlw 0x00 movwf CNT1 movwf CNT2 movwf CNT3 movwf OSC_001_WAVE movwf OSC_002_WAVE movwf OSC_003_WAVE movwf SW_CNT movwf OSC_004_WAVE wait goto wait ; 割り込みを待つ setcount movf PORTB,0 ; PORTB -> W andlw B'11110000' ; 下位 4 ビットを 0 にする movwf count ; W -> count swapf count,1 ; 上位 4 ビットと下位 4 ビットを入れ替える movf count,0 ; count -> W movwf PORTA ; W -> PORTA bcf INTCON,RBIF ; 割り込みをリセット retfie ; 割り込み処理から復帰 count_begin clrw ; 0 -> W movwf PORTA ; LEDを消す bsf PORTA,4 ; 赤いLEDを点灯 goto wait ; 割り込みを無効にしたまま待つ INT_TMR1 bcf INTCON,GIE ; 全体の割り込みを禁止する MOVLW 00H ;Wレジスタに00Hをセット MOVWF TMR1L ;TMR1Lに下位8ビットデータをセット MOVLW 00H ;Wレジスタに00Hをセット MOVWF TMR1H ;TMR1Hに上位8ビットデータをセット BCF PIR1,TMR1IF ;オーバーフローフラグのクリア BSF STATUS,RP0 ;メモリーバンクを1にセット BSF PIE1,TMR1IE ;オーバーフロー割り込み許可 BCF STATUS,RP0 ;メモリーバンクを0にセット INCF CNT1,F ;変数CNT1に+1する。 MOVF CNT1,W ;WレジスタにCNT1の値をセット MOVWF PORTB ;PORTBへCNT1の値を出力 ;[ if _DATA1 < _DATA2 then goto Xxx ] ;movf CNT1,W ;subwf 0xFF,W ;btfss STATUS,C ;goto Xxx RETFIE Xxx COMF OUT_SIG1 RETFIE ;割り込みを許可してリターン INT_TMR2 ; MOVLW 00H ;Wレジスタに00Hをセット ; MOVWF TMR2L ;TMR1Lに下位8ビットデータをセット ; MOVLW 00H ;Wレジスタに00Hをセット ; MOVWF TMR2H ;TMR1Hに上位8ビットデータをセット bcf INTCON,GIE ; 全体の割り込みを禁止する BCF PIR1,TMR2IF ;オーバーフローフラグのクリア BSF STATUS,RP0 ;メモリーバンクを1にセット BSF PIE1,TMR2IE ;オーバーフロー割り込み許可 BCF STATUS,RP0 ;メモリーバンクを0にセット INCF CNT2,F ;変数CNT1に+1する。 MOVF CNT2,W ;WレジスタにCNT1の値をセット MOVWF PORTB ;PORTBへCNT1の値を出力 RETFIE ;割り込みを許可してリターン INT_TMR3 bcf INTCON,GIE ; 全体の割り込みを禁止する BCF INTCON,T0IF ;オーバーフローフラグのクリア BSF STATUS,RP0 ;メモリーバンクを1にセット BSF INTCON,T0IE ;オーバーフロー割り込み許可 BCF STATUS,RP0 ;メモリーバンクを0にセット INCF CNT3,F ;変数CNT1に+1する。 ; _DATA1 の bit 3 を _DATA2 の bit 7 にコピー ; btfss OSC_001_WAVE,0 bcf PORTB,0 btfsc OSC_001_WAVE,0 bsf PORTB,0 ; _DATA1 の bit 3 を _DATA2 の bit 7 にコピー ; btfss OSC_002_WAVE,0 bcf PORTB,1 btfsc OSC_002_WAVE,0 bsf PORTB,1 ; _DATA1 の bit 3 を _DATA2 の bit 7 にコピー ; btfss OSC_003_WAVE,0 bcf PORTB,2 btfsc OSC_003_WAVE,0 bsf PORTB,2 ; _DATA1 の bit 3 を _DATA2 の bit 7 にコピー ; btfss OSC_004_WAVE,0 bcf PORTB,3 btfsc OSC_004_WAVE,0 bsf PORTB,3 INCF SW_CNT,F ;[ if _DATA1 = _DATA2 then goto Xxx ] movlw 0x01 xorwf SW_CNT,W btfsc STATUS,Z goto OSC_001 ;[ if _DATA1 = _DATA2 then goto Xxx ] movlw 0x02 xorwf SW_CNT,W btfsc STATUS,Z goto OSC_002 ;[ if _DATA1 = _DATA2 then goto Xxx ] movlw 0x03 xorwf SW_CNT,W btfsc STATUS,Z goto OSC_003 ;[ if _DATA1 = _DATA2 then goto Xxx ] movlw 0x04 xorwf SW_CNT,W btfsc STATUS,Z goto OSC_004 ;[ if _DATA1 < _DATA2 then goto Xxx ] movlw 0x03 movwf DATA2 movf SW_CNT,W subwf DATA2,W btfss STATUS,C goto CLR_SW RETFIE ;割り込みを許可してリターン CLR_SW movlw 0x00 movwf SW_CNT RETFIE OSC_001 movlw 0x03 movwf DATA1 INCF CNT5,F ;[ if _DATA1 < _DATA2 then goto Xxx ] movf CNT5,W subwf DATA1,W btfss STATUS,C goto OSC_001_02 RETFIE OSC_001_02 COMF OSC_001_WAVE movlw 0x00 movwf CNT5 RETFIE OSC_002 movlw 0xAA movwf DATA3 INCF CNT6,F ;[ if _DATA1 < _DATA2 then goto Xxx ] movf CNT6,W subwf DATA3,W btfss STATUS,C goto OSC_002_02 RETFIE OSC_002_02 COMF OSC_002_WAVE movlw 0x00 movwf CNT6 RETFIE OSC_003 movlw 0x55 movwf DATA4 INCF CNT7,F ;[ if _DATA1 < _DATA2 then goto Xxx ] movf CNT7,W subwf DATA4,W btfss STATUS,C goto OSC_003_02 RETFIE OSC_003_02 COMF OSC_003_WAVE movlw 0x00 movwf CNT7 RETFIE OSC_004 movlw 0x33 movwf DATA5 INCF CNT8,F ;[ if _DATA1 < _DATA2 then goto Xxx ] movf CNT8,W subwf DATA5,W btfss STATUS,C goto OSC_004_02 RETFIE OSC_004_02 COMF OSC_004_WAVE movlw 0x00 movwf CNT8 RETFIE END