;-----------------------------------------------+ ; TV_IR_RX | ; Copy by Y.Matsui | ; | ; TV_IR_RX.asm | ; 38kHzキャリアのIR受信機 | ; PIC16F84-6.4MHz水晶(MC=625nS) | ; 割込=WDT要、TMR0要、RB0不、RB4〜7不 | ; プリスケTMR01/8 | ; 21マシンサイクル=13.13uSが38.1kHz半サイクル | ; 1bitは38.1kHzを15サイクル=393.8uS | ; 1frameはスタートbit(1)+データ(4)+反転(4) | ; 合計9bit=3544uS | ; | ; 1bitの1/3=>131.3uSがtone3.81kHzの半サイクル | ; 受信ではTMR0=131.3uSに設定しtoneに使うととも | ; にスタートbitは常に監視、データは3回に1度 | ; 読みにいく。 | ; | ; KEYは電源(トグル)、CH_UP、CH_DNの3つ | ; | ; | ; データ電源=H+LLHL+HHLH(02h) | ; データCHUP=H+LHLL+HLHH(04h) | ; データCHDN=H+LHHL+HLLH(06h) | ; | ; Start 2003/5/30 Ver.0.1 | ;-----------------------------------------------+ list p=16F84 ;list directive to define processor #include ;processor specific variable definitions __CONFIG _CP_OFF & _WDT_ON & _PWRTE_ON & _HS_OSC ; read_out_OK、watch_dog_ON、power_up_OK、high_speed_X'tal ; Memory address assignment. ; ROM area assignment ;000H - 3FFH (1k byte) ; 000H ;processor reset vector ; 004H ;interrupt vector location ; RAM area assignment ;00H - 4FH (68 byte) ; 000H - 00BH ;system ; 00CH - 04FH ;useer ; ### ここからレジスタアドレスアサイン ### CT_INT EQU 00CH ;割り込み回数カウンタ(80回周期で繰り返し) KT_ON EQU 00DH ;key_tone enable(000X0000 X=1 でON) STS_reg EQU 00EH ;status'xxxxxx,受信スタートビット,8bit完了 COUNT6 EQU 00FH ;Rx_bit幅&Tx_送信回数 RX_DAT EQU 010H ;buffer for DAT_RX COUNT8 EQU 011H ;TX/RX_bit数のチェック ST_CHK EQU 012H ;detect start bit(xxxxxx11でスタートビットON) ;CHK_DN EQU 013H ;DWN_KEY buffer ;CHK_UP EQU 014H ;UP_KEY buffer ;CHK_PO EQU 015H ;TX_KEY buffer KT_CNT EQU 016H ;key tone counter ; ### ここからラベル定義 ### ; 受信データ S_POW EQU B'00101101' ;電源 CH_UP EQU B'01001011' ;チャンネルアップ CH_DN EQU B'01101001' ;チャンネルダウン ; ### ここからハードピンアサイン ### ; I/O ports assignment. ; PA.4 :no use VDD接続 ; PA.3 :no use VDD接続 ; PA.2 :no use VDD接続 ; PA.1 :no use VDD接続 ; PA.0 input=IR act_Low ; ; PB.7 :no use open ; PB.6 :no use open ; PB.5 :no use open ; PB.4 :SPK tone ; PB.3 :no use ; PB.2 :POW H=ON ; PB.1 :CH L(DN)--L(STOP)--H(UP) ; PB.0 :CH L(DN)--H(STOP)--H(UP) ;******************************************* ORG 000H ;processor reset vector RESET ;******************************************* CALL INIT ;イニシャル処理 ;******************************************* WAIT ;******************************************* ; 何もしない。すべてTMR0割り込みで処理。 GOTO WAIT ;wait interrupt timer ;******************************************* ORG 004H ;interrupt vector MAIN ;******************************************* ; 131.3μSのタイマ割り込みでMAIN ; すべての処理は131.3uS(210マシンサイクル)以内 ; で終了させ、割り込みでのpush/popは行わない。 ; WDTのクリアは131.3μS*80(約10mS) ; に一度行う。 ; ========================================== ; タイマ0の設定(TMR0=231) ; 割り込みフラグのクリア ; 4kHz_tone処理 ; IR受信処理 ; 割り込み回数-1 ; 割り込み残=0なら回数=80(約10mS)&WDTのクリア ; 割り込み残=1なら何もしない。オプション ; 割り込み残=2なら何もしない。オプション ; 割り込み残=3なら受信データ処理 NOP ;TRM0周期微調整 NOP ;TRM0周期微調整 NOP ;TRM0周期微調整 NOP ;TRM0周期微調整 NOP ;TRM0周期微調整 NOP ;TRM0周期微調整 MOVLW D'231' ;(256-218)*8(priscaler)=>304MC MOVWF TMR0 ;send data to TMR0 BCF INTCON,2 ;cleare interrupt ; tone処理(KT_ONは'000X0000 X=1ならPORTB_bit4反転) MOVFW KT_ON ;load key_tone_enable signal XORWF PORTB,F ;PORTA <= W xor PORTA ; IR受信処理 ; 131.3uSで2回連続IR信号ありでstart bit ON、以降は3回に一回 ; PA.0を取り込み。RX_DATに書き込む。 ; start_bit? ------------| ; DEC COUNT6 get PA.3 ; COUNT6=0? --| rotait ST_CHK ; SET COUNT6 | low 2bit=11? --| ; rotait RX_DAT | SET start bit | ; GET PA.3 | SET COUNT6 | ; DEC&8count? --| | | ; CLR start_bit |-------------------- ; SET 8count | ; SAVE RX_DAT | ;==================== BTFSS STS_reg,1 ;skip then start bit OK GOTO NON_STB ;無ければstart bit監視 ; start bit有りのときの処理 DECFSZ COUNT6,F ;-1 & skpi if '0' GOTO END_RX ;not COUNT6 ; COUNT6=0(6回に1回)のときの処理 MOVLW D'006' ;W <= '006' MOVWF COUNT6 ;save data to COUNT6 RLF RX_DAT,F ;C←7←...←0←C BCF RX_DAT,0 ;cleare RX_DAT.0 ; 受信データの取り込み BTFSS PORTA,0 ;PA.3=1 then skip BSF RX_DAT,0 ;RX_DAT.0 <= '1' ; bit数8?のチェック DECFSZ COUNT8,F ;-1 & skpi if '0' GOTO END_RX ;not 8count ; 8bit完了のときの処理 BCF STS_reg,1 ;cleare start bit MOVLW D'008' ;reset COUNT8 MOVWF COUNT8 ;save data to COUNT8 BSF STS_reg,0 ;8bit完了フラグON GOTO END_RX ;受信データ取り込み完了 ;------------------------------------------------- NON_STB ;start bit監視 RLF ST_CHK,F ;C←7←...←0←C BCF ST_CHK,0 ;cleare ST_CHK.0 BTFSS PORTA,0 ;PA.3=1(no sig) then skip BSF ST_CHK,0 ;ST_CHK.0 <= '1' MOVLW B'00001111' ;4回連続 XORWF ST_CHK,W ;ST_CHK xor '1111' BNZ END_RX ;if W=not'0' then END_RX BSF STS_reg,1 ;set Rx request(start bit) MOVLW D'008' ;reset COUNT8 MOVWF COUNT8 ;send data to COUNT8 MOVLW D'006' ;W <= '006' MOVWF COUNT6 ;send data to COUNT6 ;------------------------------------------------- END_RX ;受信処理完了 ; CT_INT=1(80回目)の割り込みのとき(WDT) DECF CT_INT,F ;CT_INT <= CT_INT-1 BTFSC STATUS,Z ;skip then CT_INT=1-1 GOTO CLR_WD ;cleare WDT ; CT_INT=2(79回目)の割り込みのとき DECF CT_INT,F ;CT_INT <= CT_INT-1 BTFSC STATUS,Z ;skip then CT_INT=2-1-1 GOTO OPTION1 ;no use ; CT_INT=3(78回目)の割り込みのとき DECF CT_INT,F ;CT_INT <= CT_INT-1 BTFSC STATUS,Z ;skip then CT_INT=3-1-1-1 GOTO OPTION2 ;no use ; CT_INT=4(77回目)の割り込みのとき DECF CT_INT,F ;CT_INT <= CT_INT-1 BTFSC STATUS,Z ;skip then CT_INT=4-1-1-1-1 GOTO OPTION3 ;no use ; CT_INT=5(76回目)の割り込みのとき(受信処理 DECF CT_INT,F ;CT_INT <= CT_INT-1 BTFSC STATUS,Z ;skip then CT_INT=5-1-1-1-1-1 GOTO RX_ACT ;受信データによるポート処理 MOVFW CT_INT ;4回カウント補正 ADDLW D'004' ;W <= '003' MOVWF CT_INT ;CT_INT <= W+3 END_MAIN RETFIE ;return WAIT ;END of MAIN ;******************************************* INIT ;******************************************* ; ポート方向設定(all RA=>input & all RB=>output) ; ポートBはプルアップ指定、プリスケーラ分周(1/8) ; 割り込み回数の初期化(d080),その他の初期化 ; key tone counter の設定 ; TMR0の設定 ; 割り込み設定(タイマ割り込み有効) BSF STATUS,RP0 ;set page 1 MOVLW B'11111111' ;set PORTA all input MOVWF TRISA ; CLRF TRISB ;PortB set all output MOVLW B'00000010' ;RB_pull_up,int_CLK MOVWF OPTION_REG ;priscaler=timer&1/8 BCF STATUS,RP0 ;set page 0 MOVLW B'00011111' ;W_reg MOVWF PORTA ;send portA MOVLW B'00000001' ;W_reg <= PO_OFF、CH_STOP MOVWF PORTB ;send portB MOVLW D'004' ;load interrupt times MOVWF CT_INT ;set 割り込み残り回数 MOVLW D'006' ;W <= '006' MOVWF COUNT6 ;send data to COUNT6 CLRF RX_DAT ;cleare Rx data CLRF STS_reg ;ステータスクリア MOVLW D'008' ;reset COUNT8 MOVWF COUNT8 ;send data to COUNT8 CLRF ST_CHK ;clear start bit MOVLW D'000' ; MOVWF KT_CNT ;set key tone counter MOVLW D'231' ;(256-218)*8(priscaler)=>304MC MOVWF TMR0 ;send d039 to TMR0 MOVLW B'10100000' ;interrupt enable,timer enable MOVWF INTCON ;send data to INTCON RETURN ;return RESET ;END of INIT ;******************************************* CLR_WD ;******************************************* ; ウォッチドッグのクリア ; 割り込み回数のリセット ; key tone counterからKT_ONを作成。 NOP ;割り込み時2MC命令を避ける調整 CLRWDT ;cleare WDT MOVLW D'080' ;load interrupt times MOVWF CT_INT ;set 割り込み回数カウンタ ; make KT_ON CLRF KT_ON ;set key tone off MOVFW KT_CNT ; BZ END_CW ; DECF KT_CNT,F ;KT_CNT <= KT_CNT-1 MOVLW B'00010000' ; MOVWF KT_ON ;set key tone on ; BSF KT_ONでは? END_CW GOTO END_MAIN ;return ;END of CLR_WD ;******************************************* OPTION1 ;******************************************* ; 何もしない。オプション ; CH_UP、CH_DNをSTOP状態に戻しておく。 INCF CT_INT,F ;1回カウント補正 BSF PORTB,0 ;set RB.0=1 BCF PORTB,1 ;set RB.1=0 GOTO END_MAIN ;return ;END of OPTION1 ;******************************************* OPTION2 ;******************************************* ; 何もしない。オプション INCF CT_INT,F ;2回カウント補正 INCF CT_INT,F ;CT_INT <= CT_INT+1 GOTO END_MAIN ;return ;END of OPTION2 ;******************************************* OPTION3 ;******************************************* ; 何もしない。オプション MOVFW CT_INT ;3回カウント補正 ADDLW D'003' ;W <= '003' MOVWF CT_INT ;CT_INT <= W+3 GOTO END_MAIN ;return ;END of OPTION3 ;******************************************* RX_ACT ;******************************************* ; 受信データによる処理 MOVFW CT_INT ;4回カウント補正 ADDLW D'004' ;W <= '003' MOVWF CT_INT ;CT_INT <= W+3 BTFSS STS_reg,0 ;8bit完了ならスキップ GOTO END_ACT BCF STS_reg,0 ;1ならクリアしておく MOVFW RX_DAT ; XORLW S_POW ;比較(一致なら0) BZ POW_ON ; MOVFW RX_DAT ; XORLW CH_UP ;比較(一致なら0) BZ UP_ON ; MOVFW RX_DAT ; XORLW CH_DN ;比較(一致なら0) BZ DN_ON ; GOTO END_ACT ; ;******************************************* POW_ON CLRF RX_DAT ;一旦、必ずクリアする。 MOVLW B'00001100' ; XORWF PORTB,F ; MOVLW D'008' ;受信トーン MOVWF KT_CNT ;KT_CNT <= W GOTO END_ACT ; ;******************************************* UP_ON CLRF RX_DAT ;一旦、必ずクリアする。 MOVFW PORTB ; XORLW B'00001101' BNZ END_ACT ; BSF PORTB,0 ;set RB.0=1 BSF PORTB,1 ;set RB.1=1 MOVLW D'008' ;受信トーン MOVWF KT_CNT ;KT_CNT <= W GOTO END_ACT ; ;******************************************* DN_ON CLRF RX_DAT ;一旦、必ずクリアする。 MOVFW PORTB ; XORLW B'00001101' BNZ END_ACT ; BCF PORTB,0 ;set RB.0=0 BCF PORTB,1 ;set RB.1=0 MOVLW D'008' ;受信トーン MOVWF KT_CNT ;KT_CNT <= W END_ACT GOTO END_MAIN ;return ;END of RX_ACT ;******************************************* END ;end of all ;*******************************************