第23週
;16F877でPWM
;*********************************************
        LIST        P=PIC16F877   ;
        INCLUDE     "P16f877.inc" ;標準ヘッダ定義ファイル
        __CONFIG    _HS_OSC & _PWRTE_ON & _WDT_OFF & _LVP_OFF 
 
;*********************************************
SWDT    EQU     020H            ;スイッチ読み込み
SWDTDIR EQU     021H            ;スイッチ正逆(最上位ビット)
SWDTSP  EQU     022H            ;スイッチ速度データ(3ビット)

TIMCNT  EQU     024H            ;タイマ用カウンタ
TIM2CNT EQU     025H
TIM5CNT EQU     026H
T200CNT EQU     027H

;***********************
;  メインルーチン
;***********************
        ORG     0               ;Reset Start
        GOTO    INIT

;*********************************************************
;初期処理
INIT
        BSF     STATUS,RP0      ;バンク1へ切替
        BCF     INTCON,GIE      ;割り込み禁止

        MOVLW   07H
        MOVWF   ADCON1          ;A/D用ピンをすべてデジタルI/Oに
        
        MOVLW   01H
        MOVWF   TRISA           ;とりあえずポートAをRA0入力、他は出力モード設定
                                ;今回は不使用
        MOVLW   0FFH
        MOVWF   TRISB           ;ポートBを入力モードに設定
        CLRF    TRISC           ;ポートCを出力モードに設定
                                ;CCP1(RC2),CCP2(RC1)ピンをPWMに使用するためには
                                ;出力に設定しておく必要がある
        CLRF    TRISD           ;とりあえずポートDを出力モードに設定
        CLRF    TRISE           ;とりあえずポートEを出力モードに設定
        
        MOVLW   0FFH
        MOVWF   PR2             ;タイマ2周期レジスタに0FFH
                                ;(プリスケーラ1で19.53kHz)
        BCF     STATUS,RP0      ;バンク0に戻す
        
        MOVLW   0CH
        MOVWF   CCP1CON
        MOVWF   CCP2CON         ;CCPモードセレクトをPWMモードに
                                ;(デューティ下位2ビットは0とする)
        CLRF    CCPR1L          ;初期デューティ0とする
        CLRF    CCPR2L
        
MAIN
        MOVF    PORTB,W         ;スイッチ読み込み
        ANDLW   0FH
        MOVWF   SWDT            ;スイッチデータ保存

        MOVWF   SWDTSP          ;このうち下位Bit2:0の3ビットが
        RLF     SWDTSP,F        ;デューティとして有効
        SWAPF   SWDTSP,F        ;  (Bit7:5に移動)

        MOVF    SWDTSP,W        ;方向ビットおよびCフラグの影響を
        ANDLW   0E0H            ;なくすため上位Bit7:5の3ビット
        MOVWF   SWDTSP          ;のみ有効にする(下位は0とみなす)
        
        MOVF    SWDT,W          ;スイッチデータのBit3を方向データとする
        MOVWF   SWDTDIR
        SWAPF   SWDTDIR,F
        RLF     SWDTDIR,F
        BC      REVERSE         ;1で逆転
        
FORWARD                         ;正転
        CLRF    CCPR2L
        MOVF    SWDTSP,W
        MOVWF   CCPR1L          ;デューティセット
        MOVLW   04H
        MOVWF   T2CON           ;プリスケール1でタイマ2ON
        
        GOTO    WAIT

REVERSE
        CLRF    CCPR1L
        MOVF    SWDTSP,W
        MOVWF   CCPR2L          ;デューティセット
        MOVLW   04H
        MOVWF   T2CON           ;プリスケール1でタイマ2ON
        
        GOTO    WAIT
        
WAIT    
        CALL    TIM200
        
        GOTO    MAIN

;************************************************************
;タイマ
TIM20                             ;約20μSECタイマ
        MOVLW   012H
        MOVWF   TIMCNT
TIMLP   
        DECFSZ  TIMCNT,F
        GOTO    TIMLP
        RETURN
TIM02                             ;約0.2mSECタイマ
        MOVLW   0FFH
        MOVWF   TIM2CNT
TIM2LP  NOP
        DECFSZ  TIM2CNT,F
        GOTO    TIM2LP
        RETURN
TIM5                              ;約5msecタイマ
        MOVLW   019H
        MOVWF   TIM5CNT
TIM5LP  CALL    TIM02
        DECFSZ  TIM5CNT,F
        GOTO    TIM5LP
        RETURN
TIM200                           ;0.2SECタイマ
        MOVLW   019H
        MOVWF   T200CNT
T200LP 
        CALL    TIM5
        DECFSZ  T200CNT,F
        GOTO    T200LP
        RETURN
;*********************************************************

        END