;--------------------------------------------------------------------- ; スキャナ(暗くなると10個のLEDをフラッシュ) ; ; 2008.9.21 T.Nakamura ; (1). 出力ポート ; GP0-2,5: LEDに繋ぐ ; (2). 入力ポート ; GP3: タクトSW ; GP4/AN3: 明るさセンス(CDS電圧をAD変換) ;--------------------------------------------------------------------- LIST P=PIC12F675 INCLUDE "P12F675.INC" __CONFIG _CPD_OFF & _CP_OFF & _BODEN_ON & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT ERRORLEVEL -302 ;アセンブル時のバンク警告メッセージ抑制 ;--------------------------------------------------------------------- ; マクロ定義 ;--------------------------------------------------------------------- BANK0 MACRO BCF STATUS,RP0 ;BANK0に切り替える ENDM BANK1 MACRO BSF STATUS,RP0 ;BANK1に切り替える ENDM ;--------------------------------------------------------------------- ; 変数レジスタの定義 ;--------------------------------------------------------------------- CNT EQU 20H ; カウンタ CNT1 EQU 21H ; WAIT用カウンタ CNT2 EQU 22H ; WAIT用カウンタ LED_NO EQU 23H ; 点灯するLED番号(0〜9) LEDBUF EQU 24H ; LED表示バッファ(24-25H, 25Hは下位2ビットのみ使用) LEDCNT EQU 26H ; 割り込みで表示するLED番号カウンタ PATADDR EQU 27H ; 表示パターンのアドレスカウンタ PATCNT EQU 28H ; 表示パターンの表示繰り返しカウンタ CNTL EQU 29H ; バイナリカウンタ(下位) CNTH EQU 2AH ; バイナリカウンタ(上位) ADDATH EQU 2BH ; A/D変換の測定結果(上位) THREDAT EQU 2CH ; 点灯の閾値(上位) EE_ADDR EQU 2DH ; EEPROMアドレス EE_DATA EQU 2EH ; EEPROMデータ ; BKUPW EQU 30H ; 割り込み待避用 BKUPS EQU 31H ; 割り込み待避用 BKUPFR EQU 32H ; 割り込み待避用 BKUPPCL EQU 33H ; 割り込み待避用 ; ;--------------------------------------------------------------------- ; EEPROMデータ ;--------------------------------------------------------------------- ORG H'2100' DE H'00' ;--------------------------------------------------------------------- ; リセット・割り込み ;--------------------------------------------------------------------- ORG 00H ; リセット時の飛び込み先 RESET GOTO START ; 初期設定へ ; ;--------------------------------------------------------------------- ; 割り込み処理でダイナミック表示を行う。 ; LEDBUFの0ビット目から順次表示(1回の割り込みで1ビット分) ;--------------------------------------------------------------------- ORG 04H ; 割り込み時の飛び込み先 INTRUPT ;レジスタ待避 MOVWF BKUPW ;バックアップ(Wレジ) SWAPF STATUS,W ;バックアップ(STATUSレジ) MOVWF BKUPS MOVF FSR,W ;バックアップ(FSRレジ) MOVWF BKUPFR MOVF PCLATH,W ;バックアップ(PCLATHレジ) MOVWF BKUPPCL ; BCF INTCON,T0IF ;割り込みフラグリセット ; ; LEDBUFのLEDCNTビット目を調べ、点灯するか判断 ; MOVLW LEDBUF ; LEDBUFアドレス MOVWF FSR BTFSC LEDCNT,3 ; LEDCNT>8以上ならFSR+1 INCF FSR,F ; FSR+1 ; MOVF LEDCNT,W ANDLW H'07' ; 下位ビット取り出し CALL DECBIT ; ビット位置に変換 ANDWF INDF,W BTFSC STATUS,Z ; 0以外なら表示 GOTO UNDISP ; MOVF LEDCNT,W MOVWF LED_NO ; 表示番号をLED_NOへ ; ; LED表示 ; CLRF GPIO MOVF LED_NO,W CALL TABLE_TRIS BSF STATUS,RP0 ; bank1 切り替え MOVWF TRISIO BCF STATUS,RP0 ; bank0に戻す MOVF LED_NO,W CALL TABLE_IO MOVWF GPIO ; GOTO NEXTBIT ; UNDISP CLRF GPIO ; LED非表示 ; NEXTBIT INCF LEDCNT,F ; 次の割り込みに備え、カウントアップ MOVF LEDCNT,W SUBLW D'10' BTFSC STATUS,Z CLRF LEDCNT ; RSTREG ;レジスタ復元 MOVF BKUPPCL,W ;復元(PCLATHレジ) MOVWF PCLATH MOVF BKUPFR,W ;復元(FSRレジ) MOVWF FSR SWAPF BKUPS,W ;復元(STATUSレジ) MOVWF STATUS SWAPF BKUPW,F ;復元(Wレジ)LED_NO SWAPF BKUPW,W ; RETFIE ;割り込みから復帰 ; ;--------------------------------------------------------------------- ; 初期設定 ;--------------------------------------------------------------------- START BCF INTCON,GIE ; 全割込み禁止 BANK1 CALL 3FFH ; 内部OSCのキャリブレーションデータ MOVWF OSCCAL ; OSCCALレジスタにセット MOVLW B'00111000' ; 内部osc(ADCS2-0:011), MOVWF ANSEL ; AN3をアナログ,GP0-2をデジタルI/O MOVLW H'6F' MOVWF TRISIO ; ポートを入力設定 ;割り込みタイマーセット MOVLW H'80' ; プリスケーラを1:2にする MOVWF OPTION_REG ; 約2Kヘルツで割り込みが入るはず ; clock4MHz -> 1Mcycle ; 1Mcycle/256/2=1,953Hz(=512sec毎) ; LED 10個なので195Hz毎に全てを表示する。 BANK0 ; MOVLW B'00001100' ; ADFM:left/0, VCFG:VDD/0, CHS:ch3/11 MOVWF ADCON0 ; MOVLW B'00000111' ; GP0-2をデジタルI/Oに設定 MOVWF CMCON ; デフォルトはコンパレータ ; CLRF LEDCNT ; LEDカウンタクリア CLRF LEDBUF ; LEDバッファクリア CLRF LEDBUF+1 ; LEDバッファクリア MOVLW H'00' MOVWF EE_ADDR CALL REDEEP ; 閾値読み出し MOVWF THREDAT ; ;--------------------------------------------------------------------- ; メイン ;--------------------------------------------------------------------- MAIN BSF INTCON,T0IE ; タイマー0割り込みイネーブル BSF INTCON,GIE ; 割り込み許可 ; CALL PAT1 ; 電源投入の動作確認のために表示 MAINLP BTFSS GPIO,3 ; タクトスイッチ確認 CALL SETTHRE ; 押されていたら閾値設定 ; CALL CHKCDS ; 明るさ測定 CALL CMPTHRE ; 閾値と比較 BTFSC STATUS,C CALL PAT1 ; スキャンパターン表示 GOTO MAINLP ; ;--------------------------------------------------------------------- ; I/Oパターン ;--------------------------------------------------------------------- TABLE_IO CLRF PCLATH ADDWF PCL,F RETLW B'00000001' ; LED 0 RETLW B'00000010' ; LED 1 RETLW B'00000010' ; LED 2 RETLW B'00000100' ; LED 3 RETLW B'00000100' ; LED 4 RETLW B'00100000' ; LED 5 RETLW B'00000001' ; LED 6 RETLW B'00000100' ; LED 7 RETLW B'00000001' ; LED 8 RETLW B'00100000' ; LED 9 ; TABLE_TRIS CLRF PCLATH ADDWF PCL,F RETLW B'00111100' ; LED 0 RETLW B'00111100' ; LED 1 RETLW B'00111001' ; LED 2 RETLW B'00111001' ; LED 3 RETLW B'00011011' ; LED 4 RETLW B'00011011' ; LED 5 RETLW B'00111010' ; LED 6 RETLW B'00111010' ; LED 7 RETLW B'00011110' ; LED 8 RETLW B'00011110' ; LED 9 ; ;--------------------------------------------------------------------- ; Wレジ値をビット位置にデコード ;--------------------------------------------------------------------- DECBIT CLRF PCLATH ADDWF PCL,F DECBIT1 RETLW B'00000001' ;0 RETLW B'00000010' ;1 RETLW B'00000100' ;2 RETLW B'00001000' ;3 RETLW B'00010000' ;4 RETLW B'00100000' ;5 RETLW B'01000000' ;6 RETLW B'10000000' ;7 ; ;--------------------------------------------------------------------- ; 点灯の閾値を設定 ;--------------------------------------------------------------------- SETTHRE ; 現時点の明るさを閾値に設定 CALL CHKCDS ; 明るさ測定 CALL WAIT1MS CALL WAIT1MS CALL WAIT1MS BTFSS GPIO,3 ; タクトスイッチが離されるまで待つ GOTO $-1 ; EEPROMへ書き込み MOVLW H'00' MOVWF EE_ADDR MOVF ADDATH,W MOVWF THREDAT ; 閾値レジスタ(上位) MOVWF EE_DATA CALL WRTEEP ; EEPROMへ書き込み RETURN ;--------------------------------------------------------------------- ; 明るさの測定 ;--------------------------------------------------------------------- CHKCDS CLRF ADRESH ; A/D変換結果 ; BSF ADCON0,0 ; A/Dオン CALL W100US ; 100us待ち BSF ADCON0,1 ; A/D変換開始 BTFSC ADCON0,1 ; A/D変換が終わるまでループ GOTO $-1 ; ; MOVF ADRESH,W ; A/D変換結果を格納(上位8ビットのみ使用) MOVWF ADDATH RETURN ; ;--------------------------------------------------------------------- ; 現在の明るさと閾値の比較 ;--------------------------------------------------------------------- CMPTHRE MOVF THREDAT,W ; 閾値 <= 現在値 ? SUBWF ADDATH,W RETURN ;--------------------------------------------------------------------- ; EEPROMへ書き込む(アドレス:EE_ADDR, データEE_DATA) ;--------------------------------------------------------------------- WRTEEP MOVF EE_ADDR,W ; BANK1 MOVWF EEADR ; Data Memory Address to write BANK0 MOVF EE_DATA,W ; BANK1 MOVWF EEDAT ; Data Memory Value to write BSF EECON1,WREN ; Enable writes BCF INTCON,GIE ; Disable INTs. MOVLW H'55' ; MOVWF EECON2 ; Write 55h MOVLW H'AA' ; MOVWF EECON2 ; Write AAh BSF EECON1,WR ; Set WR bit to begin write BSF INTCON,GIE ; Enable INTs. BANK0 RETURN ;--------------------------------------------------------------------- ; EEPROMから読み出す(アドレス:EE_ADDR, 結果:W) ;--------------------------------------------------------------------- REDEEP MOVF EE_ADDR,W ; BANK1 MOVWF EEADR ; Data Memory ; Address to read BSF EECON1,RD ; EE Read MOVF EEDAT,W ; W = EEDAT BANK0 RETURN ;--------------------------------------------------------------------- ; Waitルーチン(注)割り込みが入るので下記時間にはならない ;--------------------------------------------------------------------- W100US ; 約100usec MOVLW D'32' MOVWF CNT1 W100USLP DECFSZ CNT1,F GOTO W100USLP RETURN ; WAIT1MS ;1ミリ秒(998usec) CALLと合わせて1.000ms MOVLW D'248' ;1cycle MOVWF CNT1 ;1cycle W1MSLP NOP ;1cycle*248 DECFSZ CNT1,F ;1cycle*247+2cycle GOTO W1MSLP ;2cycle*247 GOTO $+1 ;2cycle NOP ;1cycle RETURN ;2cycle ; WSCAN ;30ミリ秒位 MOVLW D'30' ;1cycle MOVWF CNT2 ;1cycle WSCANLP CALL WAIT1MS ; DECFSZ CNT2,F ; GOTO WSCANLP ; RETURN ; ; WAIT ;0.5秒(499.998msec)CALLと合わせて500.000ms MOVLW D'249' ;1cycle MOVWF CNT2 ;1cycle WAITLP CALL WAIT1MS ;(2cycle+998cycle)*249 CALL WAIT1MS ;(2cycle+998cycle)*249 GOTO $+1 ;2cycle*249 GOTO $+1 ;2cycle*249 NOP ;1cycle*249 DECFSZ CNT2,F ;1cycle*248+2cycle GOTO WAITLP ;2cycle*248 NOP ;1cycle GOTO $+1 ;2cycle RETURN ;2cycle ; ;--------------------------------------------------------------------- ; 表示パターン1 ;--------------------------------------------------------------------- ORG H'0100' PAT1 MOVLW D'20' ; LEDの表示パターン数 MOVWF CNT ; ループカウント設定 CLRF PATADDR ; パターンアドレス PAT1LP CALL PAT1DT MOVWF LEDBUF INCF PATADDR,F CALL PAT1DT MOVWF LEDBUF+1 INCF PATADDR,F CALL WSCAN ; 表示パターン切り替え待ち時間 DECFSZ CNT,F GOTO PAT1LP CLRF LEDBUF CLRF LEDBUF+1 RETURN ; PAT1DT MOVLW H'01' MOVWF PCLATH MOVF PATADDR,W ADDWF PCL,F RETLW B'00000001' ; RETLW B'00000000' ; RETLW B'00000010' ; RETLW B'00000000' ; RETLW B'00000100' ; RETLW B'00000000' ; RETLW B'00001000' ; RETLW B'00000000' ; RETLW B'00010000' ; RETLW B'00000000' ; RETLW B'00100000' ; RETLW B'00000000' ; RETLW B'01000000' ; RETLW B'00000000' ; RETLW B'10000000' ; RETLW B'00000000' ; RETLW B'00000000' ; RETLW B'00000001' ; RETLW B'00000000' ; RETLW B'00000010' ; RETLW B'00000000' ; RETLW B'00000010' ; RETLW B'00000000' ; RETLW B'00000001' ; RETLW B'10000000' ; RETLW B'00000000' ; RETLW B'01000000' ; RETLW B'00000000' ; RETLW B'00100000' ; RETLW B'00000000' ; RETLW B'00010000' ; RETLW B'00000000' ; RETLW B'00001000' ; RETLW B'00000000' ; RETLW B'00000100' ; RETLW B'00000000' ; RETLW B'00000010' ; RETLW B'00000000' ; RETLW B'00000001' ; RETLW B'00000000' ; ; ;--------------------------------------------------------------------- END ;--------------------------------------------------------------------- ; 終わり ;---------------------------------------------------------------------