PICによる計数実験

  1. 計数器

    1. 計数とは
      順に数を数えます。ここでは、2進数で計数します。

    2. モードnの計数
       n-1まで数えると、0に戻る場合、モードnの計数といいます。モード10の計数器を接続すると、10進数の計数ができます。ここでは、モードの値を スイッチ で設定します。

  2. プログラムの説明

    1. 回路
      ポートAにスイッチ、ポートBにLEDを接続した回路を利用します。

    2. プログラムと命令
       変数Count に計数値を記録します。Count の値を増やすには
        incf Count 
      命令を利用します。incは「increment」の略です。モードnにするには、Countの値がPortAの値と同じになったら、Countを0に戻す必要があります。このため、次のプログラムを組みます。CountとPORTAを同時に扱うことはできませんから、まず、CountA の値を W に移します。次に比較のため、PORTA から W の値を引きます(subwf は引き算命令)。この結果が 0 になると、STATUSレジスタの Z フラグ に対応するビットが1になります。このZフラグが0のとき、次の clrf 命令をスキップします。Z フラグが1の場合、clrf 命令を実行し、これは Count の値をクリア(clear:0にする)します。

       movf    Count,W          ;W <- Count
       subwf   PORTA,W     ;w == PORTA ?
       btfsc    STATUS,Z    ;同じでなければスキップ
       clrf       Count        ;Count <- 0

    3. 暇つぶし
       今回も、Timer3 以下のプログラムで、1回計数するごとに 3重の繰り返しを行い、時間を稼ぎます。これをしないと早く動きすぎて、目に見えないからです。

    4. ソースプログラム
      ;*********************************************
      ;   PIC16F628A
      ;   4bit計数プログラム
      ;   「ディジタル回路」実験用教材
      ;   
      ;*********************************************
      
      ;入出力ピン対応表
      ;   RA0,1,2,3   SW入力
      ;   RB0,1,2,3   LED出力
      
      LIST P=16F628, ST=OFF, R=DEC, F=INHX8M
      INCLUDE <P16F628A.INC>
      
      __CONFIG _LVP_OFF & _CP_OFF & _BODEN_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT 
      
      ; 変数の定義
      
      ;  メインルーチン
      CNT1     EQU     20h     ;TIMER1用カウンタ
      CNT2     EQU     21h     ;TIMER2用カウンタ
      CNT3     EQU     22h     ;0.5秒カウント用カウンタ
      Count    EQU     23h     ;シフトするデータを格納するレジス
      
      ; プログラム開始番地
              org    0                ;Reset Start
      MAIN        
       ;ポート設定
              movlw   0x07
              movwf   CMCON            ;PORTAをIOとして使用する
      
              bsf     STATUS, RP0       ;BANK1にする
              movlw   B'00001111'
              movwf   TRISA             ;RA3,2,1,0を入力に
              
              movlw   B'11110000'
              movwf   TRISB              ;RB0,1,2,3を出力に
      
              bcf     STATUS, RP0         ;BANK0に戻す
              
              movlw   0                   ;初期化
              movwf   Count
      
      ;ポートAから入力し、ポートBに出力、
      LOOP
              movf    Count,W         ;Count -> W
              movwf   PORTB        ;W -> PORTB
              call    TIMER3          ;約0.5秒待機
              
              incf    Count
              movf    Count,W
              subwf   PORTA,W       ;w == PORTA ?
              btfsc   STATUS,Z      ;同じでなければスキップ
              clrf    Count         ;Count<0
              goto    LOOP          ;DTOUTへ戻りシフトを繰り返す
      
      
      ;***** 約0.5秒のタイマー(@4MHz) *****
      TIMER3  MOVLW   d'10'           ;10 ->W
              MOVWF   CNT3            ;W -> CNT3
      TIMLP3  CALL    TIMER1          ;50m秒待機
              DECFSZ  CNT3, F         ;CNT3を減らし0なら次をスキップ
              GOTO    TIMLP3          ;CNT3がゼロになるまで繰り返す
              RETURN                  ;戻る
      
      ; ***** 約50m秒のタイマ(@4MHz) *****
      TIMER1  MOVLW   d'99'           ;TIMER2を99回実行する
              MOVWF   CNT1            ;CNT1 = 99
              NOP                     ;何もしない命令で時間調整
              NOP
      TIMLP1  CALL    TIMER2
              DECFSZ  CNT1, F         ;CNT1を減らし、ゼロなら次をスキップ
              GOTO    TIMLP1
              RETURN
      
      ; ***** 約500μ秒のタイマ(@4MHz) *****
      TIMER2  MOVLW   d'165'          ;
              MOVWF   CNT2            ;CNT1 = 165
              NOP                     ;
              NOP                     ;NOPを2回入れることで、正確に500回となる。
      TIMLP2  DECFSZ  CNT2, F         ;CNT1を減らしゼロなら次をスキップ
              GOTO    TIMLP2
              RETURN
      
              end                     ;プログラム終了

  3. 実験

    1. プロジェクト作成
      まず、プロジェクトのフォルダを作成します。標準は、workフォルダにex0627フォルダを作成します。配布FDDからソースファイル excount4.asm をex0627 フォルダにコピーします。
       ProjectWizardから、projectを作成します。ディレクトリ(フォルダ)とプロジェクト名を指定し、先に作成したソースファイルをプロジェクトに追加します。

    2. デバッグ
       F7キーは命令単位でデバッグします。F8キーは、call 命令も1命令として実行しますから、call TIMER3 も(少し時間がかかりますかが)F8キーで、プログラムを変更せずにデバッグできます。
      デバッグの前に、
       まず、Debuggerメニューの Stimulas でPORTA のRA4をHighに設定しておきます。次に、watchウインドウで、PORTA、PORTB、WREG、それにCount の値をチェックしてください。
       これで、F8キーを押すと、順に命令が実行され、Countの値が04になったら、0に戻ることを確認してください。
       
    3. 書き込み準備
       FDDから ICProg フォルダを Work フォルダにコピーしてください。次に、RS232Cケーブルで パソコンのシリアル端子とPICライターボードを接続します。
       ICProgを立ち上げます。設定画面が出ますから、プログラマをJDM、ポートをCOM1、インターフェースを WindowsAPI に設定します。
       PIC の下に束線用の紐をとおしPICを抜き取り、PICライタに移します。このとき、RSケーブルを上にしたとき、左がICの1ピンになります。間違えないよう挿入してください。

    4. 書き込み
       ツールバーの横にあるメニューでPICとして 16F628A を選択し、ファイルメニューからプロジェクトフォルダの中の HEX ファイルを選択します。ツールメニューので、書き込みを開始します。書き込みが完了すると、照合チェックを行います。ここで、エラーがでても正常に書き込みができている場合もあります。
       ICを抜き取りパッチボードに戻し、実行してください。

  4. レポート

    1. レポート
      どこまでできたかレポートしてください

      プロジェクトの作成
      デバッグによるプログラムの確認
      IC_Progの組み込み
      PICライタの接続
      PICへの書き込み
      実行