본문 바로가기

AVR/AVR 연습, Tutorial

AVR으로 LED ON/OFF 개별 비트 별로 제어하기 - AVR 연습하기


8비트 값으로 전체 LED를 제어해 봤다면 이제 포트 하나하나 즉 비트별로 1 또는 0 값을 줘서 제어 할 수도 있습니다.

코드비전의 경우에는 비트별로 제어하는 방법이 따로 있어서 쉽게 제어 할 수가 있지만 스튜디오에서는 그렇지 못하기 때문에 AND나 OR 비트연산자로 AVR의 포트에 비트별로 각기 다른 신호를 줄 수 있습니다.



연습 하드웨어 회로는?




또 등장...

앞으로 많이 우려먹을 회로인데요. 역시 LED 보호용으로 저항을 달고 LED 연결 후에 그라운드로 연결 하면 됩니다.

모듈이 없다면 브레드보드에 TINY2313과 ISP연결용 커넥터만 만들어 연결해 놓으면 연습용 회로를 꾸밀수 있습니다.

그럼 소스코드를 보겠습니다.



CodeVisionAVR용 소스코드


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

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


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

{

PORTB=0x00;    // B포트의 초기상태를 0 모두 꺼짐으로 설정합니다.

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

                   

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

      {

        PORTB.0=1;    // AVR의 PB0번에 1 (5V)출력

        PORTB.1=0;    // AVR의 PB1번에 0 (0V)출력

        PORTB.2=1;    // AVR의 PB2번에 1 (5V)출력

        PORTB.3=0;    // AVR의 PB3번에 0 (0V)출력

        PORTB.4=1;    // AVR의 PB4번에 1 (5V)출력

        PORTB.5=0;    // AVR의 PB5번에 0 (0V)출력

        PORTB.6=1;    // AVR의 PB6번에 1 (5V)출력

        PORTB.7=0;    // AVR의 PB7번에 0 (0V)출력   

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

        PORTB.0=0;    // AVR의 PB0번에 0 (0V)출력

        PORTB.1=1;    // AVR의 PB1번에 1 (5V)출력

        PORTB.2=0;    // AVR의 PB2번에 0 (0V)출력

        PORTB.3=1;    // AVR의 PB3번에 1 (5V)출력

        PORTB.4=0;    // AVR의 PB4번에 0 (0V)출력

        PORTB.5=1;    // AVR의 PB5번에 1 (5V)출력

        PORTB.6=0;    // AVR의 PB6번에 0 (0V)출력

        PORTB.7=1;    // AVR의 PB7번에 1 (5V)출력

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

      }

}


위 처럼 코드비전에 경우에는 TINY2313의 핀 PB0, PB1 .... 포트가 PORTB.0, PORTB.1 식으로 바로 제어할수 있도록 되어있어서 쉽게 제어가 가능합니다.
하지만 스튜디오의 경우에는 좀 다른데요. 소스코드를 보겠습니다.

AVR Studio 용 소스코드


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

#define F_CPU 8000000UL    // 사용하는 크리스탈 주파수값을 8Mhz 상수로 설정합니다.

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


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

{

PORTB=0x00;    // B포트의 초기값은 0 모두 꺼짐으로 설정합니다.

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

while(1)

{

PORTB=PORTB|0x01;    // 포트B와 1 과 OR연산으로 1 (5V)출력

PORTB=PORTB&~(0x02);    // 포트B와 2의 보수와 AND연산으로 0 (0V)출력

PORTB=PORTB|0x04;    // 포트B와 4 와 OR연산으로 1 (5V)출력

PORTB=PORTB&~(0x08);    // 포트B와 8의 보수와 AND연산으로 0 (0V)출력

PORTB=PORTB|0x10;    // 포트B와 16 과 OR연산으로 1 (5V)출력

PORTB=PORTB&~(0x20);    // 포트B와 32의 보수와 AND연산으로 0 (0V)출력

PORTB=PORTB|0x40;    // 포트B와 64 와 OR연산으로 1 (5V)출력

PORTB=PORTB&~(0x80);    // 포트B와 128의 보수와 AND연산으로 0 (0V)출력

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

PORTB=PORTB&~(0x01);    // 포트B와 1의 보수와 AND연산으로 0 (0V)출력

PORTB=PORTB|0x02;    // 포트B와 2 과 OR연산으로 1 (5V)출력

PORTB=PORTB&~(0x04);    // 포트B와 4의 보수와 AND연산으로 0 (0V)출력

PORTB=PORTB|0x08;    // 포트B와 8 과 OR연산으로 1 (5V)출력

PORTB=PORTB&~(0x10);    // 포트B와 16의 보수와 AND연산으로 0 (0V)출력

PORTB=PORTB|0x20;    // 포트B와 32 과 OR연산으로 1 (5V)출력

PORTB=PORTB&~(0x40);    // 포트B와 64의 보수와 AND연산으로 0 (0V)출력

PORTB=PORTB|0x80;    // 포트B와 128 과 OR연산으로 1 (5V)출력

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

}


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

}


조금 복잡해졌지만 C언어에서 OR, AND연산과 보수값 구하는 방법만 알면 쉽게 이해 할 수 있는 내용입니다. 

AVR도 결국은 계산기라서 숫자로 입출력을 설정하고 10진수로는 다음 표처럼 할당


 PB7

PB6

PB5

PB4

PB3

PB2

PB1

PB0

 128

64

32

16

8

4

2

1


16진수로는 다음 처럼 할당 됩니다.


PB7

PB6

PB5

PB4

PB3

PB2

PB1

PB0

0x80

0x40

0x20

0x10

0x08

0x04

0x02

0x01


따라서 PORTB와 0x80과 OR연산을 하면 0x80이 포트B의 7번째 비트만 1이므로 OR연산은 둘중하나만 1이면 결과가 1이기 때문에 PB7번 비트는 1 (5V) 출력으로 설정되게 됩니다.


AVR Studio에서는 논리 연산 이외에도 쉽게 제어할수 있는 방법이 하나 있는데요, 다음처럼 구성하면 동일한 동작을 확인할수 있습니다. (전체 뼈대가 되는 코드는 동일하고 while문만 보면..)


while(1)

{

PORTB=(0<<PB7) | (1<<PB6) | (0<<PB5) | (1<<PB4) | (0<<PB3) | (1<<PB2) | (0<<PB1) | (1<<PB0);    // B포트에 2진수 값 01010101을 출력합니다.

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

PORTB=(1<<PB7) | (0<<PB6) | (1<<PB5) | (0<<PB4) | (1<<PB3) | (0<<PB2) | (1<<PB1) | (0<<PB0);    // B포트에 2진수 값 10101010을 출력합니다.

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

}


해당 코드도 AVR에서 직접 실행해 보면 동일한 동작을 하는 것을 확인 할 수 있습니다.^


프로그래밍 후 동작은?




한비트 띄고 점등 한비트 띄고 점등 순서 바껴서 깜박깜박 거립니다.

재미없는 동영상이네요... 

다음은 AVR로 순차점멸이랑 2진 카운터를 만들어보고, AVR 입력 포스팅을 하겠습니다.^