list p=16f877a ; PIC16F877A 用のプログラムであることを宣言 #include p16f877a.inc ; PIC16F877A 用のヘッダ・ファイルを読み込む __config _HS_OSC & _CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF CT_DELAY1MS equ 0x20 CT_DELAYN equ 0x21 PORTC_ equ 0x22 COUNT equ 0x23 TMP equ 0x24 MSG_LOOP equ 0x25 ANGLE equ 0x26 org 0x0 nop goto start org 0x4 retfie start ; 初期設定をする bcf STATUS, RP0 ; この2行でバンク0にする bcf STATUS, RP1 clrf INTCON ; 割り込み禁止 clrf PORTC ; LEDが点灯しない, サーボが動かないように0に clrf PORTD ; 出力は0にしておく clrf PORTE ; 出力は0にしておく bsf STATUS, RP0 ; バンク1にする movlw 0xff movwf TRISB ; ポートBはディジタル入力 movlw B'00000111' ; PORTBのウィーク・プルアップを有効に ; プリスケーラはタイマに割り当て ; プリスケーラは1/256にする movwf OPTION_REG clrf TRISC ; 全ピン出力に clrf TRISD ; 全ピン出力に bcf STATUS, RP0 ; バンク0にする movlw B'00100000' ; LED0は消灯LED1は点灯 movwf PORTC_ movwf PORTC movlw D'127' ; 最初のパルスの長さ1000+127×8=2016[us]=2[ms] movwf ANGLE ; 初期設定は終了 ; ここからメイン・ルーチン main bcf INTCON, T0IF ; フラグのクリア movlw D'61' ; 20[ms] タイマの設定 movwf TMR0 btfss COUNT, 0 goto DEC_COUNT ;; ANGLEから1を引いていく decf ANGLE, f movlw D'50' ; 50になったかチェック subwf ANGLE, w btfsc STATUS, Z bcf COUNT, 0 ; 50 の場合は反転 goto SERVO_PULSE ;; ANGLEに1を足していく DEC_COUNT incf ANGLE, f movlw D'200' ; 200になったかチェック subwf ANGLE, w btfsc STATUS, Z bsf COUNT, 0 ; 200の場合は反転 SERVO_PULSE ;; 一つ目のサーボのパルスを作る bsf PORTC_, 3 movfw PORTC_ movwf PORTC call delay1ms movfw ANGLE call delayn bcf PORTC_, 3 movfw PORTC_ movwf PORTC ;; 二つ目のサーボのパルスを作る bsf PORTC_, 4 movfw PORTC_ movwf PORTC call delay1ms movfw ANGLE call delayn bcf PORTC_, 4 movfw PORTC_ movwf PORTC btfss INTCON, T0IF ; 全体として20[ms]経過するのを待つ goto $-1 goto main delay10us: goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 nop ; 1 return ; 2 delay1ms: movlw D'89' ; 1 movwf CT_DELAY1MS ; 1 delay1msl1: call delay10us ; 25 decfsz CT_DELAY1MS, f ; 1(次の行を実行)、2(次の行はとばす) goto delay1msl1 ; 2 nop ; 1 goto $+1 ; 2 return ; 2 delayn: movwf CT_DELAYN movf CT_DELAYN, f btfsc STATUS, Z return delaynl1: goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 goto $+1 ; 2 nop ; 1 decfsz CT_DELAYN, f ; 1 goto delaynl1 ; 2 return end リスト6-1 Copyright 2005 Noriaki Mitsunaga