ATmega128A::Linetracer 실습과제
[main.c]
#include "motor.h"
#include "sensor.h"
#include "usart.h"
int main(void)
{
int error=0, rpps=0, lpps=0, gain=15;
mtr0_init();
mtr2_init();
sensor_init();
usart0_init();
_delay_ms(3000);
while (1)
{
error = get_error(get_sensor());
lpps=-(150-gain*error);
rpps=(150+gain*error);
mtr0_tc0(lpps);
mtr1_tc2(rpps);
//usart0_printf("left pps : %d, right pps: %d, ",lpps,rpps);
//usart0_printf("error:%d \n",error);
_delay_ms(1);
}
return 0;
}
[motor.h]
#ifndef _MOTOR_H_
#define _MOTOR_H_
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
void mtr0_init();
void mtr2_init();
void mtr0_tc0(int pps);
void mtr1_tc2(int pps);
#endif
[motor.c]
int cw0=1;
int cw2=1;
static char cw[4]={0x01, 0x02, 0x04, 0x08};
static char ccw[4]={0x08, 0x04, 0x02, 0x01};
static int i0=0;
static int i2=0;
int ocr0, ocr2;
int angle1, angle2;
void mtr0_init()// tc0 사용
{
DDRA |= 0x0F; //하위 4bit 출력으로 설정
ASSR =0x00; //클럭소스 선택
TCCR0 = 0x1F; //CTC 모드, toggle compare match, prescaler = 1024
OCR0 = 0x22; //
TCNT0 = 0x00; //0 ~ 22
TIFR &= 0xFD; //1111_1101, 0cf0 compare match 인터럽트 핸들링 루틴 실행
}
void mtr2_init()//tc2 사용
{
DDRB |= 0x0F;
ASSR =0x00;
TCCR2 = 0x1D;
OCR2 = 0x22;
TCNT2 = 0x00;
TIFR &= 0x7F;
}
ISR(TIMER0_COMP_vect)
{
int j=0;
j = (i0++)%4;
if(cw0){PORTA = cw[j];}
else {PORTA = ccw[j];}
}
ISR(TIMER2_COMP_vect)
{
int j=0;
j = (i2++)%4;
if(cw2){PORTB = cw[j];}
else {PORTB = ccw[j];}
}
void mtr0_tc0(int pps)
{
cli();
TIMSK |= 0x02;
if(pps<0){cw0=0; pps=-pps;}
else if(pps==0){TIMSK &= 0xFD;}
else {cw0=1;}
ocr0 = (7.18125/((double)pps/1000)-1);
if(ocr0<0 || ocr0>256){TIMSK &= 0xFD;}
OCR0 = ocr0;
sei();
}
void mtr1_tc2(int pps)
{
cli();
TIMSK |= 0x80;
if(pps<0){cw2=0; pps=-pps;}
else if(pps==0){TIMSK &= 0x7F;}
else {cw2=1;}
ocr2 = (7.18125/((double)pps/1000)-1);
if(ocr2<0 || ocr2>256){TIMSK &= 0x7F;}
OCR2 = ocr2;
sei();
}
[sensor.h]
#endif
#define SENSOR_H_
#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
void sensor_init();
char get_sensor();
int get_error(char cdata);
#endif
[sensor.c]
#include "sensor.h"
//센서포트초기화
void sensor_init()
{
DDRC &=0x0f; //입력으로 설정
}
//센서출력값 리턴
char get_sensor()
{
char c;
c = PINC&0x0f; //4bit 사용, PC0:3
return c;
}
//로봇이 라인에서 벗어난 거리를 리턴(+:우측으로 벗어남
int get_error(char cdata)
{
int error=0, error1=0,error2=0;
switch(cdata&0x03)
{
case 0x00:
error2=0;
break;
case 0x01:
error2=-3;
break;
case 0x02:
error2=-1;
break;
case 0x03:
error2=-2;
break;
default:
error2=0;
}
switch(cdata&0x0c)
{
case 0x00:
error1=0;
break;
case 0x04:
error1 =1;
break;
case 0x08:
error1 =3;
break;
case 0x0c:
error1 =2;
break;
}
error = error1 + error2;
return error;
}