,

내꺼 2012.05.23 12:35

avrstudio

컴파일하면 hex파일 생성

http://binworld.kr/36

 

/*****************************************************
Chip type           : ATmega128L
Program type        : Application
Clock frequency     : 8.000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 1024
*****************************************************/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <avr/wdt.h>

#define TRUE            0xff
#define FALSE           0x00 

#define SONAR_PORT      PORTD
#define SONAR_1_IN_PIN          0
#define SONAR_1_CONTROL_PIN     4
#define SONAR_1_CONTROL      0x10   
#define SONAR_2_IN_PIN          1
#define SONAR_2_CONTROL_PIN     5
#define SONAR_2_CONTROL      0x20
#define SONAR_3_IN_PIN          2
#define SONAR_3_CONTROL_PIN     6
#define SONAR_3_CONTROL      0x40

#define SERVO_ANGLE_LEFT           30   //0
#define SERVO_ANGLE_CENTER         44   //90
#define SERVO_ANGLE_RIGHT          58   //180

#define DISTANCE__NEAR             200 //300      //mm
#define DISTANCE__MIDDLE           400//800       //mm
#define DISTANCE__FAR              1000//1300       //mm

#define SPEED_SLOW             150
#define SPEED_MIDDLE           200
#define SPEED_FAST             255

#define Buffer_Lenth    20

/////////////////////////////////////////////////////////
#define sbit(x,y) (x |= (1<<y)) //비트를 1
#define cbit(x,y) (x &= ~(1<<y))//비트를 0
#define tbit(x,y) (x & (1<<y)) //비트가 1인지를 검사

////////////////////////////////////////////////////////////
volatile unsigned char Main_Timer_Count=0;
volatile unsigned int Read_Timer1_Value =0;

volatile unsigned char imsi_Count = 0;
volatile unsigned char imsi_flag = 0;
volatile unsigned char imsi2_Count = 0;
volatile unsigned char imsi2_flag = 0;
                                 
volatile unsigned int Sonar_1_Distance_Buf = 0;
volatile unsigned int Sonar_2_Distance_Buf = 0;
volatile unsigned int Sonar_3_Distance_Buf = 0;
volatile unsigned int Sonar_1_Distance = 0;
volatile unsigned int Sonar_2_Distance = 0;
volatile unsigned int Sonar_3_Distance = 0;
volatile unsigned int Sonar_1_Distance_Array[4] = {0,0,0,0};
volatile unsigned int Sonar_2_Distance_Array[4] = {0,0,0,0};
volatile unsigned int Sonar_3_Distance_Array[4] = {0,0,0,0};

volatile unsigned char Distance_1_Count = 0;
volatile unsigned char Distance_2_Count = 0;
volatile unsigned char Distance_3_Count = 0;

volatile unsigned char Fan_Speed_Data = 0;
volatile unsigned char Servo_Dgree_Data = 0;

volatile unsigned char Sonar_Read_Time = 0;
volatile unsigned char Send_Sonar_Time = 0;
volatile unsigned char Send_Sonar_Count = 0;

volatile unsigned char Sonar_Send_Flag = 0;
volatile unsigned char Sonar_Receive_Flag = 0;
volatile unsigned char Sonar_Select_Count = 0;
volatile unsigned char Int_Rising_Edge_Flag=0;

volatile unsigned char System_Run_Flag=0;
volatile unsigned int System_Run_Count=0;
volatile unsigned char System_Run_Count_Flag=TRUE;

volatile unsigned int imsi_count_1 = 0;
volatile unsigned int imsi_count_2 = 0;
volatile unsigned int imsi_count_3 = 0;

////////////////////////////////////////////////////////////////////////////


// Timer 3 output compare A interrupt service routine
SIGNAL(SIG_OUTPUT_COMPARE3A)  // void timer3_compa_isr(void)
{
 Main_Timer_Count++;
}  

// External Interrupt 0 service routine
SIGNAL(SIG_INTERRUPT0)    // void ext_int0_isr(void)
{                      
     unsigned char imsi_data;

          if(Sonar_Send_Flag == TRUE)
          {
               if(Int_Rising_Edge_Flag == TRUE)
               {
                    //int0를 하강 엣지로 설정
                    EICRA &= ~(0x01);
                    //타이머 초기화
                    TCNT1H=0;
                    TCNT1L=0;
           
                    Int_Rising_Edge_Flag = FALSE;
               }
               else
               {
                    //타이머 데이터 읽기
                    imsi_data = TCNT1L;
                    Sonar_1_Distance_Buf = TCNT1H;
                    Sonar_1_Distance_Buf <<= 8;
                    Sonar_1_Distance_Buf |= imsi_data;
       
                    //int0를 상승 엣지로 설정
                    EICRA |= 0x01;
       
                    Int_Rising_Edge_Flag = TRUE;
                    Sonar_Send_Flag = FALSE;
                    Sonar_Receive_Flag = TRUE;
               }
          }
}

// External Interrupt 1 service routine
SIGNAL(SIG_INTERRUPT1)    // void ext_int1_isr(void)
{

     unsigned char imsi_data;

          if(Sonar_Send_Flag == TRUE)
          {
               if(Int_Rising_Edge_Flag == TRUE)
               {
                    //int1를 하강 엣지로 설정
                    EICRA &= ~(0x04);
                    //타이머 초기화
                    TCNT1H=0;
                    TCNT1L=0;

                    Int_Rising_Edge_Flag = FALSE;
               }
               else
               {
                    //타이머 데이터 읽기
                    imsi_data = TCNT1L;
                    Sonar_2_Distance_Buf = TCNT1H;
                    Sonar_2_Distance_Buf <<= 8;
                    Sonar_2_Distance_Buf |= imsi_data;

                    //int1를 상승 엣지로 설정
                    EICRA |= 0x04;

                    Int_Rising_Edge_Flag = TRUE;
                    Sonar_Send_Flag = FALSE;
                    Sonar_Receive_Flag = TRUE;
               }
              
          }
}

// External Interrupt 2 service routine
SIGNAL(SIG_INTERRUPT2)    // void ext_int2_isr(void)
{  

     unsigned char imsi_data;

          if(Sonar_Send_Flag == TRUE)
          {
               if(Int_Rising_Edge_Flag == TRUE)
               {
                    //int2를 하강 엣지로 설정
                    EICRA &= ~(0x10);
                    //타이머 초기화
                    TCNT1H=0;
                    TCNT1L=0;

                    Int_Rising_Edge_Flag = FALSE;

               }
               else
               {
                    //타이머 데이터 읽기
                    imsi_data = TCNT1L;
                    Sonar_3_Distance_Buf = TCNT1H;
                    Sonar_3_Distance_Buf <<= 8;
                    Sonar_3_Distance_Buf |= imsi_data;

                    //int2를 상승 엣지로 설정
                    EICRA |= 0x10;

                    Int_Rising_Edge_Flag = TRUE;
                    Sonar_Send_Flag = FALSE;
                    Sonar_Receive_Flag = TRUE;
               }
          }
}

void Delay_Func(unsigned int delay_data)
{            
     while(delay_data--)
     {
          asm("nop");
     }
       
}

void Motor_Speed_Process(unsigned char motor_speed)
{  
     //속도는 0 ~ 255 까지 가능 하다
     if(motor_speed == 1)           //최저 속도
     {
          OCR2 = SPEED_SLOW;
     }
     else if(motor_speed == 2)      //중간 속도
     {
          OCR2 = SPEED_MIDDLE;
     }
     else if(motor_speed == 3)      //최고 속도
     {
          OCR2 = SPEED_FAST;
     }
     else if(motor_speed == 4)      //정지
     {
          OCR2 = 0;
     }
     else
     {
     }
}

void Servo_Data_Process(unsigned char servo_angle)
{                     

     if(servo_angle == 1)           //좌측
     {
          OCR0 = SERVO_ANGLE_RIGHT;;
     }
     else if(servo_angle == 2)      //중간
     {
          OCR0 = SERVO_ANGLE_CENTER;
     }
     else if(servo_angle == 3)      //우측
     {
          OCR0 = SERVO_ANGLE_LEFT;
     }
     else if(servo_angle == 4)      //센터
     {
          OCR0 = SERVO_ANGLE_CENTER;
     }
     else
     {
     }
}

//-------최소 128ms 이상의 간격으로 출력해야 한다 ------------------------------------------------
void Send_Sonar_Func(unsigned char sonar_num)
{            
    if(sonar_num == 1)
    {
        //핀을 출력으로
        DDRD |= 0x10;//SONAR_1_CONTROL;
       
        Sonar_Send_Flag = FALSE;
        //sonar INIT출력 LOW
        TCNT1H=0;
        TCNT1L=0;
        //TCCR1B=0x02;   // 8분주 사용 2us 클럭 스타트
        //sbit(PORTE,3);       //소나 출력을 H
        sbit(SONAR_PORT,SONAR_1_CONTROL_PIN);// = 1;
        Delay_Func(1000);
        cbit(SONAR_PORT,SONAR_1_CONTROL_PIN);// = 0;
        Delay_Func(100);
       
        Sonar_Send_Flag = TRUE;
       
        //int0를 상승 엣지로 설정
       
        //핀을 입력으로
        DDRD &= ~(0x10);
       
        //int0를 상승 엣지로 설정    
        EICRA |= 0x01;
       
        Int_Rising_Edge_Flag = TRUE;
    }
    else if(sonar_num == 2)
    {

          //핀을 출력으로
        DDRD |= 0x20;//SONAR_1_CONTROL;

          Sonar_Send_Flag = FALSE;
        //sonar INIT출력 LOW
        TCNT1H=0;
        TCNT1L=0;
        //TCCR1B=0x02;   // 8분주 사용 2us 클럭 스타트
        //sbit(PORTE,3);       //소나 출력을 H

        sbit(SONAR_PORT,SONAR_2_CONTROL_PIN);// = 1;

        Delay_Func(1000);
        cbit(SONAR_PORT,SONAR_2_CONTROL_PIN);// = 0;
        Delay_Func(100);

        Sonar_Send_Flag = TRUE;

        //int1를 상승 엣지로 설정

        //핀을 입력으로
        DDRD &= ~(0x20);

        //int1를 상승 엣지로 설정
        EICRA |= 0x04;

        Int_Rising_Edge_Flag = TRUE;
    }
    else if(sonar_num == 3)
    {

           //핀을 출력으로
        DDRD |= 0x40;//SONAR_1_CONTROL;

          Sonar_Send_Flag = FALSE;
        //sonar INIT출력 LOW
        TCNT1H=0;
        TCNT1L=0;
        //TCCR1B=0x02;   // 8분주 사용 2us 클럭 스타트
        //sbit(PORTE,3);       //소나 출력을 H

        sbit(SONAR_PORT,SONAR_3_CONTROL_PIN);// = 1;

        Delay_Func(1000);
        cbit(SONAR_PORT,SONAR_3_CONTROL_PIN);// = 0;
        Delay_Func(100);

        Sonar_Send_Flag = TRUE;

        //int2를 상승 엣지로 설정

        //핀을 입력으로
        DDRD &= ~(0x40);

        //int2를 상승 엣지로 설정
        EICRA |= 0x10;

        Int_Rising_Edge_Flag = TRUE;
    }
    else
    {
    }
}  

void Sonar_Receive_Process(void)
{   

    unsigned int imsi2_int=0,imsi_base=0,imsi_distance=0,sum_data=0;
    unsigned long imsi3_long=0,imsi4_long=0;
   
     //초음파 센서 번호 검사
     if(Sonar_Select_Count == 1)
     {
         
          //소리는 초당 340m(34000cm)나간다, 1ms= 34cm(340mm), 2us=0.68mm , 8us = 2.72mm 이다
          imsi4_long = (Sonar_1_Distance_Buf / 2);       //왕복이라 2로 나눈다
          imsi3_long = ((imsi4_long * 272) / 100);      //기본이 8us라
          imsi2_int = imsi3_long;
         
          if(imsi2_int > DISTANCE__FAR)
          {
               imsi2_int = DISTANCE__FAR + 100;
          }
         
          Sonar_1_Distance_Array[Distance_1_Count] = imsi2_int;
         
          Distance_1_Count++;
          if(Distance_1_Count > 3)
          {
               Distance_1_Count = 0;
          }

          sum_data = Sonar_1_Distance_Array[0];
          sum_data += Sonar_1_Distance_Array[1];
          sum_data += Sonar_1_Distance_Array[2];
          sum_data += Sonar_1_Distance_Array[3];
         
          Sonar_1_Distance = sum_data >> 2;//imsi2_int;
         
     }
     else if(Sonar_Select_Count == 2)
     {
         
          //소리는 초당 340m(34000cm)나간다, 1ms= 34cm(340mm), 2us=0.68mm, 8us = 2.72mm  이다
          imsi4_long = (Sonar_2_Distance_Buf / 2);       //왕복이라 2로 나눈다
          imsi3_long = ((imsi4_long * 272) / 100);      //기본이 8us라
          imsi2_int = imsi3_long;
         
          if(imsi2_int > DISTANCE__FAR)
          {
               imsi2_int = DISTANCE__FAR + 100;
          }
         
          Sonar_2_Distance_Array[Distance_2_Count] = imsi2_int;
         
          Distance_2_Count++;
          if(Distance_2_Count > 3)
          {
               Distance_2_Count = 0;
          }
         
          sum_data = Sonar_2_Distance_Array[0];
          sum_data += Sonar_2_Distance_Array[1];
          sum_data += Sonar_2_Distance_Array[2];
          sum_data += Sonar_2_Distance_Array[3];
         
          Sonar_2_Distance = sum_data >> 2;//imsi2_int;

     }
     else if(Sonar_Select_Count == 3)
     {
         
          //소리는 초당 340m(34000cm)나간다, 1ms= 34cm(340mm), 2us=0.68mm, 8us = 2.72mm  이다
          imsi4_long = (Sonar_3_Distance_Buf / 2);       //왕복이라 2로 나눈다
          imsi3_long = ((imsi4_long * 272) / 100);      //기본이 8us라
          imsi2_int = imsi3_long;
         
          if(imsi2_int > DISTANCE__FAR)
          {
               imsi2_int = DISTANCE__FAR + 100;
          }
         
          Sonar_3_Distance_Array[Distance_3_Count] = imsi2_int;

          Distance_3_Count++;
          if(Distance_3_Count > 3)
          {
               Distance_3_Count = 0;
          }

          sum_data = Sonar_3_Distance_Array[0];
          sum_data += Sonar_3_Distance_Array[1];
          sum_data += Sonar_3_Distance_Array[2];
          sum_data += Sonar_3_Distance_Array[3];
         
          Sonar_3_Distance = sum_data >> 2;//imsi2_int;
     }
     else
     {
     }


     if(System_Run_Flag == TRUE)
     {
     ///////////////////////////////////////////////////////////////
          //각 센서 거리 계산
          imsi_base = Sonar_1_Distance;
    
          if(imsi_base <= Sonar_2_Distance)            //2번보다 1번이 작다
          {
               if(imsi_base <= Sonar_3_Distance)       //3번보다 1번이 작다
               {
                    if(imsi_base < DISTANCE__FAR)
                    {
                         //센서 1번이 가장 작다
                         Servo_Data_Process(1);
                         imsi_distance = Sonar_1_Distance;
                    }
                    else
                    {
                          Servo_Data_Process(4);
                         imsi_distance = Sonar_1_Distance;
                    }
               }
               else      //1번보다 3번이 작다
               {
                    imsi_base = Sonar_3_Distance;
                    if(imsi_base < DISTANCE__FAR)
                    {
                         //센서 3번이 가장 작다
                         Servo_Data_Process(3);
                         imsi_distance = Sonar_3_Distance;
                    }
                    else
                    {
                         //
                         Servo_Data_Process(4);
                         imsi_distance = Sonar_3_Distance;
                    }
               }
          }
          else      //1번 보다 2번이 더 작다
          {
               imsi_base = Sonar_2_Distance;
               if(imsi_base <= Sonar_3_Distance)       //3번보다 2번이 작다
               {
                    if(imsi_base < DISTANCE__FAR)
                    {
                         //센서 2번이 가장 작다
                         Servo_Data_Process(2);
                         imsi_distance = Sonar_2_Distance;
                    }
                    else
                    {
                         Servo_Data_Process(4);
                         imsi_distance = Sonar_2_Distance;
                    }
               }
               else           //3번보다 2번이 작다
               {
                    imsi_base = Sonar_3_Distance;
                    if(imsi_base < DISTANCE__FAR)
                    {
                         //센서 3번이 가장 작다
                         Servo_Data_Process(3);
                         imsi_distance = Sonar_3_Distance;
                    }
                    else
                    {
                         Servo_Data_Process(4);
                         imsi_distance = Sonar_3_Distance;
                    }
               }
          }
    
          //거리가 거리 최대치 보다 작으면 동작
          if(imsi_distance < DISTANCE__FAR)
          {
               //거리 계산
               if(imsi_distance <= DISTANCE__NEAR)     //300mm 이하
               {
                    //모터 정지
                    Motor_Speed_Process(4);
               }
               else if(imsi_distance  > DISTANCE__NEAR && imsi_distance <= DISTANCE__FAR)     //300mm ~ 1300mm
               {
                    //모터 작동
                    Motor_Speed_Process(3);
               }
               else  
               {
                    //모터 작동
                  //  Motor_Speed_Process(3);
               }
          }
          else
          {
               //모터 정지
               Motor_Speed_Process(4);
          }
     }
}

void System_Init_Func(void)
{
// Declare your local variables here
// Port A initialization
     PORTA=0x00;
     DDRA=0xff;

// Port B initialization
     PORTB=0xff;
     DDRB=0xff;

// Port C initialization
     PORTC=0xff;
     DDRC=0xff;

// Port D initialization
     PORTD=0xf0;
     DDRD=0xf0;

// Port E initialization
     PORTE=0x00;
     DDRE=0x00;

// Port F initialization
     PORTF=0x00;
     DDRF=0x00;

// Port G initialization
     PORTG=0x00;
     DDRG=0x00;

// Timer/Counter 0 initialization
     ASSR = 0x00;
     TCCR0 = 0x6e;         //0110 1110   1fast pwm , match claear, 256분주 0.125ns * 256 = 32us
     TCNT0 = 0x00;
     OCR0 = SERVO_ANGLE_CENTER;            //1.5ms 중간 값

// Timer/Counter 1 initialization
     TCCR1A = 0x00;
     TCCR1B = 0x03;        //64분주 기준 시간을 8us로 설정
     TCNT1H = 0x00;
     TCNT1L = 0x00;
     OCR1AH = 0x00;
     OCR1AL = 0x00;

// Timer/Counter 2 initialization
     TCCR2 = 0x6c;     //fast pwm, match clear ,256분주 0.125ns * 256 = 32us
     TCNT2 = 0x00;
     OCR2 = 0;      //초기 값      //전체 구간은 8.1ms  약 120 Hz

// Timer/Counter 3 initialization
     TCCR3A = 0x00;
     TCCR3B = 0x0c;    //256분주 0.125ns * 256 = 32us
     TCNT3H = 0x00;
     TCNT3L = 0x00;
     OCR3AH = 0x00;
     OCR3AL = 62;      //32us * 62 = 2ms

// Timer(s)initialization
     TIMSK = 0x00;

     ETIMSK = 0x10;

// External Interrupt(s) initialization
     EICRA = 0x03f;         //0011 1111    (상승 엣지)
     EICRB = 0x00;
     EIMSK = 0x07;        //0000 0111(인터럽트 0,1,2)


// USART0 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART0 Receiver: On
// USART0 Transmitter: On
// USART0 Mode: Asynchronous
// USART0 Baud Rate: 9600
     UCSR0A = 0x00;
     UCSR0B = 0xD8;
     UCSR0C = 0x06;
     //16MHz
     //UBRR0H=0x00;
     //UBRR0L=0x67;
     //8MHz
     UBRR0H = 0x00;
     UBRR0L = 0x33;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
     ACSR=0x80;
     SFIOR=0x00;
}

// Declare your global variables here

int main(void)
{
    cli();
    System_Init_Func();
    // Global enable interrupts
    sei();
    cbit(SONAR_PORT,SONAR_1_CONTROL_PIN);// = 0;
    cbit(SONAR_PORT,SONAR_2_CONTROL_PIN);// = 0;
    cbit(SONAR_PORT,SONAR_3_CONTROL_PIN);// = 0;

     while (1)
     {
          // Place your code here
          if(Main_Timer_Count >= 2) //4ms
          {
               Sonar_Read_Time++;
              
               if(System_Run_Count_Flag == TRUE)
               {
               System_Run_Count++;
               }
               Main_Timer_Count = 0;
          }

          //초음파 송신 처리 함수
          if(Sonar_Read_Time >= 50)      //200ms  기준은 4ms, 50 * 4ms = 200ms
          {
               Send_Sonar_Func(Sonar_Select_Count);
              
               Sonar_Select_Count ++;
               if(Sonar_Select_Count > 3)
               {
                    Sonar_Select_Count = 1;
               }
              
               Sonar_Read_Time = 0;
          }
          //초음파 수신 처리 함수
          if(Sonar_Receive_Flag == TRUE)
          {
               Sonar_Receive_Process();
               Sonar_Receive_Flag = FALSE;
          }
         
          if(System_Run_Count >= 1000)       //약 4초
          {
               System_Run_Count = 0;
               System_Run_Flag = TRUE;
               System_Run_Count_Flag = FALSE;
          }
     };//
}//

 

'내꺼' 카테고리의 다른 글

wavelet  (0) 2012.05.23
,  (0) 2012.05.23
ssat모의 후기  (0) 2012.02.06
키엘 블루 허벌 라인  (0) 2011.07.01
Posted by 아크k


티스토리 툴바