Skip to content

Instantly share code, notes, and snippets.

@ha2zakura

ha2zakura/main1.asm

Last active Mar 21, 2018
Embed
What would you like to do?
16F84A+Matrix LED
; マトリクスLED
; ha2zakura
list p=16F84A ; 使用するPICの種類の定義
#include <p16F84A.inc> ; 設定ファイルの指定
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC
; _CP_OFF プログラムコードプロテクト無効
; _WDT_OFF ウォッチドドック・タイマ無効
; _PWRTE_ON パワーアップタイム有効
; _HS_OSC 外部クロック(4MHz-20MHz)
;***** 定数の定義 **
MOSI EQU 0
SCK EQU 1
SS EQU 2
CNT EQU 0x0C
DAT0 EQU 0x0D ; 書き込みデータ
DAT1 EQU 0x0E ; 書き込みデータ
;**********************************************************************
ORG 0x000 ; リセット
BSF STATUS, RP0
CLRF TRISA ; 0 : 出力, 1 : 入力
CLRF TRISB ; bit0 -> RA0(RB0)
BCF STATUS, RP0
goto MAIN ; MAINへ移動
;**********************************************************************
; メイン
MAIN bcf PORTB, MOSI
bcf PORTB, SCK
bsf PORTB, SS
movlw B'11011011'
movwf DAT0
movlw B'11011011'
movwf DAT1
call DATOUT
LOOP goto LOOP
DATOUT bcf PORTB, SS
call SHTOUT
movf DAT1, w
movwf DAT0
call SHTOUT
bsf PORTB, SS
return
SHTOUT movlw D'8'
movwf CNT
DO0 btfss DAT0, 0
goto DO1
call MOSIS
goto DO2
DO1 call MOSIC
DO2 RRF DAT0, f
decfsz CNT, f
goto DO0
return
MOSIS bsf PORTB, MOSI
bsf PORTB, SCK
bcf PORTB, SCK
return
MOSIC bcf PORTB, MOSI
bsf PORTB, SCK
bcf PORTB, SCK
return
END
; timer0によるマトリクスLED
; ha2zakura
list p=16F84A ; 使用するPICの種類の定義
#include <p16F84A.inc> ; 設定ファイルの指定
; Fosc = 外部4.000MHz
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC
; _CP_OFF プログラムコードプロテクト無効
; _WDT_OFF ウォッチドドック・タイマ無効
; _PWRTE_ON パワーアップタイム有効
; _HS_OSC 外部クロック(4MHz-20MHz)
;***** 定数の定義 **
MOSI EQU D'0'
SCK EQU D'1'
SS EQU D'2'
TMR0CNT EQU D'221' ; TMR0初期値
; 計算方法
; 1サイクル実行時間 = 4/発振子の周波数
; 1サイクル実行時間*プリスケーラ値*(256-TMR初期値) = Timer0割り込み周期
w_temp EQU 0x0C ; Wレジスタ保存用
status_temp EQU 0x0D ; STATUSレジスタ保存用
CNT EQU 0x0E
DAT0 EQU 0x0F ; 書き込みデータ
DAT1 EQU 0x10 ; 書き込みデータ
ARR EQU 0x11 ; 配列先頭
POS EQU 0x19 ; ポインタ
I EQU 0x1A ; for文用
;**********************************************************************
ORG 0x000 ; リセット
goto MAIN ; MAINへ移動
;**********************************************************************
ORG 0x004 ; 割り込み処理
goto INTR
;**********************************************************************
; メイン
MAIN bsf STATUS, RP0 ; バンク1へ
clrf TRISA ; 0 : 出力, 1 : 入力
clrf TRISB ; bit0 -> RA0(RB0)
movlw B'01010001' ; プリスケーラの設定
movwf OPTION_REG
bcf STATUS, RP0 ; バンク0へ
clrf PORTA
clrf PORTB
movlw TMR0CNT ; カウント値の設定
movwf TMR0
bsf INTCON, T0IE ; TMR0割り込みを許可
bsf INTCON, GIE ; 割り込みを許可
clrf POS ; ポインタをリセット
movlw B'00000000'
movwf ARR+0
movlw B'00011000'
movwf ARR+1
movlw B'00111100'
movwf ARR+2
movlw B'01111110'
movwf ARR+3
movlw B'01111110'
movwf ARR+4
movlw B'00111100'
movwf ARR+5
movlw B'00011000'
movwf ARR+6
movlw B'00000000'
movwf ARR+7
LOOP goto LOOP
DATOUT bcf PORTB, SS
call SHTOUT
movf DAT1, w
movwf DAT0
call SHTOUT
bsf PORTB, SS
return
SHTOUT movlw D'8'
movwf CNT
DO0 btfss DAT0, 0
goto DO1
call MOSIS
goto DO2
DO1 call MOSIC
DO2 RRF DAT0, f
decfsz CNT, f
goto DO0
return
MOSIS bsf PORTB, MOSI
bsf PORTB, SCK
bcf PORTB, SCK
return
MOSIC bcf PORTB, MOSI
bsf PORTB, SCK
bcf PORTB, SCK
return
;**********************************************************************
; 割り込み処理
INTR
movwf w_temp ; Wレジスタを保存しておく
movf STATUS, w ; STATUSレジスタも保存しておく
movwf status_temp
bcf INTCON, T0IF ; TMR0オーバーフローフラグのクリア
bsf INTCON, T0IE ; TMR0オーバーフローフラグのクリア
movlw TMR0CNT ; カウント値の設定
movwf TMR0
;割り込み処理メイン
movlw ARR ; 配列先頭アドレスをWに
addwf POS, w ; ポインタをWに加算
movwf FSR ; 間接アドレッシング
movf INDF, w ; ARR[POS]の値を行の値として設定
movwf DAT0 ;
clrf DAT1 ; 列の位置をリセット
bsf DAT1, 7 ; 列の位置を一番上に
movf POS, w ; ポインタをIに
movwf I
incf I, f ; ポインタが0の場合はシフトしない
decfsz I, f
goto YLOOP
goto YOUT
YLOOP bcf STATUS, C ; Cフラグを一応削除
rrf DAT1, f ; 列の位置を下にシフト
decfsz I, f ; ポインタの数だけ繰り返す
goto YLOOP
YOUT call DATOUT ; 行の値と列の位置を出力
incf POS, f ; ポインタを加算
movlw D'8' ; ポインタが8になった時は、
xorwf POS, w
BTFSC STATUS, Z
clrf POS ; ポインタをリセット
movf status_temp, w ; STATUSを復帰
movwf STATUS
swapf w_temp, f
swapf w_temp, w ; Wレジスタを復帰
retfie ; 割り込みから復帰
END
; マトリクスLED(アニメーション...?)
; ha2zakura
list p=16F84A ; 使用するPICの種類の定義
#include <p16F84A.inc> ; 設定ファイルの指定
; Fosc = 外部4.000MHz
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC
; _CP_OFF プログラムコードプロテクト無効
; _WDT_OFF ウォッチドドック・タイマ無効
; _PWRTE_ON パワーアップタイム有効
; _HS_OSC 外部クロック(4MHz-20MHz)
;***** 定数の定義 **
MOSI EQU D'0'
SCK EQU D'1'
SS EQU D'2'
TMR0CNT EQU D'252' ; TMR0初期値
; 計算方法
; 1サイクル実行時間 = 4/発振子の周波数
; 1サイクル実行時間*プリスケーラ値*(256-TMR初期値) = Timer0割り込み周期
w_temp EQU 0x0C ; Wレジスタ保存用
status_temp EQU 0x0D ; STATUSレジスタ保存用
CNT EQU 0x0E
DAT0 EQU 0x0F ; 書き込みデータ
DAT1 EQU 0x10 ; 書き込みデータ
ARR EQU 0x11 ; 配列先頭
POS EQU 0x19 ; ポインタ
I EQU 0x1A ; for文用
TIM1 EQU 0x1B ; タイマー用
TIM2 EQU 0x1C ; タイマー用
;**********************************************************************
ORG 0x000 ; リセット
goto MAIN ; MAINへ移動
;**********************************************************************
ORG 0x004 ; 割り込み処理
goto INTR
;**********************************************************************
; メイン
MAIN bsf STATUS, RP0 ; バンク1へ
clrf TRISA ; 0 : 出力, 1 : 入力
clrf TRISB ; bit0 -> RA0(RB0)
movlw B'01010111' ; プリスケーラの設定
movwf OPTION_REG
bcf STATUS, RP0 ; バンク0へ
clrf PORTA
clrf PORTB
movlw TMR0CNT ; カウント値の設定
movwf TMR0
bsf INTCON, T0IE ; TMR0割り込みを許可
bsf INTCON, GIE ; 割り込みを許可
clrf POS ; ポインタをリセット
LOOP movlw B'00000000'
movwf ARR+0
movlw B'00000000'
movwf ARR+1
movlw B'00000000'
movwf ARR+2
movlw B'00011000'
movwf ARR+3
movlw B'00011000'
movwf ARR+4
movlw B'00000000'
movwf ARR+5
movlw B'00000000'
movwf ARR+6
movlw B'00000000'
movwf ARR+7
call Delay
movlw B'00000000'
movwf ARR+0
movlw B'00000000'
movwf ARR+1
movlw B'00011000'
movwf ARR+2
movlw B'00100100'
movwf ARR+3
movlw B'00100100'
movwf ARR+4
movlw B'00011000'
movwf ARR+5
movlw B'00000000'
movwf ARR+6
movlw B'00000000'
movwf ARR+7
call Delay
movlw B'00000000'
movwf ARR+0
movlw B'00000000'
movwf ARR+1
movlw B'00100100'
movwf ARR+2
movlw B'00000000'
movwf ARR+3
movlw B'00000000'
movwf ARR+4
movlw B'00100100'
movwf ARR+5
movlw B'00000000'
movwf ARR+6
movlw B'00000000'
movwf ARR+7
call Delay
movlw B'00000000'
movwf ARR+0
movlw B'00111100'
movwf ARR+1
movlw B'01000010'
movwf ARR+2
movlw B'01000010'
movwf ARR+3
movlw B'01000010'
movwf ARR+4
movlw B'01000010'
movwf ARR+5
movlw B'00111100'
movwf ARR+6
movlw B'00000000'
movwf ARR+7
call Delay
movlw B'00000000'
movwf ARR+0
movlw B'01000010'
movwf ARR+1
movlw B'00000000'
movwf ARR+2
movlw B'00000000'
movwf ARR+3
movlw B'00000000'
movwf ARR+4
movlw B'00000000'
movwf ARR+5
movlw B'01000010'
movwf ARR+6
movlw B'00000000'
movwf ARR+7
call Delay
movlw B'01111110'
movwf ARR+0
movlw B'10000001'
movwf ARR+1
movlw B'10000001'
movwf ARR+2
movlw B'10000001'
movwf ARR+3
movlw B'10000001'
movwf ARR+4
movlw B'10000001'
movwf ARR+5
movlw B'10000001'
movwf ARR+6
movlw B'01111110'
movwf ARR+7
call Delay
movlw B'10000001'
movwf ARR+0
movlw B'00000000'
movwf ARR+1
movlw B'00000000'
movwf ARR+2
movlw B'00000000'
movwf ARR+3
movlw B'00000000'
movwf ARR+4
movlw B'00000000'
movwf ARR+5
movlw B'00000000'
movwf ARR+6
movlw B'10000001'
movwf ARR+7
call Delay
clrf ARR+0
clrf ARR+1
clrf ARR+2
clrf ARR+3
clrf ARR+4
clrf ARR+5
clrf ARR+6
clrf ARR+7
call Delay
call Delay
call Delay
call Delay
goto LOOP
DATOUT bcf PORTB, SS
call SHTOUT
movf DAT1, w
movwf DAT0
call SHTOUT
bsf PORTB, SS
return
SHTOUT movlw D'8'
movwf CNT
DO0 btfss DAT0, 0
goto DO1
call MOSIS
goto DO2
DO1 call MOSIC
DO2 RRF DAT0, f
decfsz CNT, f
goto DO0
return
MOSIS bsf PORTB, MOSI
bsf PORTB, SCK
bcf PORTB, SCK
return
MOSIC bcf PORTB, MOSI
bsf PORTB, SCK
bcf PORTB, SCK
return
TIM movlw 0xFF
movwf TIM1
TIMLP nop
decfsz TIM1, F
goto TIMLP
return
Delay movlw 0x33
movwf TIM2
TIMLP2 call TIM
decfsz TIM2, F
goto TIMLP2
return
;**********************************************************************
; 割り込み処理
INTR
movwf w_temp ; Wレジスタを保存しておく
movf STATUS, w ; STATUSレジスタも保存しておく
movwf status_temp
bcf INTCON, T0IF ; TMR0オーバーフローフラグのクリア
bsf INTCON, T0IE ; TMR0オーバーフローフラグのクリア
movlw TMR0CNT ; カウント値の設定
movwf TMR0
;割り込み処理メイン
movlw ARR ; 配列先頭アドレスをWに
addwf POS, w ; ポインタをWに加算
movwf FSR ; 間接アドレッシング
movf INDF, w ; ARR[POS]の値を行の値として設定
movwf DAT0 ;
clrf DAT1 ; 列の位置をリセット
bsf DAT1, 7 ; 列の位置を一番上に
movf POS, w ; ポインタをIに
movwf I
incf I, f ; ポインタが0の場合はシフトしない
decfsz I, f
goto YLOOP
goto YOUT
YLOOP bcf STATUS, C ; Cフラグを一応削除
rrf DAT1, f ; 列の位置を下にシフト
decfsz I, f ; ポインタの数だけ繰り返す
goto YLOOP
YOUT call DATOUT ; 行の値と列の位置を出力
incf POS, f ; ポインタを加算
movlw D'8' ; ポインタが8になった時は、
xorwf POS, w
BTFSC STATUS, Z
clrf POS ; ポインタをリセット
movf status_temp, w ; STATUSを復帰
movwf STATUS
swapf w_temp, f
swapf w_temp, w ; Wレジスタを復帰
retfie ; 割り込みから復帰
END
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment