;--------------------------------------------------------------------- ; クリスマス・オーナメント ; ; 2020.11.20 naka ; 1. I/Oポート ; ; (1). 出力ポート ; GP0-2: LEDに繋ぐ ; (2). 入力ポート ; GP3 : CDSと抵抗でVDDを分圧し明るさをセンス(sleepからの復帰割り込み) ; ; 2. 光り方 ; ・4段階(フル,1/2,1/4,消灯)でランダムに点灯する。 ; ・時々高速に点滅 ; ・時々回転表示 ; ; 3. 暗くなると自動点灯 ; 普段はsleepしていて、暗くなるとGPIOの変化による割り込みで ; sleepから復帰して点灯する。 ;--------------------------------------------------------------------- LIST P=PIC12F675 INCLUDE "P12F675.INC" __CONFIG _CPD_OFF & _CP_OFF & _BODEN_OFF & _MCLRE_OFF & _PWRTE_OFF & _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) ; 各LED 2ビットで明るさ設定(00,01,10,11の順) ; 6LEDなので24H、25Hの半分使用 LEDCNT EQU 26H ; 割り込みで表示するLED番号カウンタ PATADDR EQU 27H ; 表示パターンのアドレスカウンタ PATCNT EQU 28H ; 表示パターンの表示繰り返しカウンタ TMP EQU 29H ; 一時作業用(割り込み内) FLWAIT EQU 2AH ; FLASHウエイト時間 PWMCNT EQU 2BH ; 疑似PWMのためのカウンタ(0〜3で変化) DSPFLG EQU 2CH ; 表示/非表示フラグ(0:非表示、1:表示) ; TMP2 EQU 30H ; 一時作業(割り込み外) RNDVAL EQU 31H ; 乱数生成用 WK1 EQU 32H ; 乱数生成用 BLNKCNT EQU 33H ; 高速点滅までのカウンタ WCNT EQU 34H ; 高速点滅回数カウンタ INDEX EQU 35H ; 回転表示時のパターンインデックス RCNT EQU 36H ; 回転表示カウンタ ; BKUPW EQU 40H ; 割り込み待避用 BKUPS EQU 41H ; 割り込み待避用 BKUPFR EQU 42H ; 割り込み待避用 BKUPPCL EQU 43H ; 割り込み待避用 ; ;--------------------------------------------------------------------- ; リセット・割り込み ;--------------------------------------------------------------------- ORG 00H ; リセット時の飛び込み先 RESET GOTO START ; 初期設定へ ; ;--------------------------------------------------------------------- ; 割り込み処理でダイナミック表示を行う。 ; (4回の割り込みで1LED分 ; 4段階PWM) ;--------------------------------------------------------------------- ORG 04H ; 割り込み時の飛び込み先 INTRUPT ;レジスタ待避 MOVWF BKUPW ;バックアップ(Wレジ) SWAPF STATUS,W ;バックアップ(STATUSレジ) MOVWF BKUPS MOVF FSR,W ;バックアップ(FSRレジ) MOVWF BKUPFR MOVF PCLATH,W ;バックアップ(PCLATHレジ) MOVWF BKUPPCL ; BTFSS INTCON,GPIF ; 外部割り込みか? GOTO INT1 ; MOVF GPIO,F ; 一度、空読みしないと割り込みが連続する BCF DSPFLG,0 BTFSC GPIO,3 ; LowならSleep,Highなら表示 BSF DSPFLG,0 ; 表示 BCF INTCON,GPIF ; INT1 ; BCF INTCON,T0IF ;割り込みフラグリセット ; ; 点灯するLEDの明るさを確認 ; MOVF LEDCNT,W ; LED番号 CALL LEDBRT ; 0,1,2,4が返る SUBWF PWMCNT,W ; PWMCNT - 明るさ > 0 なら点灯 BTFSS STATUS,C GOTO DISP GOTO UNDISP ; DISP MOVF LEDCNT,W MOVWF LED_NO ; 表示番号をLED_NOへ ; ; LED表示 ; CLRF GPIO BSF STATUS,RP0 ; bank1 切り替え MOVLW H'FF' MOVWF TRISIO BCF STATUS,RP0 ; bank0に戻す ; 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 PWMCNT,W ANDLW H'03' MOVWF PWMCNT BTFSS STATUS,Z GOTO RSTREG ; INCF LEDCNT,F ; 次の割り込みに備え、カウントアップ MOVF LEDCNT,W SUBLW D'6' ; LED:0〜5 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 ; 全割込み禁止 ; CLRF GPIO MOVLW B'00111111' ; GPIOをデジタルI/Oに設定 MOVWF CMCON ; デフォルトはコンパレータ BANK1 MOVLW B'00010111' ; GPIO3,5(空き→出力) MOVWF TRISIO ; ;TMR0割り込みタイマーセット MOVLW H'88' ; プリスケーラを使わない MOVWF OPTION_REG ; clock4MHz -> 1Mcycle ; 1Mcycle/256/2=3,906Hz(=256usec毎) ; 割り込み4回でひとつのLEDを点灯 ; 明るい :割り込み4回とも点灯 ; 少し暗い:割り込み4回のうち2回のみ点灯 ; 暗い :割り込み4回のうち1回のみ点灯 ; LED 12個x4回なので3,906/48=81Hzとなりチラチラしない ; GPIO割り込み(明るさ検知) MOVLW B'00001000' ; GP3 Interrupt-on-change enabled MOVWF IOC BANK0 ; CLRF LEDCNT ; LEDカウンタクリア CLRF LEDBUF ; LEDバッファクリア CLRF LEDBUF+1 ; LEDバッファクリア CLRF DSPFLG ; CLRF PWMCNT CLRF BLNKCNT ; ;--------------------------------------------------------------------- ; メイン ;--------------------------------------------------------------------- MAIN BSF INTCON,T0IE ; タイマー0割り込みイネーブル BSF INTCON,PEIE ; 周辺割り込み許可 BSF INTCON,GPIE ; GPIO change割り込み許可 BSF INTCON,GIE ; 割り込み許可 ; CALL DIAG ; 電源投入の動作確認のために表示 CALL RANDINT MAINLP CALL RNDBLINK BTFSS DSPFLG,0 ; 非表示ならSleep GOTO MAINSLEEP ; CALL FASTBLINK BTFSS DSPFLG,0 ; 非表示ならSleep GOTO MAINSLEEP ; CALL RNDBLINK BTFSS DSPFLG,0 ; 非表示ならSleep GOTO MAINSLEEP ; CALL ROTATION BTFSS DSPFLG,0 ; 非表示ならSleep GOTO MAINSLEEP ; GOTO MAINLP ; MAINSLEEP BCF INTCON,T0IE ; タイマー0割り込み停止 CLRF GPIO SLEEP NOP ; BSF INTCON,T0IE ; タイマー0割り込みイネーブル GOTO MAINLP ;--------------------------------------------------------------------- ; 高速点滅 ;--------------------------------------------------------------------- FASTBLINK MOVLW D'30' MOVWF BLNKCNT FASTBLP CALL RNDPAT ; ランダム点灯 MOVLW D'10' ; wait 40ms CALL WBLINK DECFSZ BLNKCNT,F GOTO FASTBLP RETURN ; ;--------------------------------------------------------------------- ; 通常ランダム点滅 ;--------------------------------------------------------------------- RNDBLINK MOVLW D'30' MOVWF BLNKCNT RNDBLP CALL RNDPAT ; ランダム点灯 MOVLW D'200' ; wait 800ms CALL WBLINK DECFSZ BLNKCNT,F GOTO RNDBLP RETURN ; ;--------------------------------------------------------------------- ; 回転表示(点灯の明るさは1/2) ;--------------------------------------------------------------------- ROTATION MOVLW D'10' ; 10回転 MOVWF WCNT ROTLP1 MOVLW D'7' ; 7通りの表示パターン MOVWF RCNT CLRF INDEX ROTLP2 CALL ROTGET MOVWF LEDBUF INCF INDEX,F CALL ROTGET MOVWF LEDBUF+1 INCF INDEX,F MOVLW D'10' ; wait時間(40ms) CALL WBLINK DECFSZ RCNT,F GOTO ROTLP2 ; DECFSZ WCNT,F GOTO ROTLP1 RETURN ; ROTGET CLRF PCLATH MOVF INDEX,W ADDWF PCL,F ROTDT RETLW B'00000011' ; 0 RETLW B'00000000' ; ; RETLW B'00001101' ; 1 RETLW B'00000000' ; ; RETLW B'00110100' ; 2 RETLW B'00000000' ; ; RETLW B'11010000' ; 3 RETLW B'00000000' ; ; RETLW B'01000000' ; 4 RETLW B'00000011' ; ; RETLW B'00000000' ; 5 RETLW B'00001101' ; ; RETLW B'00000000' ; 6 RETLW B'00000100' ; ; ;--------------------------------------------------------------------- ; 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'00000001' ; LED 4 RETLW B'00000100' ; LED 5 ; TABLE_TRIS CLRF PCLATH ADDWF PCL,F RETLW B'00011100' ; LED 0 RETLW B'00011100' ; LED 1 RETLW B'00011001' ; LED 2 RETLW B'00011001' ; LED 3 RETLW B'00011010' ; LED 4 RETLW B'00011010' ; LED 5 ; ;--------------------------------------------------------------------- ; 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 ; ;--------------------------------------------------------------------- ; LED番号からLEDBUFの値(明るさ)を取り出す(0,1,2,4) ;--------------------------------------------------------------------- LEDBRT BCF STATUS,C RLF LEDCNT,W ; LED番号を2倍しジャンプ先アドレスに変換 CLRF PCLATH ADDWF PCL,F ; CALL LEDNO_0 GOTO LEDBRT_1 CALL LEDNO_1 GOTO LEDBRT_1 CALL LEDNO_2 GOTO LEDBRT_1 CALL LEDNO_3 GOTO LEDBRT_1 CALL LEDNO_4 GOTO LEDBRT_1 CALL LEDNO_5 GOTO LEDBRT_1 LEDBRT_1 MOVWF TMP SUBLW D'3' BTFSC STATUS,Z INCF TMP,F MOVF TMP,W RETURN ; LEDNO_0 MOVF LEDBUF,W ANDLW B'00000011' ; LEDNO = 0 RETURN ; LEDNO_1 MOVF LEDBUF,W ANDLW B'00001100' ; LEDNO = 1 MOVWF TMP BCF STATUS,C RRF TMP,F RRF TMP,W RETURN ; LEDNO_2 SWAPF LEDBUF,W ANDLW B'00000011' ; LEDNO = 2 RETURN ; LEDNO_3 SWAPF LEDBUF,W ANDLW B'00001100' ; LEDNO = 3 MOVWF TMP BCF STATUS,C RRF TMP,F RRF TMP,W RETURN ; LEDNO_4 MOVF LEDBUF+1,W ANDLW B'00000011' ; LEDNO = 4 RETURN ; LEDNO_5 MOVF LEDBUF+1,W ANDLW B'00001100' ; LEDNO = 5 MOVWF TMP BCF STATUS,C RRF TMP,F RRF TMP,W RETURN ; ;--------------------------------------------------------------------- ; 消灯 ;--------------------------------------------------------------------- LEDOFF CLRF LEDBUF CLRF LEDBUF+1 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 ; WBLINK ; Wレジに待ち時間(単位4ms)を入れてCALL MOVWF CNT2 WBLINKLP CALL WAIT1MS CALL WAIT1MS CALL WAIT1MS CALL WAIT1MS BTFSS DSPFLG,0 ; 非表示になったら即時リターン RETURN DECFSZ CNT2,F GOTO WBLINKLP RETURN ; ;--------------------------------------------------------------------- ; 電源投入時、全LED点灯 ;--------------------------------------------------------------------- DIAG MOVLW B'11111111' ; MOVWF LEDBUF MOVLW B'00001111' ; MOVWF LEDBUF+1 ; MOVLW D'250' ; 点灯時間 CALL WBLINK RETURN ; ;--------------------------------------------------------------------- ; ランダム表示 ;--------------------------------------------------------------------- RNDPAT CALL RANDOM MOVWF LEDBUF CALL RANDOM MOVWF LEDBUF+1 ; RETURN ;--------------------------------------------------------------------- ; M系列乱数(1〜255) ;--------------------------------------------------------------------- RANDINT MOVLW B'00101010' XORWF TMR0,W MOVWF RNDVAL RANDOM MOVF RNDVAL,W MOVWF WK1 RRF WK1,F RRF WK1,F XORWF WK1,W RRF WK1,F RRF WK1,F XORWF WK1,W RRF WK1,F RRF WK1,F RRF WK1,F XORWF WK1,F BCF STATUS,C BTFSC WK1,0 BSF STATUS,C RLF RNDVAL,F MOVF RNDVAL,W RETURN ; END ;--------------------------------------------------------------------- ; 終わり ;---------------------------------------------------------------------