;#define debug ; 国民機起動音発生装置 PiPo Ver.4.0 ; 製作 : 爆竹銃 ; Web : http://baku.homeunix.net ; e-mail : bakuchikujuuあっとniftyどっとこむ ; 最終更新 : 2006/07/31 ; いろんなサンプルをパッチワークで繋ぎつつうりうり改造 ; Ver.3まではループでタイミングを合わせていたが、 ; 色々面倒が多いので割り込み利用に(ほぼ)作り直し。 list P=PIC12F675 include "P12F675.INC" __CONFIG _CPD_OFF & _CP_OFF & _BODEN_ON & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT #define PI_TMR1L 0x12 ; (65536-250+12) #define PI_TMR1H 0xff #define PO_TMR1L 0x18 #define PO_TMR1H 0xfe #define WAIT10ms_TMR1L 0xfc ;10ms周期割り込み用 #define WAIT10ms_TMR1H 0xd8 ;(65536-10000+12) #define MODE_BEEP 0 ; beep音発生 mode=&b0000 0001 #define MODE_WAIT 1 ; beep equ 5 ; GPIO5 BEEP出力 input equ 4 ; GPIO4 スルーBEEP入力 reset equ 2 ; GPIO2 テスト再生 w_save equ 0x20 ; W待避用 status_save equ 0x21 ; STATUS待避用 counter4wait equ 0x28 ;ループでのWAIT用 mode equ 0x30 ; 「状態」 beep_state equ 0x31 ;BEEPはH?L? beep_counter_h equ 0x32 ;波数カウント用 beep_counter_l equ 0x33 ; beep_counter_h_ad equ 0x34 ;波数カウント用 A/D変換結果 beep_counter_l_ad equ 0x35 ; wait_counter_h equ 0x32 ;無音時間待ちカウント用 wait_counter_l equ 0x33 ; adcon_channel equ 0x3a ;A/Dチャンネル指定 adcon_h equ 0x3b ;A/D結果 adcon_l equ 0x3c ; set_TMR1L equ 0x40 ; 割り込み時に再セットするTMR1の値 set_TMR1H equ 0x41 ;いちいちmovlw, movwfとかは面倒だよな movlf MACRO literal, filereg movlw literal movwf filereg ENDM ;使用例 ; movlf 0x01, mode movff MACRO filereg_src, filereg_dist movf filereg_src, W movwf filereg_dist ENDM ; bank0 MACRO bcf STATUS, RP0 ENDM bank1 MACRO bsf STATUS, RP0 ENDM ;16bit decfscもどき(0ではなく、-1でループ(等)脱出) ; ■使用例: ; movlf 0x04, h ; movlf 0x00, l ; loop ; call hoge ; decfscw h,l ; goto loop ; ; DECrement F, Skip if Carry (Word) decfscw MACRO h, l movlw 0x01 subwf l, f btfss STATUS, C subwf h, f btfss STATUS, C ENDM ; ■使用例: ; decfsncw h,l ; clrf flag ; DECrement F, Skip if NonCarry (Word) decfsncw MACRO h, l movlw 0x01 subwf l, f btfss STATUS, C subwf h, f btfss STATUS, C ENDM ;割り込み時レジスタ待避 save_reg MACRO ;W,STATUSレジスタ退避 movwf w_save swapf STATUS, W bcf STATUS, RP0 ;割り込み前にバンク切り替えしてるかも movwf status_save ENDM load_reg MACRO ;W,STATUSレジスタ復帰 swapf status_save, W movwf STATUS swapf w_save, f swapf w_save, W ENDM ; ============================================== org 0 goto initialize org 4 goto interrupt ; //////////////////////////////////////////////////////////////// initialize clrf GPIO clrwdt ;割り込み関連初期化 ; BANK 1 -------------------------------- bank1 call 0x03ff ;OSCCAL Valueの読み込み movwf OSCCAL ;読み込んだ校正値をOSCCALレジスタにセット movlf b'00000001', PIE1 ;TMR1割り込み Enable movlf b'00011111', TRISIO ;GPIO[0:4]=input, GPIO5=output movlf b'00010100', WPU ;WeekPullup movlf b'00000000', OPTION_REG ;bit7 /GPPU 0 Weak pull-ups on GPIO movlf b'00010011', ANSEL ;GPIO 0,1をアナログ入力 ; BANK 0 -------------------------------- bank0 movlf b'00000001', T1CON ;TMR1 1:1 movlf b'01000000', INTCON ; Peripheral Interrupt Enable movlf b'000000111', CMCON ;コンパレータ無効 ; ---------------------------------------------------------------- pipo movlf 0x00, wait_counter_h movlf d'20', wait_counter_l call wait_by_timer movlf 0x00, beep_state ; beep初期値 clrf mode bsf mode, MODE_BEEP ; ピポ音長さ読み込み movlf 0, adcon_channel call adcon10bit movff adcon_h, beep_counter_h_ad movff adcon_l, beep_counter_l_ad movff beep_counter_h_ad, beep_counter_h movff beep_counter_l_ad, beep_counter_l pi ; *"Pi" ------------------------------------------------ movlf PI_TMR1H, set_TMR1H movlf PI_TMR1L, set_TMR1L movff set_TMR1L, TMR1L movff set_TMR1H, TMR1H bcf PIR1,TMR1IF bsf INTCON, GIE pi_loop btfss mode, MODE_BEEP goto po goto pi_loop ; *"Po" ------------------------------------------------ po clrf mode bsf mode, MODE_BEEP movff beep_counter_h_ad, beep_counter_h movff beep_counter_l_ad, beep_counter_l bcf STATUS, C rrf beep_counter_h, f ; カウント数半減 rrf beep_counter_l, f ;タイマーセット movlf PO_TMR1H, set_TMR1H movlf PO_TMR1L, set_TMR1L movff set_TMR1L, TMR1L movff set_TMR1H, TMR1H bcf PIR1,TMR1IF bsf INTCON, GIE po_loop btfss mode, MODE_BEEP goto po_end goto po_loop po_end bcf INTCON, GIE ; ブツ音を防ぐ btfss GPIO, input bsf GPIO, beep btfsc GPIO, input bcf GPIO, beep ;発振後無音時間 call silent_wait bcf INTCON, GIE ;割り込み禁止 ;BEEPスルー状態へ移行 goto eloop ;end of main //////////////////////////////////////////////// ;発振後無音時間 ---------------------------------------- silent_wait movlf 1, adcon_channel call adcon10bit movff adcon_h, wait_counter_h movff adcon_l, wait_counter_l wait_by_timer clrf mode bsf mode, MODE_WAIT movlf WAIT10ms_TMR1H, set_TMR1H movlf WAIT10ms_TMR1L, set_TMR1L movff set_TMR1L, TMR1L movff set_TMR1H, TMR1H bcf PIR1,TMR1IF bsf INTCON, GIE btfss mode, MODE_WAIT goto $+2 goto $-2 return ;end of silent_wait -------------------------------- ;*A/D変換10bit精度 ------------------------------------------------ ; adcon_channelにポート番号を入れてcall ; adcon_h, adcon_lに結果が入る ; ■使用例: ; movlf adcon_channel, 0 ; call adcon10bit adcon10bit bcf STATUS, C rlf adcon_channel, f rlf adcon_channel, W iorlw b'10000001' ; 右詰, A/D_ON movwf ADCON0 movlf 3, counter4wait ;wait 20us call wait bsf ADCON0, GO btfsc ADCON0, GO_DONE goto $-1 movff ADRESH, adcon_h bank1 movf ADRESL, W bank0 movwf adcon_l #ifdef debug movlf 0x10, adcon_l movlf 0x00, adcon_h #endif return ; end of adcon10bit ------------------------------------------------ ; *WAIT -------------------------------------------------------- ; (counter4wait-1)*5 + 8 サイクル時間待ち ; movlw, movwfを入れれば、(X-1)*5+10 ; ■使用例: ; movlf d'10', counter4wait ; call wait wait ;2 (call) goto $+1 ;2 ;2 decfsz counter4wait, f ;1 ;2(脱出時) goto wait ;2 return ;2 ; end of wait ------------------------------------------------ ; *割り込み部分(主処理?)-------------------------------- interrupt save_reg ; 割り込み発生からここまで12サイクル movf set_TMR1L, W ;タイマー再セット movwf TMR1L movf set_TMR1H, W movwf TMR1H bcf PIR1, TMR1IF btfsc mode, MODE_BEEP ; ここで、割り込み発生から 18サイクル goto intsub_beep btfsc mode, MODE_WAIT goto intsub_wait ; BEEP! ------------------------------------------------ intsub_beep ;割り込み発生から20サイクル経過 ; BEEP出力操作 movlw 0x01 ;1 xorwf beep_state, f ;1 btfsc beep_state, 0 ;1 ;2 goto set_BEEP_H ;2 goto set_BEEP_L ;2 set_BEEP_H nop ;1 bsf GPIO, beep ;1 goto end_set_BEEP ;2 set_BEEP_L bcf GPIO, beep ;1 goto end_set_BEEP ;2 end_set_BEEP ;計17サイクル nop ;波数カウント decfsncw beep_counter_h, beep_counter_l ;5 clrf mode ;1 減算でキャリー有りなら、「状態」変更 ;計6サイクル load_reg ;4 retfie ;計6サイクル@復帰処理 ; intsub_wait ;カウントダウン movlw 0x01 ;1 subwf wait_counter_l, f ;1 btfss STATUS, C ;1 ;2 subwf wait_counter_h, f ;1 btfss STATUS, C ;1 ;2 clrf mode ;1 減算でキャリー有りなら、「状態」変更 ;計6サイクル load_reg retfie ;計6サイクル@復帰処理 ; end of interrupt ------------------------------------------------ ; BEEPスルーループ ------------------------------------------------- eloop btfss GPIO, input bsf GPIO, beep btfsc GPIO, input bcf GPIO, beep btfss GPIO, input bsf GPIO, beep btfsc GPIO, input bcf GPIO, beep btfss GPIO, input bsf GPIO, beep btfsc GPIO, input bcf GPIO, beep btfss GPIO, input bsf GPIO, beep btfsc GPIO, input bcf GPIO, beep btfss GPIO, input bsf GPIO, beep btfsc GPIO, input bcf GPIO, beep btfss GPIO, input bsf GPIO, beep btfsc GPIO, input bcf GPIO, beep btfss GPIO, input bsf GPIO, beep btfsc GPIO, input bcf GPIO, beep btfss GPIO, input bsf GPIO, beep btfsc GPIO, input bcf GPIO, beep btfss GPIO, input bsf GPIO, beep btfsc GPIO, input bcf GPIO, beep btfss GPIO, input bsf GPIO, beep btfsc GPIO, input bcf GPIO, beep btfss GPIO, input bsf GPIO, beep btfsc GPIO, input bcf GPIO, beep btfss GPIO, input bsf GPIO, beep btfsc GPIO, input bcf GPIO, beep btfss GPIO, input bsf GPIO, beep btfsc GPIO, input bcf GPIO, beep btfss GPIO, input bsf GPIO, beep btfsc GPIO, input bcf GPIO, beep btfss GPIO, input bsf GPIO, beep btfsc GPIO, input bcf GPIO, beep btfss GPIO, input bsf GPIO, beep btfsc GPIO, input bcf GPIO, beep btfsc GPIO, reset ; 再起動でループ脱出 goto eloop goto pipo end