안녕하세요.....
SRF-04를 이용해서 시리얼통신으로 거리를 구현 하려고합니다.
현재 까지 진행한 소스 입니다.
#include <iom128.h>
#include <ina90.h>
unsigned char portB = 0;
int trigerCheck = 0;
int echoCheck;
int isHigh = 0;
int timecount;
float value;
#define SONAR_TRG 0x01 //0x00000001
#define TINT_CHECK 0x02 //0x00000010
void delay_us(long int k) //시간 지연 함수
{
while(k--);
}
void MCU_initialize(void) // initialize ATmege128 MCU
{
DDRB = 0xFF; //PORTB 출력 설정(Triger 신호)
PORTB = 0x00;
DDRD = 0xF7; //PORTD 입력 설정(Echo 신호)
PORTD = 0x00;
}
#pragma vector=TIMER1_OVF_vect
__interrupt void T1_overflow(void)
{
__disable_interrupt();
{
if( isHigh ) // isHigh의 초기값이 0이므로 최초에 실행 안됨.
{
portB &= (~TINT_CHECK); // ~0x00000010 와 & 연산 후 입력
isHigh = 0; // 꼬리표_출력레벨 : 0
}
else // isHigh의 값이 0일때 실행
{
portB |= TINT_CHECK; // 0x00000010 와 or 연산 후 입력
isHigh = 1; // 꼬리표_출력레벨 : 1
}
PORTB = portB; // portB에 입력된 값을 PORTB로 출력
portB |= SONAR_TRG; // portB 에 SOANR_TRG(0x00000001) 와 or 연산후 입력
PORTB = portB; // PORTB = 0x00000011
delay_us(15); // 약 10us delay
portB &= (~SONAR_TRG); // ~SONAR_TRG(0x11111110) 와 portB & 연산 후 portB에 입력 -->
PORTB = portB; // PORTB = 0x00000010 출력
timecount = 0;
}
TCNT1H = 0xA6;
TCNT1L = 0x00;
trigerCheck = 1;
__enable_interrupt();
}
void USART_initialize(void)
{
UCSR0A=0x00; //Asynchronous normal mode
UCSR0B=0x98; //Rx/Tx enable, 8data
UCSR0C=0x06; //no parity, 1stop, 8data
UBRR0H=0x00;
UBRR0L=7; //19200 band rate
}
void TX0_char(unsigned char data) //transmit a character by USART0
{
while((UCSR0A & 0x20) == 0x00); //data register empty?
UDR0 = data;
}
void TX0_string(unsigned char *string) //transmit a string by USART0
{
while(*string != '\0')
{
TX0_char(*string);
string++;
}
}
void send()
{
DDRB = 0xFF; // 포트 B를 출력으로 설정
TCCR1A = 0x00;
TCCR1B = 0x03; // 65536/(14745600/64)=0.28[s]
TCCR1C = 0x00;
TCNT1H = 0xA6; // 1/(14745600/64)=0.00000434 0.1(100ms)/0.00000434 = 23041.47465
// 65536-23040 = 42469 = 0xA600 = TCNT1H = 0xA6
TCNT1L = 0x00; // TCNT1L = 0x00
TIMSK = 0x04;
ETIMSK = 0x00;
TIFR = 0x00; //Clear All Interrupt Flag
ETIFR = 0x00;
__enable_interrupt();
}
void distance_check_start() //타이머 3을 이용한 거리 측정 시작
{
TCCR3A = 0x00;
TCCR3B = 0x03; // 65536/(14745600/64)=0.28[s]
TCCR3C = 0x00;
// TCNT3H = 0xD3; // 1/(14745600/64)=0.00000434 0.05(50ms)/0.00000434 = 11520.73733
// 65536-11519 = 54017 = 0xD301 = TCNT1H = 0xD3
// TCNT3L = 0x01; // TCNT1L = 0x01
}
void distance_check_end() //타이버3을 이용한 거리 측정 끝
{
TCCR3A = 0x00;
TCCR3B = 0x00;
TCCR3C = 0x00;
// TCNT3H = 0x00;
// TCNT3L = 0x00;
}
void revice_check() //Echo를 체크 하기 위한 함수
{
do
{
if((PIND & 0x08) == 0x08 )
{
// TX0_string(" yes, Echo Check ");
distance_check_start();
// PORTD = 0x10;
}
else((PIND & 0x08) == 0x00);
{
// TX0_string(" No, Echo check ");
distance_check_end();
// PORTD = 0xEF;
}
}while(1);
}
/*void distance() // 타이머 off
{
float echoH = 0;
float echoL = 0;
float dis_con;
float m_sec;
float T_con;
echoH = TCNT3H;
echoL = TCNT3L;
T_con = echoH*256+echoL;
m_sec = 0.000004*((float)T_con);
dis_con = 32400*((float)m_sec/2);
} */
void main()
{
MCU_initialize();
portB = 0;
send();
USART_initialize();
for(;;)
{
revice_check();
TX0_string(" value : ");
// 계산
// uart 전송
}
}
현재 구현한 프로그램을 간단히 설명드리면, PORT B에 Trigger 신호를 내보내고요.
PORT D 로 Echo 신호를 받음.........
현재 테스트 결과
주기적신호 : 포트 B Timer 1사용 (Trigger).......... 확인됨
Echo 신호 : 포트 D .................확인됨
시리얼 통신 : String만 해봄........Test 완료
구현을 못한 부분
Timer 3을 이용해서 Echo 신호가 들어오는 구간에 시간을 가지고 10진수로 변환을 해서 시리얼통신을 이용해서 구현 하려고 합니다......
어떻게 구현을 해야 하는지요...지푸라기라도 던져 주시길 바랍니다.
첫댓글 거리 계산은 타이머에서 해줄꺼구여.. 그 값을 배열로 바꾸어서 char 형으로 변환해서 시리얼 통신을 하문 될꺼 같은데요.. Send_Buf[1] = (char)(value / 100)+ '0'; Send_Buf[2] = (char)((value % 100) / 10)+ '0'; Send_Buf[3] = (char)(value % 10)+ '0'; Send_Buf[4] = '\n'; Send_Buf[5] = '\r';이런식으로 해서 보내면 안되나여..
초음파 후방감지기 개발경험이 있는사람으로서 무슨 말인지 하나도 모르겠네요. avr은 초보라서... 잘 해보세요. 저도 처음에 무지하게 고생많이 했답니다.