programming/MCU

ATmega128A::Linetracer 실습과제

krystalS2ee 2020. 3. 29. 13:31

[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;
}