제가 PIC16F84를 이용하여 미니라인트레이서를 만들려합니다.
기존 라인과는 조금 다른것은 4바퀴에 모두 모터를 달고 각각 독립적으로 제어를 할려고 합니다.
두바퀴제어하는 미니라인트레이서의 경우는 수광센서신호를 RB4~RB7 포트로 받아 PORT B가 변화때 인터럽트를 사용하고 RA0~RA3를 좌우모터 각각을 제어하도록 되어있더군요.
제가 궁금한 것은 저는 이를 응용해서 RA0~RA4로 광센서신호를 받아 RA0~RB7을 이용해 4바퀴를 모두 각각 독립적으로 제어했으면 하는데 이게 가능한지요? 소위 PORT A 변화인터럽트라는 것은 없는지요? 만약 가능하다면 어찌해야 하는지 알려주십시요..
A port에 모터 두 개 4선을 연결하여 출력 포트로 하고 B port의 4,5,6,7번 포트를 센서입력으로 해서 B port 4,5,6,7 의 신호가 변화하면 걸리는 인터럽트 기능을 사용합니다. 센서로 부터 정보가 바뀌면 인터럽트가 걸리고 인터럽트가 걸릴 때 마다 포트A 출력 값과 출력되는 시간이 바뀌게 됩니다.
예를 들어 오른쪽 센서가 라인을 감지한 경우, 이 경우는 로봇이 왼쪽으로 가장 많이 벗어난 경우가 됩니다. 왼쪽 모터는 빠르게, 오른쪽 모터는 느리게 동작해야 합니다. 10msec를 주기로 왼쪽 모터는 10msec 동안 그리고 오른쪽 모터는 5msec 동안 동작시키면 빠르게 오른쪽으로 방향을 바꾸겠지요. 다음은 C언어로 작성한 프로그램입니다. 컴파일러는 CCS-C입니다.
#include <16f84.h>
#byte PORTA=5 //포트A 레지스터 주소
#byte PORTB=6 //포트B 레지스터 주소
#byte INTCON=0xb //인터럽트 콘트롤 레지스터 주소
#byte TRISA=0x85 //포트A 입출력 설정 레지스터 주소
#byte TRISB=0x86 //포트B 입출력 설정 레지스터 주소
#use delay (clock=4000000) //크리스탈 주파수 4MHz
int pwm_index, motor_control; //전역변수 선언
#INT_RB //포트B 변화 인터럽트 사용 선언, 이 선언 뒤에 오는 함수가 인터럽트 서비스 루틴이 된다.
void rb_isr() //인터럽트 서비스 함수
{
int i;
i=PORTB;
switch(i){
case 0b00000000: //3개 센서가 모두 라인을 인식한 경우
case 0b01110000: //3개 센서 모두 라인을 인식하지 못한 경우
case 0b00100000: //좌,우측 센서가 라인을 인식한 경우
break; //위 세 경우는 현재 동작에 변화 없음
case 0b01010000: //중앙 센서가 라인을 인식한 경우
pwm_index=0;
motor_control=0xa;
break;
case 0b00110000: //좌측 센서가 라인 인식
pwm_index=2;
motor_control=0x2;
break;
case 0b00010000: //좌측, 중앙 센서가 라인 인식
pwm_index=1;
motor_control=0x2;
break;
case 0b01100000: //우측 센서 라인 인식
pwm_index=2;
motor_control=0x8;
break;
case 0b01000000: //중앙, 우측 센서 라인 인식
pwm_index=1;
motor_control=0x8;
break;
}
}
void main()
{
TRISA=0b00000000; //포트A를 모두 출력으로 설정
TRISB=0b11111111; //포트B를 모두 입력으로 설정
INTCON=0b10001000; //'포트B 변화 인터럽트' 인에이블 설정(GBIE=1, RBIE=1)
pwm_index=10;
motor_control=0x00;
while(1){ //무한 루프
PORTA=0xa; //좌,우 모터 모두 ON
delay_ms(10-pwm_index);
PORTA=motor_control; //좌 or 우 or 좌,우 모터 동작
delay_ms(pwm_index);
}
}
< 출처: >http://chanhak.com.ne.kr/>