학습목표    1

학습주제    1

예습내용    1

실습방법    1

        1

포토인터럽터

학습목표

포토인터럽터의 원리를 이해하고 모터의 회전수를 측정한다.

학습주제

1. 포토인터럽터의 원리

예습내용

 

그림1

포토인터럽터의 원리는 “PC제어” “모터회전 측정에서 설명을 하였다.

 

보드의 회로연결

1.        그림에서 J6 1 - 5V J6 2 - GND 연결한다.

2.        실습보드의 그림1에서 콘넥터 J51 – S1, J52 – S2 연결한다.

 

보드의 포트 PD3 5V 입력되어 있다. 포토인터럽터가 동작을 하면 0V 떨어진다. 그러므로 “Falling Edge”에서 인터럽트 함수가 동작하게 하여 펄스를 카운트 한다.

1초동안의 카운트한 회수로 모터의 회전수를 있다. 실습보드는 검은새 띠가 10 이므로 10개의 펄스가 모터의 1회전을 나타낸다.

 

실습방법

   

 

1.      포토인터럽터에 의한 펄스 카운트 프로그램을 만든다.

[원본프로그램 다운 받기]

타이머 함수를 1 간격으로 동작시키고 이때 외부 인터럽트 (INT3) 펄스를 카운트 값을 C포트로 출력한다.

아래와 같이 프로젝트 함수를 만들고 손으로 DC 모터를 회전시켜 포토인터럽터로 입력된 카운트 값이 C포트로 출력되는지 확인해 본다.

포트 PD3 Falling Edge에서 동작하는 외부인터럽트 함수를 만든다.

1초마다 동작하는 타이머 함수를 만든다.

RS232 함수를 만든다.

프로젝트 함수를 만든다.

 

 

 

예제1-1  포트 PD3 입력되는 펄스를 Falling Edge에서 카운트 한다.

 

 

=== 생략 ===

char count=0;

 

// External Interrupt 3 service routine

interrupt [EXT_INT3] void ext_int3_isr(void)

{

              count++;

}

=== 생략 ===

 

 

 

예제1-2 타이머 함수를 “1마다 동작하게 하고, 여기에 펄스 카운트 값을 “C포트 출력을 내보낸다.

 

 

=== 생략 ===

// Timer 1 output compare A interrupt service routine

interrupt [TIM1_COMPA] void timer1_compa_isr(void)

{

              PORTC=count;

              count=0;

}

=== 생략 ===

// Timer/Counter 1 initialization

// Clock source: System Clock

// Clock value: 62.500 kHz

// Mode: CTC top=OCR1A

// OC1A output: Discon.

// OC1B output: Discon.

// OC1C output: Discon.

// Noise Canceler: Off

// Input Capture on Falling Edge

TCCR1A=0x00;

TCCR1B=0x0C;

TCNT1H=0x00;

TCNT1L=0x00;

 

// 1초마다 타이머1 동작하게 한다.

OCR1AH=62499>>8;

OCR1AL=62499&0xff;

 

OCR1BH=0x00;

OCR1BL=0x00;

OCR1CH=0x00;

OCR1CL=0x00;

=== 생략 ===

 

 

2.      PC에서 모터의 회전수를 조절하는 프로그램과 연결한다.

 

앞에서 기술한 “DC모터 제어단원의 PC 프로그램과 연결할 있게 AVR 프로그램을 수정한다. 그리고 회전수를 변화 시키며 C포트로 출력이 변하는 것을 확인 한다.

 

예제 2-1 B포트를 출력으로 하고 PWM0 출력하게 한다.

 

 

=== 생략 ===

PORTB=0x00;

DDRB=0xFF;

=== 생략 ===

// Timer/Counter 0 initialization

// Clock source: System Clock

// Clock value: Timer 0 Stopped

// Mode: Normal top=FFh

// OC0 output: Disconnected

ASSR=0x00;

TCNT0=0x00;

//TCCR0 = 0x00;

//OCR0 = 0x00;

// 16000000/(1024*256)=61Hz

TCCR0 = 0x6f;      // (1) Fast PWM Mode   ATmega128(L) Data Book P100  주기조절

OCR0 = 0xa0;        // ATmega128(L) Data Book P102   듀티비조절

=== 생략 ===

 

 

 

예제 2-2  RS232 통신 프로그램을 추가 한다.

[원본프로그램 다운 받기]

 

 

=== 생략 ===

char count=0,receive=0;

=== 생략 ===

interrupt [USART0_RXC] void uart0_rx_isr(void)

{

char status,data;

#asm

    push r26

    push r27

    push r30

    push r31

    in   r26,sreg

    push r26

#endasm

status=UCSR0A;

data=UDR0;

 

if(data == 0x02)     // 통신시작

              rx_wr_index0 = 0;  

if(data == 0x03)                    // 통신 완료 - 메세지 발생

              receive=1;             

             

if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)

   {

=== 생략 ===

while (1)

      {

      // Place your code here

      if(receive==1) {

          if(rx_buffer0[1] == 0x30)

                                        PORTB=0x01;

                                           else if(rx_buffer0[1] == 0x31)

                                                         PORTB=0x02;

                                           else if(rx_buffer0[1] == 0x32)

                                                         PORTB=0x00;

                                           OCR0 = rx_buffer0[2];

                                           receive=0;

      }

      };

}

 

 

3.       PC 프로그램에 AVR count 표시한다.

아래와 같이 “NumEdit Control” 추가하고 “Member Variales” 이름은 “m_nCount” 한다.

 

 

 

예제 3-1  AVR 프로그램에 count 값을 전송하는 프로그램을 추가한다.

 

 

interrupt [TIM1_COMPA] void timer1_compa_isr(void)

{

              PORTC=count;   

              putchar(0x02);  // 송신 시작 표시

        putchar(count);   // D포트 상태 전송

              putchar(0x03);  //송신 마침 표시

              count=0;

}

 

 

 

 

예제3-2  PC프로그램에 AVR count 값을 표시한다.

 

 

LONG CRs232Dlg::OnCommunication(UINT port, LONG lParam)

{

              char buff[2048]="";

              BYTE aByte;

 

              int size= (m_ComuPort.m_QueueRead).GetSize();

              for( int i=0; i< size; i++ )

              {

                             (m_ComuPort.m_QueueRead).GetByte(&aByte);

                             if( aByte!= NULL ) buff[i]= aByte;

                             else { i--; size--; }

              }

 

              m_nCount.Value = (int)buff[0];

 

              if(size > 0)

                             m_Edit2.SetWindowText(buff);

              return 0;

}

 

 

 

 

 

예제3-2  그림과 같이 펄스의 개수로 회전 속도를 계산하여 모니터링하는 프로그램을 추가 하였다.

 

 

LONG CRs232Dlg::OnCommunication(UINT port, LONG lParam)

{

              char buff[2048]="";

              BYTE aByte;

 

              int size= (m_ComuPort.m_QueueRead).GetSize();

              for( int i=0; i< size; i++ )

              {

                             (m_ComuPort.m_QueueRead).GetByte(&aByte);

                             if( aByte!= NULL ) buff[i]= aByte;

                             else { i--; size--; }

              }

 

              m_nCount.Value = (int)buff[0];

              m_nRpm.Value = (float)buff[0]/10.*60.;

 

              if(size > 0)

                             m_Edit2.SetWindowText(buff);

              return 0;

}

 

 

 

 

 

 

 

 

 

처음