;--------------------------------------------------------------- LIST P=16F84 #include __CONFIG _CP_OFF & _HS_OSC & _PWRTE_ON & _WDT_OFF ;--------------------------------------------------------------- ;アドレスに名前を付ける ;--------------------------------------------------------------- ;割り込み時にレジスタを退避させるメモリ w_temp equ 0x0C status_temp equ 0x0D pos1 equ 0x0E pos2 equ 0x0F ;ウェイト用メモリ wait_val1 equ 0x10 wait_val2 equ 0x11 wave1 equ 0x12 wave2 equ 0x13 sound equ 0x14 cycle equ 0x15 soundtime equ 0x16 ;RS232c 送信用メモリ SEND_TMR equ 0x17 SEND_COUNTER equ 0x18 SEND_BUF equ 0x19 counter equ 0x1A ;PIC16F84では0x0Cから0x4Fまでが使用可能 ;*************************************************************** ;リセットベクタ ;*************************************************************** org 0 goto start ;*************************************************************** ;割り込みベクタ ;*************************************************************** org 4 ;レジスタの退避 movwf w_temp movf STATUS,w clrf STATUS movwf status_temp ;各割り込みに対して適切なアドレスにジャンプさせる btfsc INTCON,0 goto int0 btfsc INTCON,1 goto int1 btfsc INTCON,2 goto int2 intret ;レジスタの復帰 clrf STATUS movf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;割り込みから復帰 ;--------------------------------------------------------------- ;RB0/INT割り込みにより実行 ;--------------------------------------------------------------- int0 ;RB4~RB7割り込み ;割り込み時の処理をここに記述 bcf INTCON,0 ;RB4~RB7割り込みフラグリセット goto intret ;--------------------------------------------------------------- ;RB4〜RB7割り込みにより実行 ;--------------------------------------------------------------- int1 ;RB0/INT割り込み ;割り込み時の処理をここに記述 bcf INTCON,1 ;RB0/INT割り込みフラグリセット goto intret ;--------------------------------------------------------------- ;タイマー割り込みにより実行 ;--------------------------------------------------------------- int2 ;タイマー割り込み ;タイマーにはクロックが1/4周期で供給されるため、 ;10MHzクロックでは 1/2500000secとなる ;1/19200 sec(52 usec)毎にタイマー割り込みを入れるために ;減算タイマー値に256-130=0x7Eを設定 ;しかし、割り込みから、ここまでに0x0Eほどかかるため加算する movlw 0x7E+0x0E ;タイマー値リセット movwf TMR0 ;割り込み時の処理をここに記述 ;**************************************************************************** ;RS232c送信処理 400bps 奇数パリティ ;**************************************************************************** SEND_START TSTF SEND_BUF ;SEND_BUFがゼロかテストする BZ SEND_END ;ゼロのときジャンプ ;1/19200を32分周して1/600を作り出す decfsz SEND_TMR,F ;Fレジスタを‐1して0ならスキップ goto SEND_END ;ジャンプ MOVLW 0x1F ;Wレジスタに値を代入 MOVWF SEND_TMR ;WレジスタからFレジスタに代入 ;送信カウンタのセット TSTF SEND_COUNTER ;SEND_COUNTERがゼロかテストする BNZ SEND_COUNTER_SET_END ;ゼロ以外のときジャンプ SEND_COUNTER_SET MOVLW 0x16+1 ;Wレジスタに値を代入 MOVWF SEND_COUNTER ;WレジスタからFレジスタに代入 SEND_COUNTER_SET_END DECF SEND_COUNTER ;Fレジスタを-1する ;----------------------------------------------------------------------- ;スタートビットを立てる ;----------------------------------------------------------------------- SEND_START_BIT MOVFW SEND_COUNTER ;WレジスタにFレジスタを代 SUBLW 0x14 ;Wレジスタから値を引く BNZ SEND_0_BIT ;結果が0以外ならジャンプ BCF PORTA,1 ;指定ビットに0を立てる ;----------------------------------------------------------------------- ;0ビット目の送信 ;----------------------------------------------------------------------- SEND_0_BIT MOVFW SEND_COUNTER ;WレジスタにFレジスタを代 SUBLW 0x12 ;Wレジスタから値を引く BNZ SEND_0_BIT_END ;結果が0以外ならジャンプ BTFSS SEND_BUF,0 ;指定ビットがゼロ以外ならスキップ goto SEND_0_OFF ;ジャンプ SEND_0_ON BSF PORTA,1 ;指定ビットに1を立てる goto SEND_0_BIT_END SEND_0_OFF BCF PORTA,1 ;指定ビットに0を立てる SEND_0_BIT_END ;----------------------------------------------------------------------- ;1ビット目の送信 ;----------------------------------------------------------------------- SEND_1_BIT MOVFW SEND_COUNTER ;WレジスタにFレジスタを代 SUBLW 0x10 ;Wレジスタから値を引く BNZ SEND_1_BIT_END ;結果が0以外ならジャンプ BTFSS SEND_BUF,1 ;指定ビットがゼロ以外ならスキップ goto SEND_1_OFF ;ジャンプ SEND_1_ON BSF PORTA,1 ;指定ビットに1を立てる goto SEND_1_BIT_END SEND_1_OFF BCF PORTA,1 ;指定ビットに0を立てる SEND_1_BIT_END ;----------------------------------------------------------------------- ;2ビット目の送信 ;----------------------------------------------------------------------- SEND_2_BIT MOVFW SEND_COUNTER ;WレジスタにFレジスタを代 SUBLW 0x0E ;Wレジスタから値を引く BNZ SEND_2_BIT_END ;結果が0以外ならジャンプ BTFSS SEND_BUF,2 ;指定ビットがゼロ以外ならスキップ goto SEND_2_OFF ;ジャンプ SEND_2_ON BSF PORTA,1 ;指定ビットに1を立てる goto SEND_2_BIT_END SEND_2_OFF BCF PORTA,1 ;指定ビットに0を立てる SEND_2_BIT_END ;----------------------------------------------------------------------- ;3ビット目の送信 ;----------------------------------------------------------------------- SEND_3_BIT MOVFW SEND_COUNTER ;WレジスタにFレジスタを代 SUBLW 0x0C ;Wレジスタから値を引く BNZ SEND_3_BIT_END ;結果が0以外ならジャンプ BTFSS SEND_BUF,3 ;指定ビットがゼロ以外ならスキップ goto SEND_3_OFF ;ジャンプ SEND_3_ON BSF PORTA,1 ;指定ビットに1を立てる goto SEND_3_BIT_END SEND_3_OFF BCF PORTA,1 ;指定ビットに0を立てる SEND_3_BIT_END ;----------------------------------------------------------------------- ;4ビット目の送信 ;----------------------------------------------------------------------- SEND_4_BIT MOVFW SEND_COUNTER ;WレジスタにFレジスタを代 SUBLW 0x0A ;Wレジスタから値を引く BNZ SEND_4_BIT_END ;結果が0以外ならジャンプ BTFSS SEND_BUF,4 ;指定ビットがゼロ以外ならスキップ goto SEND_4_OFF ;ジャンプ SEND_4_ON BSF PORTA,1 ;指定ビットに1を立てる goto SEND_4_BIT_END SEND_4_OFF BCF PORTA,1 ;指定ビットに0を立てる SEND_4_BIT_END ;----------------------------------------------------------------------- ;5ビット目の送信 ;----------------------------------------------------------------------- SEND_5_BIT MOVFW SEND_COUNTER ;WレジスタにFレジスタを代 SUBLW 0x08 ;Wレジスタから値を引く BNZ SEND_5_BIT_END ;結果が0以外ならジャンプ BTFSS SEND_BUF,5 ;指定ビットがゼロ以外ならスキップ goto SEND_5_OFF ;ジャンプ SEND_5_ON BSF PORTA,1 ;指定ビットに1を立てる goto SEND_5_BIT_END SEND_5_OFF BCF PORTA,1 ;指定ビットに0を立てる SEND_5_BIT_END ;----------------------------------------------------------------------- ;6ビット目の送信 ;----------------------------------------------------------------------- SEND_6_BIT MOVFW SEND_COUNTER ;WレジスタにFレジスタを代 SUBLW 0x06 ;Wレジスタから値を引く BNZ SEND_6_BIT_END ;結果が0以外ならジャンプ BTFSS SEND_BUF,6 ;指定ビットがゼロ以外ならスキップ goto SEND_6_OFF ;ジャンプ SEND_6_ON BSF PORTA,1 ;指定ビットに1を立てる goto SEND_6_BIT_END SEND_6_OFF BCF PORTA,1 ;指定ビットに0を立てる SEND_6_BIT_END ;----------------------------------------------------------------------- ;7ビット目の送信 ;----------------------------------------------------------------------- SEND_7_BIT MOVFW SEND_COUNTER ;WレジスタにFレジスタを代 SUBLW 0x04 ;Wレジスタから値を引く BNZ SEND_7_BIT_END ;結果が0以外ならジャンプ BTFSS SEND_BUF,7 ;指定ビットがゼロ以外ならスキップ goto SEND_7_OFF ;ジャンプ SEND_7_ON BSF PORTA,1 ;指定ビットに1を立てる goto SEND_7_BIT_END SEND_7_OFF BCF PORTA,1 ;指定ビットに0を立てる SEND_7_BIT_END ;----------------------------------------------------------------------- ;パリティビットの送信 ;----------------------------------------------------------------------- SEND_PARITY_BIT MOVFW SEND_COUNTER ;WレジスタにFレジスタを代 SUBLW 0x02 ;Wレジスタから値を引く BNZ SEND_PARITY_BIT_END ;結果が0以外ならジャンプ ;奇数パリティを計算する MOVLW 0x00 MOVWF pos1 BTFSC SEND_BUF,0 ;指定ビットがゼロだったら次命令スキップ INCF pos1,F BTFSC SEND_BUF,1 ;指定ビットがゼロだったら次命令スキップ INCF pos1,F BTFSC SEND_BUF,2 ;指定ビットがゼロだったら次命令スキップ INCF pos1,F BTFSC SEND_BUF,3 ;指定ビットがゼロだったら次命令スキップ INCF pos1,F BTFSC SEND_BUF,4 ;指定ビットがゼロだったら次命令スキップ INCF pos1,F BTFSC SEND_BUF,5 ;指定ビットがゼロだったら次命令スキップ INCF pos1,F BTFSC SEND_BUF,6 ;指定ビットがゼロだったら次命令スキップ INCF pos1,F BTFSC SEND_BUF,7 ;指定ビットがゼロだったら次命令スキップ INCF pos1,F BTFSC pos1,0 ;指定ビットがゼロだったら次命令スキップ goto SEND_8_OFF SEND_8_ON BSF PORTA,1 ;指定ビットに1を立てる goto SEND_PARITY_BIT_END SEND_8_OFF BCF PORTA,1 ;指定ビットに0を立てる SEND_PARITY_BIT_END ;----------------------------------------------------------------------- ;送信完了のため、送信バッファのクリア ストップビットの送信 ;----------------------------------------------------------------------- SEND_BUF_CLEAR TSTF SEND_COUNTER ;SEND_COUNTERがゼロかテストする BNZ SEND_END ;ゼロ以外のときジャンプ BSF PORTA,1 ;ストップビットの送信 ;送信バッファをクリアする MOVLW 0x00 ;Wレジスタに値を代入 MOVWF SEND_BUF ;WレジスタからFレジスタに代入 SEND_END ;---------------------------------------------------------------------------- bcf INTCON,2 ;タイマー割り込みフラグリセット goto intret ;ジャンプ ;*************************************************************** ;スタート ;*************************************************************** start MOVLW 0x00 MOVWF SEND_TMR MOVWF SEND_COUNTER MOVWF SEND_BUF MOVWF counter ;FレジスタにWレジスタを代入 ;--------------------------------------------------------------- ;ポートの設定 ;--------------------------------------------------------------- clrf PORTA clrf PORTB bsf STATUS,5 ;ページを1に切り替え movlw b'00000001 movwf TRISA ;portAをbit 00000001 を入力に設定 movlw b'00000001 movwf TRISB ;portBを11111110 を出力に設定 bcf STATUS,5 ;ページを0に切り替え ;--------------------------------------------------------------- ;RB0/INT割り込みの設定 ;--------------------------------------------------------------- bsf STATUS,5 ;ページを1に切り替え bcf OPTION_REG,6 ;RB0のエッジ設定は立ち上がり bcf STATUS,5 ;ページを0に切り替え bsf INTCON,4 ;RB0/INT割り込み発生許可 ;--------------------------------------------------------------- ;RB4〜RB7割り込みの設定 ;--------------------------------------------------------------- ; bsf INTCON,3 ;RB4〜RB7割り込み発生許可 ;--------------------------------------------------------------- ;タイマー割り込みの設定 ;--------------------------------------------------------------- movlw 0x00 ;タイマー値リセット movwf TMR0 bsf STATUS,5 ;ページを1に切り替え bsf OPTION_REG,0 ;PS0 プリスケーラの設定 bsf OPTION_REG,1 ;PS1 bsf OPTION_REG,2 ;PS2 bsf OPTION_REG,3 ;PSA プリスケーラをTMRで使用する場合は0,WDTで使用する場合は1 bcf OPTION_REG,5 ;T0CS タイマ0の入力先 1でRA4ピン入力,0でクロック1/4入力 bcf STATUS,5 ;ページを0に切り替え bsf INTCON,5 ;タイマ割り込み発生許可 ;--------------------------------------------------------------- ;割り込みの開始 ;--------------------------------------------------------------- ; bsf INTCON,7 ;割り込み許可 ;*************************************************************** ;メイン ;*************************************************************** init BSF PORTA,1 ;指定ビットに1を立てる main BCF PORTB,1 ;MAX232の電源OFF ; CLRWDT ;ウォッチドックタイマとプリスケーラをクリア bcf INTCON,0 ;各種割り込みフラグクリア bcf INTCON,1 bcf INTCON,2 bcf INTCON,7 ;割り込み発生停止 SLEEP NOP BSF PORTB,1 ;MAX232の電源ON MOVLW 0x00 call wait_loop inc_ INCF counter,F BZ inc_ MOVFW counter MOVWF SEND_BUF ;FレジスタにWレジスタを代入 bsf INTCON,7 ;割り込み発生許可 ;------------------------------------- ;送信中の場合は待機するループ ;------------------------------------- SEND_WAIT TSTF SEND_BUF ;SEND_BUFがゼロかテストする BNZ SEND_WAIT ;ゼロ以外のときジャンプ SEND_WAIT_END ;------------------------------------- bcf INTCON,7 ;割り込み発生停止 MOVLW 0x00 call wait_loop BCF PORTB,1 ;MAX232の電源OFF ;********************************************* MOVLW 0xFF MOVWF cycle MOVLW b'000000010 MOVWF sound MOVLW 0x0F MOVWF soundtime call beep ;******************************************* MOVLW 0x0F MOVWF soundtime MOVLW 0x08 MOVWF cycle MOVLW b'000011110 MOVWF sound call beep ;-------------------------------------------- MOVLW b'000011010 MOVWF sound call beep ;-------------------------------------------- MOVLW b'000010110 MOVWF sound call beep ;-------------------------------------------- MOVLW b'000001110 MOVWF sound call beep ;-------------------------------------------- MOVLW b'000001010 MOVWF sound call beep ;-------------------------------------------- MOVLW b'000000110 MOVWF sound call beep ;-------------------------------------------- MOVLW b'000000110 MOVWF sound call beep ;********************************************* MOVLW 0x0F MOVWF cycle MOVLW b'000000010 MOVWF sound MOVLW 0x02 MOVWF soundtime call beep ;********************************************* MOVLW 0x0F MOVWF soundtime MOVLW 0x08 MOVWF cycle MOVLW b'00011110 MOVWF sound call beep ;-------------------------------------------- MOVLW b'00011010 MOVWF sound call beep ;-------------------------------------------- MOVLW b'00010110 MOVWF sound call beep ;-------------------------------------------- MOVLW b'00010010 MOVWF sound call beep ;-------------------------------------------- MOVLW b'00001110 MOVWF sound call beep ;-------------------------------------------- MOVLW b'00001010 MOVWF sound call beep ;-------------------------------------------- MOVLW b'00000110 MOVWF sound call beep ;********************************************* MOVLW 0x00 call wait_loop ;********************************************* MOVLW 0xFF MOVWF cycle MOVLW b'000000010 MOVWF sound MOVLW 0x0F MOVWF soundtime call beep ;******************************************* MOVLW 0x0F MOVWF soundtime MOVLW 0x08 MOVWF cycle MOVLW b'000011110 MOVWF sound call beep ;-------------------------------------------- MOVLW b'000011010 MOVWF sound call beep ;-------------------------------------------- MOVLW b'000010110 MOVWF sound call beep ;-------------------------------------------- MOVLW b'000001110 MOVWF sound call beep ;-------------------------------------------- MOVLW b'000001010 MOVWF sound call beep ;-------------------------------------------- MOVLW b'000000110 MOVWF sound call beep ;-------------------------------------------- MOVLW b'000000110 MOVWF sound call beep ;********************************************* MOVLW 0x0F MOVWF cycle MOVLW b'000000010 MOVWF sound MOVLW 0x02 MOVWF soundtime call beep ;********************************************* MOVLW 0x0F MOVWF soundtime MOVLW 0x08 MOVWF cycle MOVLW b'00011110 MOVWF sound call beep ;-------------------------------------------- MOVLW b'00011010 MOVWF sound call beep ;-------------------------------------------- MOVLW b'00010110 MOVWF sound call beep ;-------------------------------------------- MOVLW b'00010010 MOVWF sound call beep ;-------------------------------------------- MOVLW b'00001110 MOVWF sound call beep ;-------------------------------------------- MOVLW b'00001010 MOVWF sound call beep ;-------------------------------------------- MOVLW b'00000110 MOVWF sound call beep ;********************************************* ;不感時間のウエイトとして使用 MOVLW 0x00 MOVWF pos1 test MOVLW 0x00 call wait_loop decfsz pos1,F goto test goto main ;--------------------------------------------------------------- ;beep ;--------------------------------------------------------------- beep MOVFW soundtime MOVWF pos1 _beep goto pu _beep2 decfsz pos1,F goto _beep return pu MOVLW b'00000011 MOVWF PORTA ;WレジスタからFレジスタに代入 MOVFW cycle call wait_loop ; MOVLW 0x00 ;Wレジスタに値を代入 MOVFW sound ;FレジスタからWレジスタに代入 MOVWF PORTA ;WレジスタからFレジスタに代入 MOVFW cycle call wait_loop goto _beep2 ;--------------------------------------------------------------- ;ウエイト ;--------------------------------------------------------------- wait_loop ; MOVLW 0x00 MOVWF wait_val1 wait_loop1 MOVLW 0x1F MOVWF wait_val2 wait_loop2 NOP decfsz wait_val2,F goto wait_loop2 decfsz wait_val1,F goto wait_loop1 return END