본문 바로가기

AVR/AVR 연습, Tutorial

AVR 스위치 입력 값에 따라서 LED 제어하기 - AVR 연습하기



이번에는 AVR에 입력을 주어서 LED를 제어해봅니다.

3개의 스위치를 브레드보드에 꼽고 스위치를 누를 때마다 들어오는 LED가 달라지도록 프로그래밍 했습니다.

입력으로 AVR을 제어할 때는 I/O레지스터 중 3가지 (DDRx, PORTx, PINx)레지스터가 모두 사용되고 if 조건문으로 비교해서 결과가 같으면 출력하도록 합니다.


연습 하드웨어 회로는?




기본 LED 연습회로에 푸쉬스위치만 추가된 회로이고 별도의 변경은 없습니다.

모듈의 경우에는 아래 핀번호가 적혀있어서 번호만 보고 맞춰 연결하면 되고, TINY2313을 바로 사용할때는 위 회로도의 핀배치를 보고 연결합니다.

그리고 스위치가 GND에 연결되어있는데 이 때는 코딩시에 입력포트를 풀업(초기상태 1)로 설정해 주어야 스위치 입력 프로그래밍이 가능합니다.

VCC에 연결했을 경우에는 AVR에서 풀다운은 지원하지 않으므로 4,7K정도의 저항을 포트와 GND에 연결해주어야 하고 스위치를 VCC에 연결해야하며 프로그래밍시에 Tri-State(초기상태 0)으로 설정해 주셔야 합니다. 그럼 코드비전 소스코드부터 볼까요!



CodeVisionAVR 용 소스코드


#include <tiny2313.h>    // TINY2313의 기본 입출력 관련 헤더파일을 포함합니다.

#include <delay.h>    // 지연용 함수관련 헤더파일을 포함합니다.


void main(void)    // main()함수를 호출합니다.

{

PORTB=0x00;    // 포트B의 초기값은 8비트 모두 0 (0V)로 설정합니다.

DDRB=0xFF;    // 포트B의 8비트 모두 출력으로 설정합니다.

PORTD=0x70;    // 포트D의 PD6, PD5, PD4를 입력전 1인상태로 설정합니다.

DDRD=0x00;    // 포트D의 7비트 모두 입력으로 설정합니다.

                   

while (1)    // 아래 구문을 무한 반복합니다.

      {

        if(PIND.6==0)    // 포트D의 6번핀의 입력이 0 이면

        { 

        PORTB.4=1;

        PORTB.5=1;

        PORTB.6=1;

        PORTB.7=1;    // 포트B의 4, 5, 6, 7 번 포트에 1 (5V) 출력

        delay_ms(500);     // 위 상태를 0.5초 유지

        }

        if(PIND.5==0)    // 포트D의 5번핀의 입력이 0 이면

        {

        PORTB.0=1;

        PORTB.1=1;

        PORTB.2=1;

        PORTB.3=1;    // 포트B의 1, 2, 3, 4 번 포트에 1 (5V) 출력

        delay_ms(500);    // 위 상태를 0.5초 유지

        }       

        if(PIND.4==0)    // 포트D의 4번핀의 입력이 0 이면

        {

        PORTB.0=1;

        PORTB.1=1;

        PORTB.2=1;

        PORTB.3=1;

        PORTB.4=1;

        PORTB.5=1;

        PORTB.6=1;

        PORTB.7=1;    // 포트D의 0, 1, 2, 3, 4, 5, 6, 7번 전체 1 (5V) 출력

        delay_ms(500);    // 위 상태를 0.5초 유지

        }        

       PORTB=0x00;    // 입력없으면 포트B의 8비트 전체 0 (0V) 출력        

      }

}


코드비전은 비트제어가 쉽기 때문에 입력역시 간단하게 처리가능합니다.
if 조건문에서 0이 되어야 하는 이유는 DDRD에서 입력으로 설정후에 PORTD로 풀업(1) 즉 모든 비트에 아무 입력이 없을 때 1인 상태로 설정해 두었기 때문에 스위치를 누르면 해당비트만 0 됩니다.
이때 if문에서 해당 비트가 0 이 되었는지 확인 후에 0 이면 if문 아래 괄호에 실행하고자 하는 코드를 입력하면 됩니다.



AVR Studio 용 소스코드


#include <avr/io.h>    // AVR의 기본 입출력 관련 헤더파일을 포함합니다.

#define F_CPU 8000000UL    // AVR칩에 사용중인 크리스탈 주파수 값을 상수로 설정합니다.

#include <util/delay.h>    // 지연 함수관련 헤더파일을 포함합니다.


unsigned char pind6, pind5, pind4;    

// 부호없는 Char형으로 pind6, pind5, pind4 를 생성합니다.


int main()    //  main()함수를 호출합니다.

{

PORTB=0x00;    // 포트B의 8비트 전체 초기값을 0 (0V)로 설정합니다.

DDRB=0xFF;    // 포트B의 8비트 전체를 출력으로 사용합니다.

PORTD=0x70;    // 포트D의 PD6, PD5, PD4를 입력전 1인 상태로 설정합니다.

DDRD=0x00;    // 포트D의 7비트 전체를 입력으로 사용합니다.

while(1)    // 아래구문을 무한 반복합니다.

{

pind6=PIND&0x40;    // pind6변수에 PIND과 0x40과 AND연산한 결과를 넣습니다.

pind5=PIND&0x20;    // pind5변수에 PIND과 0x20과 AND연산한 결과를 넣습니다.

pind4=PIND&0x10;    // pind4변수에 PIND과 0x10과 AND연산한 결과를 넣습니다.


if(pind6==0)    // 포트D의 6번핀의 입력이 0 이면

{

PORTB=PORTB|0x10;

PORTB=PORTB|0x20;

PORTB=PORTB|0x40;

PORTB=PORTB|0x80;    // 포트B의 4, 5, 6, 7번 포트에 1 (5V)를 출력합니다.

_delay_ms(500);    // 위 상태를 0.5초 유지합니다.

}

if(pind5==0)    // 포트D의 5번핀의 입력이 0 이면

{

PORTB=PORTB|0x01;

PORTB=PORTB|0x02;

PORTB=PORTB|0x04;

PORTB=PORTB|0x08;    // 포트B의 1, 2, 3, 4번 포트에 1 (5V)를 출력합니다.

_delay_ms(500);    // 위 상태를 0.5초 유지합니다.

}

if(pind4==0)    // 포트D의 4번핀의 입력이 0 이면

{

PORTB=0xFF;    // 8비트 전체에 1 (5V) 출력합니다.

_delay_ms(500);    // 위 상태를 0.5초 유지합니다.

}

PORTB=0x00;    // 입력이 없으면 포트B의 8비트 전체에 0 (0V)를 출력합니다.

}


return 0;    // main함수에 0을 리턴합니다.

}



프로그래밍 후 동작은?



스위치 누르는 것에 따라 하위 4비트 상위 4비트 전체 LED ON 동작합니다.

이 지겨운 회로도 타이머 인터럽트 후에는 한번 등장하고 끝날 겁니다.~~!