BASIC4MCU | 질문게시판 | 답변 : RC카, 초음파를 이용하여 자율주행 질문입니다!
페이지 정보
작성자 master 작성일2020-09-10 05:42 조회9,658회 댓글3건
https://www.basic4mcu.com/bbs/board.php?bo_table=gac&wr_id=13348
작성일
작성일
본문
//// dist[1]--왼쪽 초음파// dist[0]--가운데 초음파// dist[4]--오른쪽 초음파//volatile char sensor=0; // 초기값 검출안됨(직진)//ISR(INT0_vect){if(EICRA==0x03)start=TCNT1;else{end=TCNT1; buf[0]=end-start; EIMSK=0;if(buf[0]<588)sensor|=2; else sensor&=~2; // 가운데}EICRA^=0x01;}//ISR(INT1_vect){if(EICRA==0x0C)start=TCNT1;else{end=TCNT1; buf[1]=end-start; EIMSK=0;if(buf[1]<588)sensor|=4; else sensor&=~4; // 왼쪽flag[1]=1;}EICRA^=0x04;}//ISR(INT4_vect){if(EICRB==0x03)start=TCNT1;else{end=TCNT1; buf[4]=end-start; EIMSK=0;if(buf[4]<588)sensor|=1; else sensor&=~1; // 오른쪽}EICRB^=0x01;}//int main(void){char val=0;DDRE=0x00; //echoDDRA=0xFF; //trigDDRG=0xFF;DDRB=0xFF; //motorTCCR1B=0x0A; OCR1A=59999; TIMSK=0x10; //8000000/8/(1+59999)=16.666Hz=60ms CTC/OCR1Atimer0_init();timer2_init();USART0_Init(MYUBRR);USART1_Init(MYUBRR);SREG=0x80;while(1){_delay_ms(200);SREG&=~0x80; val=sensor; SREG|=0x80;//switch(val){case 0b000: Go_Straight(); break; //000 전진case 0b100: case 0b010: case 0b110:Back(); _delay_ms( 500); Stop(); _delay_ms(100); Turn_Right(); _delay_ms(500); Stop(); //100 우회전 왼쪽 장애물break;default:Back(); _delay_ms( 500); Stop(); _delay_ms(100); Turn_Left(); _delay_ms(500); Stop(); //001 좌회전 오른쪽 장애물break;}}}
10cm면 588이죠?
외부인터럽트와 메인문을 조금 수정해서 스위치 문장으로 변경 해둡니다.
댓글 3
조회수 9,658seojc님의 댓글
seojc 작성일
와 감사합니다... 저도 if문이 잘 되지않아 switch문으로 짜기 도전해보았는데 잘 안되었는데 이런식으로 짜는건 생각도 못했네요 ..
SREG&=~0x80; SREG|=0x80; 혹시 여기서 인터럽트를 일부러 끄고 키시는 이유가 따로 있으신가요??
정말 감사합니다 마스터님!!
seojc님의 댓글
seojc
* 질문 글에 답변해 주신 답글 중 실수보다 정수일 때 mcu가 계산을 더 빨리한다고 말씀하신 거는 꿀 팁인 거 같아요 감사합니다 몰랐어요,,
master님의 댓글
master
SREG&=~0x80; val=sensor; SREG|=0x80;
sensor 값을 그대로 사용할 수도 있지만
중간에 인터럽트가 걸리면 sensor값이 변경될 수도 있으므로 val 변수에 값을 복사해서 사용하는 것이며
복사하는 도중에 인터럽트가 걸리지 않도록 인터럽트를 금지하고
복사한 후에 인터럽트를 해제하고 있습니다.
인터럽트 주기가 짧거나, (2바이트 또는 4바이트 형처럼) 데이터형이 큰 경우 복사하는 도중에 인터럽트가 발생해서 엉뚱한 값으로 복사되는 확률이 증가하게 됩니다.