[소스] 스테핑 라인트레이서 (ATMega16+초음파센서+스테핑모터)
ATMega16에서 초음파센서(SRF04), Stepping연결하여
라인트레이서 구현하였습니다
--------------------------------------------------------------------------
//ICC-AVR application builder : 2007-01-08
// Target : M16
// Crystal: 11.059Mhz
#include
#include
#define STEPPING_PORT PORTC
#define SersorPort PORTB
#define SersorPinInput PINB
#define STEP_DELAYTIME 10
#define Left_LED_ON (PORTB = PORTB | 0x01) // 왼쪽 LED 를 킨다.
#define Right_LED_ON (PORTB = PORTB | 0x02) // 왼쪽 LED 를 킨다.
#define Three_LED_ON (PORTB = PORTB | 0x04) // LED 를 킨다.
#define Three_LED_OFF (PORTB = PORTB & (~0x04)) // LED 를 킨다.
#define LED_OFF (PORTB = PORTB & 0xfc) // 양쪽 LED를 끈다.
#define Left_Channel 6 // 왼쪽 센서 ADC 채널
#define Right_Channel 7 // 오른쪽 센서 ADC 채널
#define ON 1
#define OFF 0
unsigned int dist=0, // 거리
dist_buff=0, // 거리임시저장
buff_cnt=0, // 버퍼카운트
waveflag=0, // 신호플래그
clrcnt=0; // 클리어카운트
unsigned int icount, count=0;
unsigned int display_num[4]={0,0,0,0}; // Seven segment 4자리 숫자 출력 버퍼
unsigned int istepwait=0;
// 트리거 신호 보냄
void Sensor_TRIGGER_ON(void)
{
SersorPort = SersorPort | 0x10;
}
// 트리거 신호 보내지 않음
void Sensor_TRIGGER_OFF(void)
{
SersorPort = SersorPort & 0xEF;
}
//에코 신호
char Sensor_ECHO(void)
{
return ((SersorPinInput & 0x40) >> 6);
}
//트리거 신호
char Sensor_TRIGGER(void)
{
return ( (SersorPinInput & 0x10) >> 4 );
}
//TIMER0 initialize - prescale:32
// WGM: Normal
// desired value: 32uSec
// actual value: 32.000uSec (0.0%)
void timer0_init(void)
{
TCCR0 = 0x00; //stop
ASSR = 0x00; //set async mode
TCNT0 = 0xF0; //set count
OCR0 = 0x10;
TCCR0 = 0x03; //start timer
/*
TCNT0 = 0xF0; //set count
OCR0 = 0x10;
TCCR0 = 0x03; //start timer
*/}
#pragma interrupt_handler timer0_ovf_isr:17
void timer0_ovf_isr(void)
{
TCNT0 = 0xf0; //reload counter value
count++; //32usec마다 카운트 올림
if(count>1000) //카운트 1500마다 신호 한번씩 보내고 클리어 카운트 올림
{
Sensor_TRIGGER_ON();
count=0;
clrcnt++;
}
if(clrcnt>50) //클리어 카운트가 100이면 거리버퍼 클리어. 클리어카운트 초기화.
{
dist_buff=0;
clrcnt=0;
}
if(waveflag==OFF) //전단계까지 신호 받은 기억 없는데
{
if(Sensor_ECHO()==ON) //좀전에 받았으면 신호 받았다고 기억함. 버퍼 카운트에 지금까지 카운트 값을 넣어줌
{
waveflag=ON;
buff_cnt=count;
}
Sensor_TRIGGER_OFF(); //트리거 신호 끔
} else if(waveflag==ON) { //신호 받았으면
if(Sensor_ECHO()==OFF) { //에코신호 끝났으면
dist = ((count-buff_cnt)/2); //거리는 카운트 - 버퍼카운트 나누기 2
dist_buff = dist; //거리버퍼는 거리
waveflag = OFF; //플래그 내리고
count = 0; //카운트와 클리어카운트 초기화
clrcnt = 0;
}
}
}
void port_init(void)
{
PORTA = 0x00;
DDRA = 0x0F;
PORTB = 0x00;
DDRB = 0xBF;
PORTC = 0x00;
DDRC = 0xFF;
PORTD = 0x00;
DDRD = 0xFF;
}
//UART0 initialize
// desired baud rate: 9600
// actual: baud rate:9600 (0.0%)
// char size: 8 bit
// parity: Disabled
void uart0_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x02;
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x8F; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0x08;
}
//ADC initialize
// Conversion time: 75uS
void adc_init(void)
{
ADCSR = 0x00; //disable adc
ADMUX = 0x20; //select adc input 0
ACSR = 0x80;
ADCSR = 0xe6;
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer0_init();
//timer1_init();
uart0_init();
adc_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x01; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void delay(int n)
{
volatile int i,j;
for(i=1;i 2) {
if(l_sensor > l_threshold && r_sensor < r_threshold){ // 좌회전
Left_LED_ON;
STEPPING_PORT=Stepping_oneprocess('L',STEPPING_PORT);
}else if(l_sensor < l_threshold && r_sensor > r_threshold){ // 우회전
Right_LED_ON;
STEPPING_PORT=Stepping_oneprocess('R',STEPPING_PORT);
}else{
LED_OFF;
STEPPING_PORT=Stepping_oneprocess('F',STEPPING_PORT);
}
delay_sp(istepwait);
} else {
STEPPING_PORT=Stepping_oneprocess('B',STEPPING_PORT);
delay(10000);
}
}
}
[이 게시물은 administrator님에 의해 2011-12-06 04:26:09 통합정보검색에서 복사 됨]
