;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;プログラム1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 動作内容:LEDが点灯、消灯を繰り返す ; セミコロン”;”以降はコメントを表すのでキー入力は不要である。 LIST P=16F873A ;マイコンとしてPIC16F873Aの使用を規定(省略) INCLUDE P16F873A.INC ;ヘッダファイルP16F873A.INCの読み込み(省略) ;変数の定義(省略) CNT1 EQU H'20' ;時間のカウント用変数をメモリ番地H'20'に定義 CNT2 EQU H'21' ;時間のカウント用変数をメモリ番地H'21'に定義 CNT3 EQU H'22' ;時間のカウント用変数をメモリ番地H'22'に定義 TIME EQU H'23' ;時間を表す変数(0〜255):TIME=D'123'は12.3秒を表す ;LEDを使用するための準備(省略) CLRF PORTB ;全てのLEDを消灯 BSF STATUS,5 ;メモリのページを1に切替 MOVLW B'11000001' ; MOVWF TRISB ;マイコンからLEDへ信号が流れるように設定 BCF STATUS,5 ;メモリのページを0に戻す ;LEDの点灯、消灯の本体 LOOP MOVLW D'10' ;10進数の'10'をW(レジスタ)へ格納 MOVWF TIME ;Wの値を変数TIMEへ格納⇒タイマーを1秒(0.1秒×10)に設定 BSF PORTB,1 ;PORTBの下位1bit目に'1'を格納⇒LED1を点灯 CALL TIMER ;ラベルTIMERへ移動⇒1秒カウント ;;1;; BSF PORTB,2 ;LED2を点灯 CALL TIMER ;1秒カウント ;;2;; BSF PORTB,3 ;LED3を点灯 CALL TIMER ;1秒カウント ;;3;; BSF PORTB,4 ;LED4を点灯 CALL TIMER ;1秒カウント ;;4;; BSF PORTB,5 ;LED5を点灯 CALL TIMER ;1秒カウント ;;5;; BCF PORTB,1 ;PORTBの下位1bit目に'0'を格納⇒LED1を消灯 CALL TIMER ;1秒カウント ;;6;; BCF PORTB,2 ;LED2を消灯 CALL TIMER ;1秒カウント ;;7;; BCF PORTB,3 ;LED3を消灯 CALL TIMER ;1秒カウント ;;8;; BCF PORTB,4 ;LED4を消灯 CALL TIMER ;1秒カウント ;;9;; BCF PORTB,5 ;LED5を消灯 CALL TIMER ;1秒カウント ;;10;; GOTO LOOP ;ラベルLOOPへ移動 ;TIMEの値で決定される任意の時間を生成するためのサブルーチン(省略) TIMER MOVF TIME,W MOVWF CNT1 ; CNT1 = TIME LOOP1 MOVLW D'245' MOVWF CNT2 ; CNT2 = 245 LOOP2 MOVLW D'255' MOVWF CNT3 ; CNT3 = 255 LOOP3 NOP NOP NOP NOP NOP DECFSZ CNT3,F ;CNT3を1減算後,CNT3=0であれば次の命令をスキップ GOTO LOOP3 ;CNT3≠0の時に実行 DECFSZ CNT2,F ;CNT2を1減算後,CNT2=0であれば次の命令をスキップ GOTO LOOP2 ;CNT2≠0の時に実行 DECFSZ CNT1,F ;CNT1を1減算後,CNT1=0であれば次の命令をスキップ GOTO LOOP1 ;CNT1≠0の時に実行 RETURN ;TIME×0.1秒経過 END ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;プログラム2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;スイッチ検出:スイッチRA2はLED1〜4を点灯させ、スイッチRA4はLED5を点灯させる LIST P=16F873A ;マイコンとしてPIC16F873Aの使用を規定(省略) INCLUDE P16F873A.INC ;ヘッダファイルP16F873A.INCの読み込み(省略) ;スイッチRA2とRA4を使用するための準備(省略) BSF STATUS,5 ;メモリのページを1に切替 MOVLW B'00000100' MOVWF ADCON1 ;スイッチRA2とRA4をディジタルポートに指定 MOVLW B'011111' MOVWF TRISA ;スイッチRA2とRA4からマイコンへ信号が流れるように設定 ;LEDを使用するための準備(省略) MOVLW B'11000001' MOVWF TRISB ;マイコンからLEDへ信号が流れるように設定 BCF STATUS,5 ;メモリのページを0に戻す ;スイッチ検出の本体;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CLRF PORTB ;PORTBの全bitに'0'を格納⇒全てのLEDを消灯 LOOP BTFSS PORTA,2 ;RORTA(2)=1(スイッチRA2がOFF)ならば次の命令をスキップ GOTO RA2ON ;スイッチRA2がONの時に実行 BCF PORTB,1 ;LED1を消灯 BCF PORTB,2 ;LED2を消灯 BCF PORTB,3 ;LED3を消灯 BCF PORTB,4 ;LED4を消灯 BTFSS PORTA,4 ;RORTA(4)=1(スイッチRA4がOFF)ならば次の命令をスキップ GOTO RA4ON ;スイッチRA4がONの時に実行 BCF PORTB,5 ;LED5を消灯 GOTO LOOP RA2ON BSF PORTB,1 ;LED1を点灯 BSF PORTB,2 ;LED2を点灯 BSF PORTB,3 ;LED3を点灯 BSF PORTB,4 ;LED4を点灯 GOTO LOOP RA4ON BSF PORTB,5 ;LED5を点灯 GOTO LOOP END ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;プログラム3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;スイッチ検出:RA2が押された瞬間だけLEDを点灯する(RA2を押し続けても点灯は続かない) LIST P=16F873A ;マイコンとしてPIC16F873Aの使用を規定(省略) INCLUDE P16F873A.INC ;ヘッダファイルP16F873A.INCの読み込み(省略) ;変数の定義(省略) CNT1 EQU H'20' ;時間のカウント用変数をメモリ番地H'20'に定義 CNT2 EQU H'21' ;時間のカウント用変数をメモリ番地H'21'に定義 CNT3 EQU H'22' ;時間のカウント用変数をメモリ番地H'22'に定義 TIME EQU H'23' ;時間を表す変数(0〜255):TIME=D'123は12.3秒を表す ;スイッチRA2とRA4を使用するための準備(省略) BSF STATUS,5 ;メモリのページを1に切替 MOVLW B'00000100' MOVWF ADCON1 ;スイッチRA2とRA4をディジタルポートに指定 MOVLW B'011111' MOVWF TRISA ;スイッチRA2とRA4からマイコンへ信号が流れるように設定 ;LEDを使用するための準備(省略) MOVLW B'11000001' MOVWF TRISB ;マイコンからLEDへ信号が流れるように設定 BCF STATUS,5 ;メモリのページを0に戻す ;スイッチ検出の本体 LOOP BTFSS PORTA,2 ;RORTA(2)=1(スイッチRA2がOFF)ならば次の命令をスキップ GOTO LOOP ;スイッチRA2がONの時に実行 CHK2 BTFSS PORTA,2 ;RORTA(2)=1(スイッチRA2がOFF)ならば次の命令をスキップ GOTO LEDON ;スイッチRA2がONの時に実行 GOTO CHK2 LEDON MOVLW B'111110' ;B'110110'と変更した時の動作を確認せよ MOVWF PORTB ;全てのLEDを点灯 MOVLW D'5' MOVWF TIME ;タイマーを0.5秒(0.1秒×5)に設定 CALL TIMER CLRF PORTB ;全てのLEDを消灯 GOTO LOOP ;TIMEの値で決定される任意の時間を生成するためのサブルーチン(省略) TIMER MOVF TIME,W MOVWF CNT1 ; CNT1 = TIME LOOP1 MOVLW D'245' MOVWF CNT2 ; CNT2 = 245 LOOP2 MOVLW D'255' MOVWF CNT3 ; CNT3 = 255 LOOP3 NOP NOP NOP NOP NOP DECFSZ CNT3,F ;CNT3を1減算後,CNT3=0であれば次の命令をスキップ GOTO LOOP3 ;CNT3≠0の時に実行 DECFSZ CNT2,F ;CNT2を1減算後,CNT2=0であれば次の命令をスキップ GOTO LOOP2 ;CNT2≠0の時に実行 DECFSZ CNT1,F ;CNT1を1減算後,CNT1=0であれば次の命令をスキップ GOTO LOOP1 ;CNT1≠0の時に実行 RETURN ;TIME×0.1秒経過 END ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;プログラム4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;スイッチ検出:スイッチRA2を押し続けるとLEDの点滅間隔が徐々に短くなり、RA4が押されると点滅間隔が初期値に戻る。RA2とRA4を同時に押しても点滅間隔は初期値に戻る。 LIST P=16F873A ;マイコンとしてPIC16F873Aの使用を規定(省略) INCLUDE P16F873A.INC ;ヘッダファイルP16F873A.INCの読み込み(省略) ;変数の定義(省略) CNT1 EQU H'20' ;時間のカウント用変数をメモリ番地H'20'に定義 CNT2 EQU H'21' ;時間のカウント用変数をメモリ番地H'21'に定義 CNT3 EQU H'22' ;時間のカウント用変数をメモリ番地H'22'に定義 TIME EQU H'23' ;時間を表す変数(0〜255):TIME=D'10'は50m秒を表す INIT EQU H'24' ;点滅間隔の初期値を表す変数(0〜255) ;スイッチRA2とRA4を使用するための準備(省略) BSF STATUS,5 ;メモリのページを1に切替 MOVLW B'00000100' MOVWF ADCON1 ;スイッチRA2とRA4をディジタルポートに指定 MOVLW B'011111' MOVWF TRISA ;スイッチRA2とRA4からマイコンへ信号が流れるように設定 ;LEDを使用するための準備(省略) MOVLW B'11000001' MOVWF TRISB ;マイコンからLEDへ信号が流れるように設定 BCF STATUS,5 ;メモリのページを0に戻す ;スイッチ検出の本体;;;;;;;;;;;;;;;;;;;; MOVLW D'200' MOVWF INIT ;点滅間隔の初期値を約1秒(200×5m秒)に設定 MOVWF TIME ;TIME=INIT LOOP BSF PORTB,1 ;LED1を点灯 CALL RA2 ;スイッチRA2の監視 CALL RA4 ;スイッチRA4の監視 CALL TIMER ;TIME×5m秒カウント BSF PORTB,2 ;LED2を点灯 CALL RA2 CALL RA4 CALL TIMER ;TIME×5m秒カウント BSF PORTB,3 ;LED3を点灯 CALL RA2 CALL RA4 CALL TIMER ;TIME×5m秒カウント BSF PORTB,4 ;LED4を点灯 CALL RA2 CALL RA4 CALL TIMER ;TIME×5m秒カウント BSF PORTB,5 ;LED5を点灯 CALL RA2 CALL RA4 CALL TIMER ;TIME×5m秒カウント BCF PORTB,5 ;LED5を消灯 CALL RA2 CALL RA4 CALL TIMER ;TIME×5m秒カウント BCF PORTB,4 ;LED4を消灯 CALL RA2 CALL RA4 CALL TIMER ;TIME×5m秒カウント BCF PORTB,3 ;LED3を消灯 CALL RA2 CALL RA4 CALL TIMER ;TIME×5m秒カウント BCF PORTB,2 ;LED2を消灯 CALL RA2 CALL RA4 CALL TIMER ;TIME×5m秒カウント BCF PORTB,1 ;LED1を消灯 CALL RA2 CALL RA4 CALL TIMER ;TIME×5m秒カウント GOTO LOOP ;スイッチRA2の状態を管理 RA2 BTFSC PORTA,2 ;RORTA(2)=0(スイッチRA2がON)ならば次の命令をスキップ RETURN DECFSZ TIME,F ;TIME=TIME-1, この結果TIME=0となれば次の命令をスキップ RETURN INCF TIME,F ;TIME+1の値をTIMEへ格納⇒TIMEの最小値は1 RETURN ;スイッチRA4の状態を管理 RA4 BTFSC PORTA,4 ;RORTA(4)=0(スイッチRA4がON)ならば次の命令をスキップ RETURN MOVF INIT,W MOVWF TIME ;TIME=INIT RETURN ;TIMEの値で決定される任意の時間を生成するためのサブルーチン(省略) TIMER MOVF TIME,W MOVWF CNT1 ; CNT1 = TIME LOOP1 MOVLW D'25' MOVWF CNT2 ; CNT2 = 25 LOOP2 MOVLW D'249' MOVWF CNT3 ; CNT3 = 249 LOOP3 NOP DECFSZ CNT3,F ;CNT3を1減算後,CNT3=0であれば次の命令をスキップ GOTO LOOP3 ;CNT3≠0の時に実行 DECFSZ CNT2,F ;CNT2を1減算後,CNT2=0であれば次の命令をスキップ GOTO LOOP2 ;CNT2≠0の時に実行 DECFSZ CNT1,F ;CNT1を1減算後,CNT1=0であれば次の命令をスキップ GOTO LOOP1 ;CNT1≠0の時に実行 RETURN ;TIME×5m秒経過 END ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;プログラム5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;モーター回転テスト:スイッチRA2を押すと低速回転、RA4を押すと高速回転 LIST P=16F873A ;マイコンとしてPIC16F873Aの使用を規定(省略) INCLUDE P16F873A.INC ;ヘッダファイルP16F873A.INCの読み込み(省略) ;スイッチRA2とRA4を使用するための準備(省略) BSF STATUS,5 ;メモリのページを1に切替(bank1) MOVLW B'00000100' MOVWF ADCON1 ;スイッチRA2とRA4をディジタルポートに指定 MOVLW B'011111' MOVWF TRISA ;スイッチRA2とRA4からマイコンへ信号が流れるように設定 ;左右のモーターを使用するための準備(省略) MOVLW B'10000000' MOVWF TRISC ;マイコンから左右のモーターへ信号が流れるように設定 BCF STATUS,5 ;メモリのページを0に戻す(bank0) ;左右のモーターの回転速度を調節するための準備(省略) CLRF CCPR1L ;左モーターの回転速度=0 CLRF CCPR2L ;右モーターの回転速度=0 MOVLW B'1100' MOVWF CCP1CON ;左モーターへの信号の変調方式をPWMに設定 MOVWF CCP2CON ;右モーターへの信号の変調方式をPWMに設定 MOVLW D'255' MOVWF PR2 ;PR2=モーターの最大回転数 MOVLW B'110' MOVWF T2CON ;PWMの周波数を設定 ;モーター回転テストの本体 LOOP BTFSS PORTA,2 ;スイッチRA2がOFFの時は次の命令をスキップ GOTO LOW1 ;ONの時、L1にジャンプ BTFSS PORTA,4 ;スイッチRA4がOFFの時は次の命令をスキップ GOTO HIGH1 ;ONの時、L2にジャンプ CLRF CCPR1L ;左モーターの回転速度=0 CLRF CCPR2L ;右モーターの回転速度=0 GOTO LOOP ;低速回転 LOW1 MOVLW D'20' MOVWF CCPR1L ;左モーターの回転速度=20 MOVWF CCPR2L ;右モーターの回転速度=20 GOTO LOOP ;(モーターの破損防止のため速度を50以上にしないこと) ;速度不足で回転しない場合は速度を+3刻み程度ずつ徐々に増加させること ;高速回転 HIGH1 MOVLW D'30' MOVWF CCPR1L ;左モーターの回転速度=30 MOVWF CCPR2L ;右モーターの回転速度=30 GOTO LOOP ;(モーターの破損防止のため速度を50以上にしないこと) ;高速と低速の違いが確認できるように高速の値を設定すること END ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;プログラム6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;直線走行:スイッチRA2を押すと4秒間低速走行し、RA4を押すと4秒間高速走行する LIST P=16F873A ;マイコンとしてPIC16F873Aの使用を規定(省略) INCLUDE P16F873A.INC ;ヘッダファイルP16F873A.INCの読み込み(省略) ;変数定義(省略) CNT1 EQU H'20' ;タイムカウント用変数(1〜255) CNT2 EQU H'21' ;タイムカウント用変数(1〜255) CNT3 EQU H'22' ;タイムカウント用変数(1〜255) TIME EQU H'23' ;タイマー設定時間用変数(1〜255) ;スイッチRA2とRA4を使用するための準備(省略) BSF STATUS,5 ;メモリのページを1に切替(bank1) MOVLW B'00000100' MOVWF ADCON1 ;スイッチRA2とRA4をディジタルポートに指定 MOVLW B'011111' MOVWF TRISA ;スイッチRA2とRA4からマイコンへ信号が流れるように設定 ;左右のモーターを使用するための準備(省略) MOVLW B'10000000' MOVWF TRISC ;マイコンから左右のモーターへ信号が流れるように設定 BCF STATUS,5 ;メモリのページを0に戻す(bank0) ;左右のモーターの回転速度を調節するための準備(省略) CLRF CCPR1L ;左モーターの回転速度=0 CLRF CCPR2L ;右モーターの回転速度=0 MOVLW B'1100' MOVWF CCP1CON ;左モーターへの信号の変調方式をPWMに設定 MOVWF CCP2CON ;右モーターへの信号の変調方式をPWMに設定 MOVLW D'255' MOVWF PR2 ;PR2=モーターの最大回転数 MOVLW B'110' MOVWF T2CON ;PWMの周波数を設定 ;直線走行の本体;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MOVLW D'40' MOVWF TIME ;タイマーを4秒(=40×0.1秒)に設定 LOOP BTFSS PORTA,2 ;スイッチRA2がOFFの時は次の命令をスキップ GOTO LOW1 ;ONの時にL1にジャンプ BTFSS PORTA,4 ;スイッチRA4がOFFの時は次の命令をスキップ GOTO HIGH1 ;ONの時にL2にジャンプ CLRF CCPR1L ;左モーターの回転速度=0 CLRF CCPR2L ;右モーターの回転速度=0 GOTO LOOP ;低速直線走行 LOW1 MOVLW D'20' MOVWF CCPR1L ;左モーターの回転速度=20 MOVWF CCPR2L ;右モーターの回転速度=20 CALL TIMER ;サブルーチンTIMERの呼び出し GOTO LOOP ;(モーターの破損防止のため速度を50以上にしないこと) ;速度不足で回転しない場合は速度を+3刻み程度ずつ徐々に増加させること ;高速直線走行 HIGH1 MOVLW D'30' MOVWF CCPR1L ;左モーターの回転速度=30 MOVWF CCPR2L ;右モーターの回転速度=30 CALL TIMER ;(モーターの破損防止のため速度を50以上にしないこと) GOTO LOOP ;高速と低速の違いが確認できるように高速の値を設定すること ;TIMEの値で決定される任意の時間を生成するためのサブルーチン(省略) TIMER MOVF TIME,W MOVWF CNT1 ; CNT1 = TIME LOOP1 MOVLW D'245' MOVWF CNT2 ; CNT2 = 245 LOOP2 MOVLW D'255' MOVWF CNT3 ; CNT3 = 255 LOOP3 NOP NOP NOP NOP NOP DECFSZ CNT3,F ;CNT3を1減算後,CNT3=0であれば次の命令をスキップ GOTO LOOP3 ;CNT3≠0の時に実行 DECFSZ CNT2,F ;CNT2を1減算後,CNT2=0であれば次の命令をスキップ GOTO LOOP2 ;CNT2≠0の時に実行 DECFSZ CNT1,F ;CNT1を1減算後,CNT1=0であれば次の命令をスキップ GOTO LOOP1 ;CNT1≠0の時に実行 RETURN ;TIME×0.1秒経過 END ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;プログラム7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Uターン走行:スイッチRA2を押すとUターン走行する LIST P=16F873A ;マイコンとしてPIC16F873Aの使用を規定(省略) INCLUDE P16F873A.INC ;ヘッダファイルP16F873A.INCの読み込み(省略) ;変数定義(省略) CNT1 EQU H'20' ;タイマーカウント用変数(1〜255) CNT2 EQU H'21' ;タイマーカウント用変数(1〜255) CNT3 EQU H'22' ;タイマーカウント用変数(1〜255) TIME EQU H'23' ;走行時間を表す変数(1〜255) ;スイッチRA2とRA4を使用するための準備(省略) BSF STATUS,5 ;メモリのページを1に切替(bank1) MOVLW B'00000100' MOVWF ADCON1 ;スイッチRA2とRA4をディジタルポートに指定 MOVLW B'011111' MOVWF TRISA ;スイッチRA2とRA4からマイコンへ信号が流れるように設定 ;左右のモーターを使用するための準備(省略) MOVLW B'10000000' MOVWF TRISC ;マイコンから左右のモーターへ信号が流れるように設定 BCF STATUS,5 ;メモリのページを0に戻す(bank0) ;左右のモーターの回転速度を調節するための準備(省略) CLRF CCPR1L ;左モーターの回転速度=0 CLRF CCPR2L ;右モーターの回転速度=0 MOVLW B'1100' MOVWF CCP1CON ;左モーターへの信号の変調方式をPWMに設定 MOVWF CCP2CON ;右モーターへの信号の変調方式をPWMに設定 MOVLW D'255' MOVWF PR2 ;PR2=モーターの最大回転速度 MOVLW B'110' MOVWF T2CON ;PWMの周波数を設定 ;Uターン走行の本体;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LOOP BTFSS PORTA,2 ;スイッチRA2がOFFの時は次の命令をスキップ GOTO RUN ;ONの時、RUNにジャンプ CLRF CCPR1L ;左モーターの回転速度=0 CLRF CCPR2L ;右モーターの回転速度=0 GOTO LOOP RUN MOVLW D'30' MOVWF TIME ;走行時間=3秒 CALL STR ;直線走行のサブルーチンを呼び出し ; MOVLW D'23' MOVWF TIME ;走行時間=2.3秒 CALL ROT ;カーブ走行のサブルーチンを呼び出し ; MOVLW D'30' MOVWF TIME ;走行時間=3秒 CALL STR ;直線走行のサブルーチンを呼び出し ; GOTO LOOP ;直線走行サブルーチン;;;;;;;;;;;;;;;; STR MOVLW D'30' MOVWF CCPR1L ;左モーターの回転速度=30 MOVLW D'30' ;(モーターの破損防止のため速度を50以上にしないこと) MOVWF CCPR2L ;右モーターの回転速度=30 CALL TIMER ;タイマーの呼び出し RETURN ;左右の回転速度の値は直線走行の課題で正確に調整した値を ;用いるのが望ましい ;カーブ走行サブルーチン;;;;;;;;;;;;;;; ROT MOVLW D'30' MOVWF CCPR1L ;左モーターの回転速度=30 MOVLW D'20' ;(モーターの破損防止のため速度を50以上にしないこと) MOVWF CCPR2L ;左モーターの回転速度=20 CALL TIMER ;タイマーの呼び出し RETURN ;TIMEの値で決定される任意の時間を生成するためのサブルーチン(省略) TIMER MOVF TIME,W MOVWF CNT1 ; CNT1 = TIME LOOP1 MOVLW D'245' MOVWF CNT2 ; CNT2 = 245 LOOP2 MOVLW D'255' MOVWF CNT3 ; CNT3 = 255 LOOP3 NOP NOP NOP NOP NOP DECFSZ CNT3,F ;CNT3を1減算後,CNT3=0であれば次の命令をスキップ GOTO LOOP3 ;CNT3≠0の時に実行 DECFSZ CNT2,F ;CNT2を1減算後,CNT2=0であれば次の命令をスキップ GOTO LOOP2 ;CNT2≠0の時に実行 DECFSZ CNT1,F ;CNT1を1減算後,CNT1=0であれば次の命令をスキップ GOTO LOOP1 ;CNT1≠0の時に実行 RETURN ;TIME×0.1秒経過 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; END ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;プログラム8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;赤外線センサを用いたライントレース走行:黒いラインをトレースしながら走行 ;課題1:正確にトレースするようにモータの回転速度とタイマ設定時間を調整し、調整値及び本体プログラムのフローチャートをレポートに記載せよ※。 ;※プログラム中で(省略)と記された部分の記載は省略して構わない LIST P=16F873A ;マイコンとしてPIC16F873Aの使用を規定(省略) INCLUDE P16F873A.INC ;ヘッダファイルP16F873A.INCの読み込み(省略) ;変数定義(省略) TIME EQU H'20' ;タイマ設定時間(1〜255) CNT EQU H'21' ;タイムカウント用変数 ONOFF EQU H'22' ;左右の赤外線センサに発生する光電流の測定値(0or1)を格納 ;スイッチRA2とRA4を使用するための準備(省略) START CLRF PORTB BSF STATUS,5 ;メモリのページ(bank)を1に切替 MOVLW 7 MOVWF ADCON1 ;スイッチRA2, RA4を含む全てのポートAをディジタルポートに指定 MOVLW B'011111' MOVWF TRISA ;スイッチRA2とRA4からマイコンへ信号が流れるように設定 ;LEDを使用するための準備(省略) MOVLW B'11000001' MOVWF TRISB ;マイコンからLEDへ信号が流れるように設定 ;左右のモータ、赤外線センサを使用するための準備(省略) MOVLW B'11111001' MOVWF TRISC ;赤外線センサからマイコンに信号が流れ、マイコンから左右の ;モーターへ信号が流れるように設定 BCF STATUS,5 ;メモリのページ(bank)を0に戻す ;左右のモーターの回転速度を調節するための準備(省略) CLRF CCPR1L ;左モーターの回転速度=0 CLRF CCPR2L ;右モーターの回転速度=0 MOVLW B'1100' MOVWF CCP1CON ;左モーターへの信号の変調方式をPWMに設定 MOVWF CCP2CON ;右モーターへの信号の変調方式をPWMに設定 MOVLW D'255' MOVWF PR2 ;PR2=モーターの最大回転速度 MOVLW B'110' MOVWF T2CON ;PWMの周波数を設定 ;ライントレース走行の本体;;;;;;;;;;;;;;;;;;;;;; MOVLW D'30' MOVWF TIME ;タイマを48μ秒(30×1.6μ秒)に設定 BSF PORTB,5 ;LED5を点灯 WAIT CALL IRCHK ;赤外線センサの感度をチェック BTFSC PORTA,2 ;スイッチRA2がONの時は次の命令をスキップ GOTO WAIT ;RA2がOFFの時に実行 LOOP BTFSS PORTA,4 ;スイッチRA4がOFFの時は次の命令をスキップ GOTO START ;RA4がONの時に実行 MOVF PORTC,W ;赤外線センサに発生する光電流を測定 MOVWF ONOFF ;左右のセンサの光電流測定値(0or1)をONOFFの ;4bit目(左センサ), 5bit目(右センサ)に格納 BTFSC ONOFF,4 ;左のセンサが暗い面を検出したら(ONOFF(4)=0)、次の命令をスキップ GOTO CHK5 ;左のセンサが明るい面を検出した時に実行 BTFSC ONOFF,5 ;右のセンサが暗い面を検出したら(ONOFF(5)=0)、次の命令をスキップ GOTO ROTL ;右のセンサが明るい面を検出した時に実行 ;以下は左右2つのセンサが共に暗い面を検出した時の処理 CLRF PORTB ;LEDを全て消灯 BSF PORTB,5 ;LED5を点灯 CLRF CCPR1L ;左モーターの回転速度=0 CLRF CCPR2L ;右モーターの回転速度=0 GOTO START CHK5 BTFSC ONOFF,5 ;右のセンサが暗い面を検出したら(ONOFF(5)=0)、次の命令をスキップ GOTO STR ;右のセンサも明るい面を検出した時に実行 GOTO ROTR ;直線走行(左:明、右:明);;;;;;;;;;;;;;;;;;;;;; STR CLRF PORTB ;LEDを全て消灯 BSF PORTB,2 ;LED2を点灯 BSF PORTB,3 ;LED3を点灯 MOVLW D'30' MOVWF CCPR1L ;左モーターの回転速度=30 MOVLW D'30' ;(モーターの破損防止のため速度を50以上にしないこと) MOVWF CCPR2L ;右モーターの回転速度=30 GOTO LOOP ;左右の回転速度の値は直線走行の課題で正確に調整した値を ;用いるのが望ましい ;右カーブ走行(左:明、右:暗);;;;;;;;;;;;;; ROTR CLRF PORTB ;LEDを全て消灯 BSF PORTB,2 ;LED2を点灯 MOVLW D'30' MOVWF CCPR1L ;左モーターの回転速度=30 MOVLW D'20' ;(モーターの破損防止のため速度を50以上にしないこと) MOVWF CCPR2L ;右モーターの回転速度=20 CALL TIMER ;タイマー呼び出し GOTO LOOP ;左カーブ走行(左:暗、右:明);;;;;;;;;;;;;;; ROTL CLRF PORTB ;LEDを全て消灯 BSF PORTB,3 ;LED3を点灯 MOVLW D'30' MOVWF CCPR2L ;右モーターの回転速度=30 MOVLW D'20' ;(モーターの破損防止のため速度を50以上にしないこと) MOVWF CCPR1L ;左モーターの回転速度=20 CALL TIMER ;タイマー呼び出し GOTO LOOP ;TIME×1.6μ秒のタイマーサブルーチン(省略);;;;;; TIMER MOVF TIME,W MOVWF CNT DLY NOP NOP NOP NOP NOP DECFSZ CNT,F ;CNTを1減算後、CNT=0ならば次の命令をスキップ GOTO DLY ;CNT≠0の時に実行 RETURN ;TIME×1.6μ秒経過 ;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;赤外線センサの感度チェック用サブルーチン ;明るい面を検出したらLEDを点灯し、暗い面を検出したらLEDを消灯する IRCHK BTFSC PORTC,4 ;赤外線センサ左が暗い面を検出したら次の命令をスキップ GOTO L2ON ;左のセンサが明るい面を検出した時に実行 BCF PORTB,2 ;LED2を消灯(左側:暗い) CHKL BTFSC PORTC,5 ;赤外線センサ右が暗い面を検出したら次の命令をスキップ GOTO L3ON ;右のセンサが明るい面を検出した時に実行 BCF PORTB,3 ;LED3を消灯(右側:暗い) RETURN L2ON BSF PORTB,2 ;LED2を点灯(左側:明るい) GOTO CHKL L3ON BSF PORTB,3 ;LED3を点灯(右側:明るい) RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; END