학습목표    1

학습주제    1

예습내용    1

실습방법    1

        1

AVR PC 통신 (슬라이드제어)

학습목표

슬라이드를 자동 왕복운동하게 하고 슬라이드 양단에 리미트스위치의 입력을 PC 표시한다.

학습주제

통신 프로토콜

인터럽트가 처리 마다 메시지를 발생하고 입력포트(D포트) 상태를 PC 보낸다.

그림에서 회전 방향과 속도를 제어하고 리미트 스위치의 동작을 알수가 있다.

 

PC프로그램은 “DC모터제어 프로그램을 이어서 만들어 본다.

[소스 프로그램 내려받기]

예습내용

슬라이드가 자동으로 왕복운동하는 AVR 프로그램을 만든다.

 

보기1 슬라이드 자동 왕복 운동 프로그램 [전체 프로그램 보기] [소스 프로그램 내려받기]

슬라이드 양단의 리미트 스위치를 AVR 인터럽트와 연결하여 자동으로 왕복 운동하게 한다.

 

 

// External Interrupt 0 service routine

interrupt [EXT_INT0] void ext_int0_isr(void)

{

// Place your code here

       PORTB=0x12;

}

 

// External Interrupt 1 service routine

interrupt [EXT_INT1] void ext_int1_isr(void)

{

// Place your code here

       PORTB=0x11;

}

 

 

실습방법

   

1. 시스템 설계

슬라이드에 있는 리미트 스위치와 슬라이드 모터를 아래와 같이 연결한다.

2. AVR 프로그램 (인터럽트&메시지 처리)

 

보기2 슬라이드 자동 왕복 운동 프로그램 [AVR프로그램 보기] [소스 프로그램 내려받기]

 인터럽트에서는 메시지(mode) 발생하고 main() while 안에서 메시지를 처리한다. 이렇게 하면 인터럽트에 의해 프로그램의 로직이 깨지는 것을 최소화 있다.

 

 

char mode=0x00;

 

// External Interrupt 0 service routine

interrupt [EXT_INT0] void ext_int0_isr(void)

{

// Place your code here

       mode=0x01;

}

 

// External Interrupt 1 service routine

interrupt [EXT_INT1] void ext_int1_isr(void)

{

// Place your code here

       mode=0x02;

}

=================================

    ……..(생략)

while (1)

      {

      // Place your code here

       if(mode == 0x01) {

               PORTB=0x12;

               putchar(0x02);

               putchar(0x01);

               putchar(0x03);

               mode=0x00;

       }

       else if(mode == 0x02) {

               PORTB=0x11;

               putchar(0x02);

               putchar(0x02);

               putchar(0x03);

               mode=0x00;

       }

       else {

               putchar(0x02);

               putchar(0x00);

               putchar(0x03);

       }

       delay_ms(100);

      };

 

 

PC 프로그램  [소스 프로그램 내려받기]

리미트 스위치의표시는 AVR(입출력제어) 프로그램을 그대로 사용한다.

 

 

3. AVR 프로그램 (인터럽트처리 않함)

인터럽트 처리를 하면 리미트 스위치가 On 때는 감지가 되나 Off 되는 순간은 메시지 처리가 되지를 않는다. 그러므로 인터럽트를 사용하지 않고 메인 함수에서 입력포트를 감시하고 있다가 상태가 변하면 메시지를 처리하는 프로그램을 만들어 본다. 경우에는 CPU 로드가 많이 걸리므로 main에서 처리되는 상황이 많으면 시간 지연이 생길 있다.

슬라이드가 끝까지 동작하고 리미트 스위치가 On 됬을 모터에 전류가 계속 흐르게 되면 모터에 무리가 발생함으로 모터의 전원을 차단하게 하였다.

 

보기3 슬라이드 제어 프로그램   [소스 프로그램 내려받기]

 

 

#include <mega128.h>

// ….. 프로그램 생략

char receive=0,inD,inDpre=0x00;

 

// USART0 Receiver interrupt service routine

#pragma savereg-

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)

   {

   rx_buffer0[rx_wr_index0]=data;

   if (++rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0;

   if (++rx_counter0 == RX_BUFFER_SIZE0)

      {

      rx_counter0=0;

      rx_buffer_overflow0=1;

      };

   };

#asm

    pop  r26

    out  sreg,r26

    pop  r31

    pop  r30

    pop  r27

    pop  r26

#endasm

}

// ….. 프로그램 생략

void main(void)

{

// ….. 프로그램 생략

// Timer/Counter 0 initialization

// Clock source: System Clock

ASSR=0x00;

TCNT0=0x00;

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

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

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

// ….. 프로그램 생략

// Global enable interrupts

#asm("sei")

while (1)

      {

      // Place your code here

         // 모터의 회전과 속도를 제어한다.

         if(receive==1) {

                       if(rx_buffer0[1] == 0x30)

                         PORTB=0x02;

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

                                PORTB=0x01;

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

                                  PORTB=0x00;

                          OCR0 = rx_buffer0[2];  // 듀티비를 바꿔서 회전수를 제어

                           receive=0;

                }

               

                // D포트의 입력값이 변하면 입력 상태를 PC 보낸다. 

                // 리미트 스위치가 동작하면 슬라이드 모터를 정지 시킨다.

                inD = PIND;

                if(inD != inDpre) {

                       if(PIND.0==1) {

                      PORTB=0x00;     // 스위치 On 모터 정지

                      putchar(0x02);

                      putchar(0x01);

                      putchar(0x03);

               }

               else if(PIND.1==1) {

                      PORTB=0x00;      // 스위치 On 모터 정지

                      putchar(0x02);

                      putchar(0x02);

                      putchar(0x03);

               }

               else {

                      putchar(0x02);

                      putchar(0x00);

                      putchar(0x03);

               }

       }

       inDpre = inD;       // 현재의 D포트 값을 저장한다.

 

      };

}

 

 

PC 프로그램  [소스 프로그램 내려받기]

[DC모터제어] 프로그램에 [입출력 제어] Led 표시 부부을 첨가 하였다.

 

 

처음