目次PIC回路集大型表示電波時計処理説明


大型表示電波時計 処理説明(表示スキャン)

表示スキャンプログラム

コンフィグレーションワード

012
013
014
015
016
017
018
        __config        h'3F10' ;OSC is Int 4MHz
                                ;RA5,RA6,RA7,RB4 are I/O
                                ;Power-up timer ON
                                ;Code protection OFF
                                ;Data code protection OFF   
                                ;Brown-out detection OFF
                                ;Watchdog timer OFF
PIC16F628は4MHzの発振器内蔵しています。これを使うことにより、外部発振器が不要になり、回路が簡単になります。また、それにより、I/Oポートを16ポートまで増やすことができます。今回の回路では14個のLEDをスキャンするので、内蔵発振器を使う必要がありました。

スキャンパターン

042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
ra_adr  equ    t10h             ;RA scan data table adr     
d10h    equ    b'00000001'      ;10th of hour
d1h     equ    b'00000010'      ;1st of hour
d10m    equ    b'00000100'      ;10th of minute
d1m     equ    b'00001000'      ;1st of minute
d10s    equ    b'01000000'      ;10th of second
d1s     equ    b'10000000'      ;1st of second

rb_adr  equ    t1000y           ;RB scan data table adr
d1000y  equ    b'11111110'      ;1000th of year
d100y   equ    b'11111101'      ;100th of year
d10y    equ    b'11111011'      ;10th of year
d1y     equ    b'11110111'      ;1st of year
d10mo   equ    b'11101111'      ;10th of month
d1mo    equ    b'11011111'      ;1st of month
d10d    equ    b'10111111'      ;10th of day
d1d     equ    b'01111111'      ;1st of day
今回の回路では曜日表示を除いて14個の7セグメントLEDを使用しています。この14個を2つのグループに分けてスキャンしています。ですから、同時には2つのLEDが点灯することになります。1つのグループにしたほうが電力消費は抑えられますが、表示が暗くなるので2つのグループにしました。
時10位、時1位、分10位、分1位、秒10位、秒1位の6個をグループにしてPORTAのI/Oポートで制御しています。RA5は入力専用のポートなので今回の用途には使えません。
年1000位、年100位、年10位、年1位、月10位、月1位、日10位、日1位の8個の8個をグループにしてPORTBのI/Oポートで制御しています。
PORTAに接続している回路は出力が"1"で点灯、PORTBの回路は出力"0"で点灯します。この違いでグループを分けたわけではありません。混在しても制御はできます。

各種レジスタの初期化処理

066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
;******************* Initial Process ********************   
init
;*** Set Port mode
        bsf     status,rp0      ;Change to Bank1
        movlw   b'00000000'     ;RA7-0:OUT mode
        movwf   trisa           ;Set TRISA reg
        movlw   b'00000000'     ;RB7-0:OUT mode
        movwf   trisb           ;Set TRISB reg

;*** Set Option reg
        movlw   b'00000001'     ;PS=1:4
        movwf   option_reg      ;Set OPTION_REG

;*** Set PIE1 reg
        movlw   b'00000000'     ;TMR1IE=OFF
        movwf   pie1            ;Set PIE1 reg
        bcf     status,rp0      ;Change to Bank0

;*** Set CMCON reg
        movlw   b'00000111'     ;RA port to digital
        movwf   cmcon           ;Set CMCON reg

;*** Set TMR0 reg
        movlw   d'6'            ;256-1000us/4us=6
        movwf   tmr0            ;Set TMR0
初期化処理では、PORTAおよびPORTBを全て出力モードに設定します。また、全てのポートをデジタルポートとして使うことをCMCONレジスタに設定します。
タイマーはTMR0のみを使用し、1_秒で割り込みが発生するように設定します。今回は内蔵の4MHz発振器を使用しています。その周期は0.25μ秒ですが、PICの動作クロックはその4倍の1μ秒になります。TMR0への入力はプリスケーラでさらに4倍とし、4μ秒でカウントさせます。1_秒=1000μ秒は250カウントになります。カウントはTMR0レジスタで行われ、カウント値が0になると割り込みが発生します。TMR0でカウントできる最大値は255ですから、256-250=6がTMR0に設定する値になります。255ではなく256としているのは最大値(255)から0になるときに割り込みが発生するので、1つ多い値で計算する必要があります。


ワークエリアの初期化処理

092
093
094
095
096
097
098
099
100
101
102
103
104

 
;*** Other registers and work area initialization
        clrf    porta           ;Clear PORTA
        clrf    portb           ;Clear PORTB
        clrf    ra_index        ;Clear PORTA index
        clrf    rb_index        ;Clear PORTB index
        movlw   d1000y          ;Read 1000th of year data   
        movwf   t1000y          ;Set 1000th of year data
        movlw   d100y           ;Read 100th of year data
        movwf   t100y           ;Set 100th of year data
        movlw   d10y            ;Read 10th of year data
        movwf   t10y            ;Set 10th of year data
        movlw   d1y             ;Read 1st of year data
        movwf   t1y             ;Set 1st of year data

以下省略
PORTAおよびPORTBの初期化および各種ワークエリアの初期化を行います。
スキャンパターンを汎用メモリに設定します。これは間接アドレス処理を行うためです。


割り込み設定および割り込み待ち処理

126
127
128
129
130
;*** Set interrupt condition
        movlw   b'10100000'     ;GIE,TOIE=1
        movwf   intcon          ;Interruption enable        

        goto    $               ;Wait interruption
全ての初期化処理が終わった段階でINTCONレジスタに割り込み可能設定を行います。使用する割り込みはTMR0の割り込みだけです。
あとは割り込みを待つだけなので、自分のアドレスを繰り返し実行させます。"$"は自分自身のアドレスを指します。

割り込み処理

132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147

 
int
;***** TMR0 Interruption ( 1 millisecond interval) ******   
        bcf     intcon,t0if     ;Clear timer int flag
        movlw   d'6'            ;Set 1 millisecond
        movwf   tmr0            ;Set TMR0

        movlw   ra_adr          ;Read RA table head adr
        addwf   ra_index,w      ;RA table head + index
        movwf   fsr             ;Set table address
        movfw   indf            ;Read data
        movwf   porta           ;Set data to PORTA
        incf    ra_index,f      ;RA index + 1
        movfw   ra_index        ;Read RA index
        sublw   d'5'            ;Check upper limit
        btfss   status,c        ;Over ?
        clrf    ra_index        ;Yes. Clear PORTA index

以下省略
1_秒毎に割り込みが発生します。
割り込み処理で最初に行うことは割り込みフラッグのクリアです。これを行わないとタイマーの時間に関係なく常に割り込みが発生してしまいます。
次にTMR0にタイマー値を再設定します。TMR0の値はカウントにより書き換えられています。
次がスキャン処理です。スキャンデータは初期化処理で汎用メモリにPORTA用とPORTB用を作ってあります。ra_index はPORTA用データのインデックス値、rb_index はPORTB用データのインデックス値です。各データの先頭番地にインデックス値を加えた場所にあるデータがポートに設定するデータになります。インデックスは毎回1つ加算し、最大値を超えた場合には0にして先頭のデータを取り出すようにしています。
PORTAのグループは6_秒で一周し、PORTBのグループは8_秒で一周します。
各LEDから見ると、例えば時10位のLEDはある時点で1_秒点灯し、そのあと5_秒消灯、再び1_秒点灯というように点滅を繰り返す動作をします。年1000位の場合は1_秒点灯、7_秒消灯を繰り返します。
_秒オーダーの点滅ですから、人間の目には連続して点灯しているように見えます。