안녕하세요,^^ 대학교3학년인 한 여학생입니다.. 제가 프로그램쪽에 지식이 많이 부족해서 도움을 얻고자 이렇게 글을 올려여~
제가 초음파센서를 이용해서 거리에따른 led를 켜지게하는 소스를 짜고있는데
현재 컴파일을 하면 오류는 나지않고
인터럽트 부분에 있는 else PORTC = 0x01 부분만 atmega128에서 작동하고있으며 srf04에는 두두두.. 하는 미세한 소리가 나고 있습니다.
트리거신호는 제대로 작동하는 것 같아요.
if문을 사용해서 5cm에서 10 cm 안에 물체가있으면 PORTC가 0x02로 되게 해놨는데 반응이 없고 else 문에 있는 0x01만 실행됩니다.
같은 인터럽트 내에 있는 것인데... 왜 else문만 돌까요...
거리계산도 맞는것 같고한데... 몇일째 이것때문에 밤을 새고있어요...ㅠ
전체적인 소스 설명은..
1. 트리거 신호를 10us만큼 보낸 후 그 때 부터 타이머 카운트를 시작하여 59us마다 SIGNAL(SIG_OVERFLOW0) 함수를 실행하여 count 변수
를 하나씩 올림. srf04의 경우 59us가 1cm이기 때문에...count값 자체가 물체와의 거리 cm값이 됨.
2. 외부 인터럽트를 사용하여 에코 신호가 상승엣지에서 하강엣지로 바뀌면 지금까지 잰 count값을 length에 넣음.
3. length 값을 이용하여 5cm에서 10cm 사이이에 물체의 유무에 따라 led 제어.
이렇게 나눌 수 있습니다.
밑에 소스에서 잘못된 부분좀 알려주세요..............
==============================================================================================
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/delay.h>
volatile unsigned int count; //count는 1cm마다 증가하는 변수. 즉, count 값이 곧 물체와의 거리이다.
volatile unsigned int length; //거리를 저장 할 변수
void delay(int dly)
{
while(dly--){
int i,n;
for(i=0;i<50;i++){
n=600;
while(n--);
}
}
}
// ATmega128은 2개의 8비트 타이머 / 카운터 0과 2 를 가지고 2개의 16비트 타이머/카운터 1과3을 가짐.
SIGNAL(SIG_OVERFLOW0)//타이머 0번 인터럽트 함수부분.
{
TCNT0 = 0x8b; //138; //(1/16us)*8분주*(256-138) =59us 마다 인터럽트를 발생 0x8a
count++; //cm 단위 srf04의 경우 59us가 1cm 이다 타이머 카운터0 레지스터 (읽기 쓰기가 가능) // 이곳도 잘되고있는지 궁금해요..
}
SIGNAL(SIG_INTERRUPT1) //에코신호가 들어오면...
{
DDRC = 0xff; //led입력
TIMSK = 0x00; // 타이머 정지
length = count; //지금까지 잰 거리를 length변수에 넣음.
EIMSK = 0; // 외부 인터럽트1 정지
if(length > 5 && length <10)
PORTC = 0x02; // 이곳이 작동이 안됨.
else PORTC = 0x01; //물체가 그 사이에 없으면 led oFF
count = 0;
}
int main(void)
{
DDRD = 0x02; //INT1(인터럽트)에 echo연결
DDRA = 0x01; //trigger연결
while(1){
EICRA = 0x02; // 외부 인터럽트 제어 레지스터 하강에지설정 ok
TCCR0 = 0x02; //8(8분주) -> 타이머 카운터 0 제어 레지스터 ok
SREG = 0x80; //set global interrupt enable 전역 인터럽트 인에이블 비트셋
PORTA = 0x01; //트리거 신호를 10us만큼 보낸다.
delay(1);
PORTA = 0x00;
TCNT0 = 0x8b;
//(1/16us)*8분주*(256-138) =59us 마다 인터럽트를 발생
TIMSK = 0x01; //타이머 카운트 활성화 -> 이 때 부터 시간을 잰다.
EIMSK = 0b00000001; //오버플로우 인터럽트
EIMSK = 0b00000010; // 외부 인터럽트1 인에이블설정
delay(5);
}
}
아 안녕하세요 내부에서 동작여부가 궁금하겠네요..
일단 인터럽트와 타이머들이 제대로 동작하는지 확인하기 위해 led등을 연결하여 확인해보는게 좋겠고요 ( 각 루틴이 어떻게 돌아가는지 밖에[서 보기만 하면 잘 모르므로)
소스에 대해서 잠깐 보자면
쩝..최초로 count=0; 이걸 해주는 작업이 없네요?? 이러면 초기값이 쓰레기가 되서 값이 마구 튀지요..
여기서 count가 계속 올라가는데 그럼 count가 발산하겠죠... 값이 쭉 올라가서 오버플로어구 나니까
volatile unsigned int count=0;
일단 그거 고치시고..
5에서 10사이를 검출하고자 하는데 음...정확한 위치를 찾기가 힘들수 있으므로 일단
5보다 큰루틴만 점검하고 10보다 작은거 점검하고 두개 합치세요^^;;
count값으로 읽어도 되는데...타이머 카운터값을 읽는게 좀 더 정확하겠네요.
avr자료실쪽에 제가 올려놓은 srf관련 자료 있으니 참고하세요..