2014년 6월 4일 수요일

12. AVR(Atmega)와 Proteus VSM 만남 - Timer0에서 1ms 만들기 (2부)

지난 글에 이어서 오늘은 좀 계산을 해보겠습니다.
난데없이 왠 계산?

미적분은 아니니까 너무 걱정마시고, 그냥 곱셈, 나눗셈만 합니다. 그래도 충분 합니다.
아래를 먼저 보시죠. 와 닿으시나요? 아니면 멍~~ 하시나요?


하나하나 차근하게 설명합니다.

1번은,
클럭주파수입니다. 즉, 수정발진자 주파수라고 생각하면 됩니다.
주파수의 역수가 1주기 이므로, 8Mhz의 주기는 0.000000125초 입니다. 인간의 시간 관념에서 보면 순식간이죠!!

2번은,
Timer0에 설정하는 분주비(Prescale)입니다. 우선 Prescale = 1/1024 로 설정하면 마스터클럭이 1024번 진동할때 Prescale을 통해서는 1번 진동합니다. 그리고, 이것이 TCNT0를 하나씩 증가시키는 것이겠죠. 계산을 하면, Prescale이후의 주파수는 7813Hz이고 주기는 0.000128초 입니다. 주파수의 경우는 1024로 나누면 되고, 주기는 1024만큼 곱해주면 바로 나오겠죠.

3번은,
각 단위시간(ms)을 재기 위해서 TCNT0의 값을 몇 정도 카운트해야 하는가를 계산한 것입니다. 1ms(0.001se)의 도달하려면 0.000128(sec)가 7.813번 있으면 되지요. 그렇다면 반올림해서 8로 잡고, TCNT0레지스터를 0부터 8까지 카운트하고 Overflow발생시키고 나서 TCNT0를 초기화(zero)하고 다시 0부터 8까지 카운트하면 되겠죠?

근데, 문제는 지난 글에 설명했듯이 TCNT0의 Overflow는 레지스터가 꽉 차고있는 상태에서 마지막 물 한방울이 더해질때 발생하잖아요.. 그렇기 때문에 약간의 기교가 필요한 것입니다. 그래서 4번이 필요한 것입니다.

4번은,(기교)
3번에서 계산한 약8번의 카운트를 0부터 시작하는 것이 아니라 TCNT0= 248부터 시작하면 어떨까요? 그러면, 8번 카운트할때 255 --> 0로 변하면서 Overflow가 발생하지 않을까요?
예, 맞습니다. 그렇게 하면됩니다. TCNT0의 값을 248부터 시작하고 오버플로우가 발생하면 TCNT0의 값을 다시 248로 셋팅하면 됩니다. 바로 이것이 4번의 내용입니다.

참고로, 위의 4번은 10ms를 발생하려면 약78번 카운트하면 됩니다.(계산해 보세요) 그러므로 TCNT0 = 256 - 78 로 하면 됩니다.

그럼, 1초는 어떻게 하나요? 10ms를 100번 카운트하면 되지 않을까요? 그럼 됩니다.
아니면 타이머0를 사용하면 굳이 위으 4번과 같이 하지 않더라도 간단히 할 수 있습니다. 왜냐하면 Timer1은 16비트 크기의 TCNT1을 갖고 있습니다. 그러므로, TCNT1 = 65536 - 7813 으로 하면 정확히 1초마다 Overflow가 발생하며, 그때 실행하는 ISR(Timer1_OVF_vect)에서 원하는 일을 하면 됩니다.

아래에 샘플 테스트 코드를 좀 적었습니다.
10ms마다 PD5 포트를 ON/OFF(토글)시킵니다. 참고하세요.

// 2. Timer0 Init : Fast PWM Mode
void init_TM0_NORMAL_mode()
{
// TOP = 255(0xFF)
// WGM02:00 = 000 (Normal mode)
// CS02:00 = 101 (Prescale = 1024 ) --> 122Hz(about 8ms = 8000000/1024 = 122)
// Pin mode = None inverting mode

TCCR0A = 0x00; // Mode : Normal Mode
TCCR0B = _BV(CS02) | _BV(CS00); // Prescale = 1/1024

TCNT0 = 256- 78; // 10ms 발생하기 위해서 78번 카운트(즉, 178 ~ 255)

TIMSK0 = _BV(TOIE0); // 오버플로우 인터럽트 인에이블(TOIE0)
}

// 타이머0 오버플로우 인터럽트 서비스 루틴
ISR(TIMER0_OVF_vect)
{
TCNT0 = 256 - 78;
PORTD ^= _BV(PD5); // PD5 토글
}

아래 프로테우스에서는 분홍색이 10ms단위로 ON/OFF하는 PORTD5 입니다.
노란색은 100ms로 ON/OFF합니다. main에 있는 while(1) 루프 안에 있습니다.
어떤가요??


11. AVR(atmega)와 Proteus VSM의 만남 - 타이머/카운터 1초 만들기(1부)

지난 글에서 AVR을 너무 급한 마음에 소개하려고 PWM을 먼저 설명한 것이 좀 후회되네요.
차근 차근 하나씩 쉽게 했어야 했는데...

그래서, AVR에서 제공하는 Timer/Counter 기능들을 하나씩 소개하려고 합니다.
그 중에서도, Timer0의 Normal Mode를 소개하려고 합니다. 그리고, 그것을 이용하여 1초마다 오버플로우 인터럽트가 발생하면 여기저기 쓸만하겠죠?

참고로, AVR에서 지원하는 타이머/카운터 기능은 아래와 같습니다.


위 표를 보시면, 기본적으로 4가지가 있다는 것을 알 수 있죠.(Mode=0,1,2,3)
그리고 아래 두개의 모드(Mode 5, 7)은  모드1, 3번과 거의 같습니다. 다른 점은 TOP값과 Max값이 조금 다르죠. 하지만 모드 1, 3번의 동작만 안다면  이해하는데는 문제 없습니다.

그럼, 오늘은 Timer0의 Normal Mode를 이용하여 1초를 만들어 보겠습니다.

오버플로우(Overflow)란 말을 들어보셨나요? 최소한 물놀이장(워터파크)에 가보셨다면 파라오의 머리통에서 쏟아져 내리는 물세례를 맞아보아다면 오버플로우가 뭔지 온몸으로 느끼실 겁니다. 아래 그림 한번 보시죠!!

어떤가요? 온몸으로 오버플로우(Overflow = OVF)가 뭔지 느껴지시죠? 맞습니다. 디지털의 세계에서도 원리는 정말로 똑같습니다. 파라오 머리의 물통에 물이 점점 차오르고 거의 마지막에 이르면 물통은 확 뒤집히면서 물을 쏟아내죠. 그리고 다시 처음부터 물을 채우기 시작합니다. 우리는 그 아래에서 물통에 물이 다시 차오르기를 기다리고 물이 내려올때 쯤에는 나름대로 뭔가 할일을 준비하여 진행하죠. 두근거리는 마음을 다독인다던가, 아니면 물 쏟아질때쯤 무서워 딴데로 내빼던가. 아무튼, 파라오 물통의 물이 쏟아지는 그 시점이 바로 오버플로우(Overflow)입니다.

그럼, AVR에서는 어떤가 보겠습니다. 위 8비트의 TCNT0에서 보듯이 물통에 숫자 1이 꽉 차있죠. 그리고, 마지막 물(오른쪽 끝의 1)이 차오르면 TOV(Timer Overflow) Flag가 1로 되면서 오버플로우가 발생하는 겁니다. 물론, 물통속의 8개의 1은 모두 0으로 초기화 되는 것이구요. 나는 단지 TOV Flag만 감시하면 TCNT0의 물통속에 물이 쏟아져 내리고 나서 초기화 되었구나! 라고 생각만 하는 되는거죠. 어떤가요, 쉽지 않나요? 바로 TOV Flag가 Set(1)되는 시점에 Overflow Interrupt가 발생하는 것이고, 그 시점에 내가 이미 코딩해놓은 ISR(Timer0_OVF_vect) { ... } 코드가 실행되는 것입니다.

다음 글에  계속...

끝.

2014년 6월 1일 일요일

10. AVR(atmega)와 Preteus VSM의 만남 - 숨쉬는 LED를 위한 PWM 제어 (4부)

글이 점점 길어집니다. 머릿속에서는 간단했는데 활자로 표현하자니 점점 길어만 지는군요! 그래도 지치지 말고 글을 이어 나갑니다.

오늘은 Timer0의 설정을 좀 하려고 합니다. 지난번 올렸던 소스코드 중에서 Timer0의 초기화 함수를 먼저 보시죠.

// Timer0 Init (Atmega 168기준)
void init_TM0_FPWM_mode()
{
// TOP = 255(0xFF)
// WGM02:00 = 011 (FPWM mode)
// CS02:00 = 100 (Prescale = 256 ) --> 122Hz(about 8ms = 8000000/256/256 = 122)
// Pin mode = None inverting mode

TCCR0A = _BV(WGM01) | _BV(WGM00); // Mode : Fast PWM
TCCR0A |= _BV(COM0A1) | _BV(COM0B1); // PWM Out Pin Mode: None Inveting mode
TCCR0B = _BV(CS02); // Prescale = 1/256

TCNT0 = 0; // 초기값 넣기(안넣어도 되지만, 확실히 하기 위해서)
OCR0A = 1; // 안넣어도 됨. 하지만, None inverting mode에서 0값은 튀는 값이라서 1로 넣어줌.
OCR0B = 1; // 위와 마찬가지.(상동)

        // 인터럽트 마스크 설정 : Output Compare Interrupt Enable 0A, 0B
TIMSK0 = _BV(OCIE0A) | _BV(OCIE0B);
}

우선 TCCR0A, TCCR0B는 타이머0의 컨트롤 레지스터입니다. 여기에 어떤 비트(Bit)를 설정하는냐에 따라서 타이머/카운터0의 동작이 결정되지요.
아래 표를 다시 한번 보시죠. 첫번째 그림은 TCCR0A, TCCR0B입니다. TCCR이란 약자의 의미는 아시죠? Timer Counter Control Register (TCCR). Timer0는 두개의 컨트롤 레지스터가 필요하네요. 어떤 atmega칩에서는 TCCR이 한 개만 있는 것도 있거든요. 각 칩마다 다르니까 그건 그때 그때 데이터시트를 참조하시면 되겠지요.

그럼, 하나씩 설명을 하지요.
TCCR0A = _BV(WGM01) | _BV(WGM00); // Mode : Fast PWM 모드 설정
--> 아래에 있는 TCCR0A 레지스터에서 WGM01, WGM00 비트를 설정함. 물론, TCCR0B의 WGM02 비트는 0(Clear)로 설정하므로, 결국 WGM02:00 = 011로 설정하는 것임. 이것이 Fast PWM 모드로 설정하는 것이죠.  아래 Table15-8 참조하세요. 아주 잘 나와 있습니다.

TCCR0A |= _BV(COM0A1) | _BV(COM0B1);
-> 계속해서, OC0A, OC0B Pin의 출력모드를 설정합니다. Non-inverting mode입니다. 이 모드의 동작방식은 지난 글에 이미 설명했습니다. Table15-3 참조하세요. 즉, TCCR0A 레지스터에서 비트 4,5,6,7 을 해당 모드에 맞게 설정해야죠. 위 명령어는 COM0A1(비트7)과 COM0B1(비트5)를 Set(1) 합니다. COM0A0, COM0B0 비트는 clear(0)합니다. 클리어는 따로 셋팅할 필요가 없겠죠? initial value가 0라고 친절하게 나와 있으니까요.
TCCR0B = _BV(CS02); // Prescale = 1/256
--> 분주비(Prescale)을 설정하는 비트입니다. TCCR0B에서 비트0,1,2에 있습니다. 1/256분주비로 셋팅하기 위해서는 CS02, CS01, CS00 = 1, 0, 0 으로 하면 됩니다. 따라서 CS02 비트만 Set(1)하면 되며, 다른 비트는 clear(0)하면 됩니다. 디폴트(기본값)가 0 이므로  CS02만 set합니다.

  TCNT0 = 0; // 초기값 넣기(안넣어도 되지만, 확실히 하기 위해서)
OCR0A = 1; // 안넣어도 됨. 하지만, None inverting mode에서 0값은 튀는 값이라서 1로 넣어줌.
OCR0B = 1; // 위와 마찬가지.(상동)
--> TCNT0는 기본이 0(zero) 이므로 굳이 넣어줄 필요는 없는데, 명시적으로 보여주기 위해서 넣었구요. OCR0A, OCR0B는 1을 넣었는데, PWM 동작시 0값은 특이값이라서 그냥 1을 넣었습니다.(데이터시트 잘 읽어 보시면, 0을 넣을 경우 이상동작에 대해서 설명되어 있습니다.)
TIMSK0 = _BV(OCIE0A) | _BV(OCIE0B);
 --> TIMSK0는 Timer Interrupt Mask 라는 뜻입니다. 타이머0에는 3가지 인터럽트가 가능하죠. 첫번째는 OVF(Overflow), 두번째와 세번째는 OCIE(Output Compare Interrupt Enable)이며 A와 B 두가지가 있습니다. 아래 그림 참조하세요. TOIE0(Oveflow), OCIE0A(Output Compare A), OCIE0B(Output Compare B


마지막으로 잊지 말아야 할 것은, 모든 인터럽트를 활성화 시켜주세요.
sei(); // 모든 인터럽트 활성화
sei() --> Set Enable Interrupt 
이 함수를 실행시켜야만 인터럽트가 동작하기 시작하는 거죠.^^

오늘은 여기까지 하고, 다음에 또 글을 씁니다.

끝.












2014년 5월 30일 금요일

9. AVR(atmega)와 Preteus VSM의 만남 - 숨쉬는 LED를 위한 PWM 제어 (3부)

자... 그럼 이번에는 숨쉬는 LED의 소스 코드를 좀 분석해 봅시다.

지난번 소스코드 한번 들여다 보셨나요? 이미 좀 알고 계신 분이라면 금방 이해하셨을테지만, 모르는 분들을 위해 설명한다 생각하고 글을 써 보겠습니다.

우선, Atmega MCU에서 PWM발생을 위해 이해해야 할 그림이 있어요.
아래 그림 한번 보세요. 이 그림을 보고 지지난 글에서 얘기한 Compare Match Interrupt 이해 가시나요?

[Timer2 Compare Match Output Interrupt]

위 그림은, Timer2로 표현한 그림이지만, Timer0도 마찬가지 입니다.(물론, 콘트롤 레지스터는 조금 다릅니다.)

TCNT2(Timer Counter Register)의 값이 하나씩 증가하죠. 쭉 증가해서 255까지 도달하면 다시 0부터 시작하죠. 이렇게 무한히 반복하는 겁니다. 증가한다는 의미로 0부터 255까지를 우상향 화살표로 표시했어요.(물론, 아날로그 회로에서는 실제 전압이 증가할 수도 있지만..마이크로 프로세서에서는 디지털 시스템이므로 레지스터의 값이 증가합니다.) 
근데, 주목해야 할 것이 중간에 OCR2(Output Compare Register)가 있고 수평으로 조그만 막대가 있죠. 이것은 OCR2에 들어 있는 값을 의미하는 것입니다.(여기서는 OCR2=100으로 가정)

 그럼, 인간의 시간 개념으로 타이머를 돌려 봅시다.

1. TCNT2 증가 시작: 0, 1, 2, 3, ......
2. 비교일치 조건 도달 ( 즉, TCNT2 == 100일때 OCR2의 설정값과 일치)
3. 비교일치 인터럽트 발생 --> ISR(TIMER2_Comp_vect) 실행됨.
4. TCNT2 계속 증가: 101, 102, ..... 254, 255
5. TCNT2가 255 --> 0으로 바뀌는 순간
  • 오버플로우 인터럽트 발생 : ISR(TIMER2_OVF_vect) 실행됨
6. 다시 1번부터 시작됨. 무한반복

그리고, OC2 Pin 출력을 보면 이것이 바로 PWM 출력입니다. 지난번 글에서 아래 내용 기억나시나요? Non-inverting mode!!
위의 OC2 Pin 출력을 보면 BOTTOM(= 0)에서 High(5V)출력이고, 비교일치(Compare Match)되는 순간(TCNT2 == OCR2 )일때 Clear(Low = 0V)로 내려갑니다. 그리고, 다시 TCNT2가 BOTTOM(=0)으로 가면 다시 High(5V). 그리고 비교일치되면 Low(0V). 이런식으로 무한히 반복되죠. 그럼, 아래 내용이 뭔 의미인지 이해됩니다!!

(원문)
"Clear OC0A on compare match, set OC0A at BOTTOM, (non-inverting mode)"

(해석)
"OC0A 핀(12번 핀: PD6 )을 클리어(논리적으로는 0, 전압으로는 0V)하고, TCNT0 = BOTTOM(0 즉 zero)일 때, 셋(set)한다.(논리적으로 1, 전압으로는 5V)"

그렇다면, Duty Rate를 바꾸려면 어찌해야 할까요?
쉽습니다. 위 그림에서 직관적으로 알 수 있다시피 OCR2의 값을 내부적으로 적당한 때에 바꿔주면 됩니다. 만약, OCR2 == 50이면 위 그림보다 Duty Rate가 절반으로 줄어들 것이며, OCR2 == 200이면 Duty Rate가 위 그림의 두 배가 될 것입니다. 이런 식으로 Duty Rate를 조절하면 LED밝기를 변화시킬 수 있으며, OCR2의 값을 0부터 하나 씩 증가시켜 255까지 가면 자연스럽게 밝아지는 LED가 되죠. 즉, 숨쉬는 LED가 된 것입니다.

잠시 바쁜 관계로,, 오늘은 여기까지.

이만, 총총.

2014년 5월 29일 목요일

8. AVR(atmega)와 Preteus VSM의 만남 - 숨쉬는 LED를 위한 PWM 제어 (2부)

지난 글에 이어,, 숨쉬는 LED를 제어하기 위한 PWM제어입니다.

이제는 PWM이 무엇인지 좀 감이 잡히시는지요?
'백문이불여일견' 이라서,, PWM동영상 하나 보여드리죠. 제가 간단히 만든겁니다.

[PWM 제어 동영상]

인간의 눈으로 보는것과 동영상으로 촬영한 것은 좀 느낌이 다르긴 하지만,, 그래도 LED의 밝기가 자연스럽게 변화하는 것이 보이시죠? 바로 그것입니다.

[숨쉬는 LED 회로도(Proteus VSM에서)]


위의 회로도를 간단히 설명하면,

  • PD0 : LED Green (지난번 강좌때 동작시켰던 LED. 10ms 주기로 On/Off)
  • PD5 : LED Yellow (Timer0의 OC0B Pin으로 동작. PWM 출력 나옴)
  • PD6 : LED Red (Timer0의 OC0A Pin으로 동작. PWM 출력이 나옴)
나머지는 지난 번과 동일합니다.

그럼, Proteus로 동작을 시켜보겠습니다.

[Proteus VSM 시뮬레이션 동영상]

어떤가요? Duty Rate(On/Off 시간)가 변하는 것이 보이나요?
보이면, PWM 신호를 구분할 수 있는 능력이 생긴겁니다.
좀더 확실한 이해를 위해서 아래에 그림을 하나 캡쳐했습니다.

오실로스코프에서...
  • 분홍색 - PD5(OC0B)
  • 파랑색 - PD6(OC0A)
  • 노란색 - PD0
아래 스코프 그림을 보면, 분홍색과 파란색의 Duty Rate가 다릅니다. 제가 아래 소스코드에서 OC0A와 OC0B의 Duty Rate를 반대로 움직이도록 코딩했거든요. 그래서, 한쪽의 듀티레이트가 서서히 증가할 때(256단계로 증가함) 다른 한쪽은 서서히 감소합니다.

PWM 주파수는 대략 122Hz 정도로 셋팅했죠.(아래 소스코드를 보면 다~~ 나옴)
노파심에 간단히 계산해 봅시다.

Master Clock Freq. = 8 Mhz = 8000000 Hz
Prescale = 1/256
Timer0 TOP value = 256 (Timer0 의 Fast PWM mode with fixed TOP value)

PWM 주파수 = Master Freq / Prescale / Timer TOP value 
                   = 8000000 / 256 /256 = 122.07 Hz

그래서, 아래 그림에서 스코프의 X축 Time Scale은 2ms/Div입니다. 즉 한 칸당 2ms 입니다.
그러므로, 주기는 노락색이 5칸(10ms), 파란색이 약4칸(8ms), 분홍색도 약4칸(8ms)



참고로, 아래에 소스 코드를 첨부합니다.
소스코드 설명은 다음에 시간날때 한번 할 예정입니다.

이만 총총.

------------------------------------------------------------------------
[Source code at Atmel Studio6.0]


#define F_CPU 8000000L   
#include <avr/io.h>
#include <avr/sfr_defs.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define BYTE unsigned char
// -------------------------------------------------------
// Timer 0 ISR Routine
// -------------------------------------------------------
BYTE t0cnt = 0;
BYTE UDFlag = 0;

ISR(TIMER0_COMPA_vect)  // PD6: CH4 PWM out
{
// nothing
if(UDFlag == 0)
{
t0cnt++;
OCR0A = t0cnt;
if(t0cnt == 255) UDFlag = 1;
}
else
{
t0cnt++;
OCR0A = 256 - t0cnt;
if(t0cnt == 255) UDFlag = 0;
}
}

ISR(TIMER0_COMPB_vect)  // PD5: CH5 PWM out
{
// nothing
OCR0B = 256 - OCR0A;

// Timer0 Init
void init_TM0_FPWM_mode()
{
// TOP = 255(0xFF)
// WGM02:00 = 011 (FPWM mode)
// CS02:00 = 100 (Prescale = 256 ) --> 122Hz(about 8ms = 8000000/256/256 = 122)
// Pin mode = None inverting mode
TCCR0A = _BV(WGM01) | _BV(WGM00); // Mode : Fast PWM
TCCR0A |= _BV(COM0A1) | _BV(COM0B1); // PWM Out Pin Mode: None Inveting mode
TCCR0B = _BV(CS02); // Prescale = 1/256
TCNT0 = 0; // 초기값 넣기(안넣어도 되지만, 확실히 하기 위해서)
OCR0A = 1; // 안넣어도 됨. 하지만, None inverting mode에서 0값은 튀는 값이라서 1로 넣어줌.
OCR0B = 1; // 위와 마찬가지.(상동)
TIMSK0 = _BV(OCIE0A) | _BV(OCIE0B); // Set interrupt mask : Output Compare Interrupt Enable 0A, 0B
}

int main(void)
{
cli(); // 모든 인터럽트 정지.
DDRD = 0xFF; // 모두 출력으로 설정.
PORTD = 0x00; // 출력 초기값은 Off(0V)로 설정.
init_TM0_FPWM_mode(); // Timer0의 초기화 함수. (위에 정의 한 것들)
sei(); // 모든 인터럽트 활성화
    while(1)
    {
        //TODO:: Please write your application code 
_delay_ms(10); // Delay 100ms
PORTD ^= _BV(PD0); // PD0 비트를 XOR 함. 즉, 토글되도록 함. 그래야 LED 깜박임.
    }
}


7. AVR(Atmega)와 Proteus의 만남 - LED를 숨쉬게 하자!! 터미네이터의 눈처럼.. PWM 제어하기!! 1부

오랫만에 글을 다시 올립니다. 이래 저래 정신이 없다보니... 변명 아닌 변명이네요.

오늘은 무엇을 할꼬 하니... 지난 시간에 했던 LED를 좀 더 고급스럽게 제어를 하려고 합니다. 고급스럽게 제어한다고 함은... LED를 좀 더 부드럽게 깜박인다고 할 수 있죠..

혹시, 영화 터미네이터의 빨간 눈알을 기억하시나요?
터미네이터의 전원이 꺼질무렵 빨간 눈빛이 서서히 어두워지고, 다시 살아날때는 다시 서서히 밝아지는 거요..



느낌이 잘 와닿지 않으시다면.. 음... 크리스마스 트리 장식용 LED를 생각하시면 금방 이해가 갈 겁니다. 서서히 환해졌다가 서서히 어두워지는 패턴을 반복하는 것 기억나시죠? 그런 것들이 모두 PWM 방식으로 LED(또는 모든 전구)를 제어 하는 것이죠.

그럼, PWM이란 무엇인가?? 한번 알아봅시다.

  • PWM = Pulse Width Modulation (펄스 폭 변조)
간단히 용어를 음미해 보면,, 펄스의 폭을 변화시킨다는 거죠? 맞습니다. 그게 끝입니다.
즉, 펄스의 ON되는 폭을 늘였다 줄였다 하는 것이죠. 역으로 생각을 해보면, OFF되는 시간이 줄었다 늘었다 하는 것으로도 생각할 수가 있죠. 아래 그림을 보시죠.



펄스(Pulse)는 주기가 있죠. 위의 예에서는 1/500sec이므로 2ms입니다. 
  • 주기(Period) = 2ms (1/500 sec)
  • Pulse ON Time
    • 1번 = 2ms x 5% = 0.1ms
    • 2번 = 2ms x 50% = 1.0ms
    • 3번 = 2ms x 90% = 1.8ms
이와 같이, 펄스의 폭을 변화시킴으로써 5V를 유지시키는 시간을 변화시킬 수 있는 것이죠. 만약, 위의 펄스가 LED를 구동시키는 입력이라면, 1번 보다는 2번이 더 밝을 것이며, 2번 보다는 3번이 더 밝겠죠. 

좀더, 재밌게 해보자면, 입력 순서를 아래와 같이 하면 어떨까요?

입력순서: [1번 --> 2번 --> 3번 --> 2번 -->1번 --> 2번 --> 3번 --> ....]

그러면, 예상하시듯이 LED 불빛이 점점 밝았지다가 다시 점점 어두워지고, 다시 점점 밝아지고.. 어두어지고... 이렇게 무한 반복을 하겠죠.^^ 이것이 곧, 숨쉬는 LED의 원리 입니다.



오우케이!! 여기까지는 다 이해하겠는데... 도대체 어떻게 저런 파형을 내 맘대로 제어할 수 있는거죠? 이런 의문이 당연히 들겠죠. 맞습니다. 당연히 이런 의문을 가져야죠. 그리고 그 방법을 찾아 보는 노력을 하는 것이 엔지니어(공학자)의 역할 아닌가요?

우리의 수고를 덜어주기 위해서, Atmel사에서는 친절하게도 아주 편리한 Atmega 칩을 만들어서 그 속에 아주 강력한 타이머(Timer) 기능을 구현해 놓았습니다. 우리는 그 사용법을 조금 공부하고 편하게 쓰면 그만인 거죠. 물론, 그 원리는 알고 써야곘죠.

그럼, 데이터시트를 한번 보시죠.


위 데이터시트를 보면, 타이머/카운터 제로(Timer/Counter 0)는 여러가지 기능이 있습니다. 우선 8비트 크기이며, Timer0에는 두개의 독립적인 출력비교 장치(Output Compare Unit)가 있습니다. 즉, Timer0 하나를 가지고 두개의 출력(독립적)을 낼 수 있죠. 좀 더 쉽게 얘기하자면, Timer 0를 써서 두개의 LED를 구동할 수 있습니다. 그것도 각각 따로따로. 어떤가요? 좋지 않나요. 타이머0의 블럭다이어그램은 아래와 같습니다.


각 레지스터(Register)의 기능을 간단히 설명할께요.

  • TCNTn 
    • Timer CouNTer 이것은 0부터 255까지 1씩 증가. 다시 0 --> 255 증가.
    • 물론, 증가를 하기 위해서는 Tn(Clock)이 들어와야 하죠.
    • Tn 앞단에는 Prescaler(분주기)가 있죠? 이것을 통해서 클럭 속도를 줄일 수 있어요.
    • 예를 들면, Tn = 8Mhz, Prescale = 1/8 이면 clkTn = 1Mhz가 되죠. 이것에 맞춰서 Edge Triggering에 맞춰서 TCNT 레지스터의 값이 1씩 증가하는 거겠죠..
  • OCRnA
    • Timer0의 경우에는 OCR0A라고 써야겠죠. 
    • 의미는, Output Compare Register 우리말로 하면, 출력 비교 레지스터(저장소)
    • 예를들어, OCR0A = 100 이라고 하면 TCNT0의 값이 0부터 시작해서 쭉 증가하다가 100에 도달하면 뭔가 내부적으로 비교일치(Compare Match)신호가 발생해요. 비교일치신호는 s/w내부적으로는 인터럽트(Interrupt)로 발생하고 외부적으로는 OC0A Pin에 신호가 나오죠.(즉, 예를들면,0V에 있다가 비교일치가 발생하면 5V로 바뀌는 것. 그 반대의 경우로도 설정하여 동작할 수도 있음. 설정하기 나름이죠.) 이후 TCNT0는 100을 넘어서 255까지 쭉 증가하다가 다시 0부터 시작하죠. 그리고 또 100에 도달하면 또 비교일치신호 발생. 이렇게 무한번 반복하는 것입니다. 그것도 아주 빠르게...
    • 위의 블록다이어그램에서 보면 OCR0A와 TCNT0가 화살표로 등호(=)표시가 있죠? 이 의미가 서로 비교해서 같으면(equal = ), 오른쪽 화살표가 쭉~~ 가서 하나는 OC0A(Int. req= Interrupt request)에서 s/w인터럽트로 발생하고, 또 하나는 waveform generator를 거쳐서 OC0A pin을 통해서 전기적 신호(0V 또는 5V)로 나오는 것입니다. 설명이 기네요....^^
  • OCRnB
    • 바로 위의 OCRnA와 동일합니다. 이렇게 A, B 두 가지가 있으므로, 독립적으로 두개의 신호(OCnA, OCnB)가 발생하는 것이죠. 물론, OC0B 핀에서는 전기적 신호가 발생하구요.
    • 나머지는 위의 OCRnA와 동일합니다.
  • TOVn(Int. req.)
    • 이것도 뭔가 신호가 발생한 것이죠. 근데 이름이 Timer OVerflow 입니다. 즉, TCNT의 값이 넘치면(Overflow)되면 발생하는데... 넘친다는 의미가 뭘까요?
    • 그건, TCNT의 사이즈가 8비트 이므로 0부터 255까지 증가하다가 그 다음이 0으돌아가죠. 이때, 255 --> 0으로 바뀔때가 Overflow입니다. 이때 s/w 인터럽트가 발생하고 s/w 내부적으로 이 순간에 뭔가 원하는 동작을 할 수 있습니다.
  • TCCRnA, TCCRnB
    • 이건, 제어를 위한 레지스터 입니다. 두 개가 있느네요.
    • Timer Counter Control Register 란 뜻입니다.
    • 제어 레지스터에 몇가지 설정을 하는데.. 별 것 없어요.
    • 세가지만 확실히 설정하면 끝!!
      • 1. Timer0의 동작 모드 결정하기 --> WGM00, WGM01, WGM02
      • 2. Prescale(분주비) 정해주기 --> CS00, CS01, CS02
      • 3. 출력핀 사용 여부 결정하기 --> COM0A1, COM0A0 또는 COM0B1, COM0B0

그럼, 차례대로 아래 그림을 보죠.

첫번째, Timer0의 동작모드 결정(WGM00, WGM01, WGM02)

여러가지 모드가 있죠? 근데, 보통 자신이 자주 사용하는 모드가 있더라구요. 
제가 자주 쓰는 모드는 아래 붉은색 부분입니다. Fast PWM.


2. Prescale(분주비) 정해주기 --> CS00, CS01, CS02

TCCR0B의 오른쪽 3비트가 분주비(Prescale)을 결정합니다. Maser Clock이 주파수가 너무 높으면, Timer를 동작시키기 위한 원하는 주파수로 조금 낮출 수 있어요.
예를들어, Master Clock 주파수가 8Mhz라고 하고, Prescale을 1/64로 하고 싶다면 아래 표15-9에서 처럼 선택하면 됩니다. 그러면, 실제 Timer0로 입력되는 주파수는 8M/64 = 125khz입니다. 이런 식으로 주파수를 낮출 수 있어요. 만약 그냥 8Mhz 넣고 싶다면 CS00=1로만 하면 되죠. 즉, no prescaling.




3. 출력핀 사용 여부 결정하기 --> COM0A1, COM0A0 또는 COM0B1, COM0B0

만약, Timer0의 비교일치(Compare Match) 신호를 외부 핀으로 전기적 출력(간단히 말하면, 0V, 5V의 전기적 출력)으로 하고 싶을 경우 설정하죠. 
간단히 예를들어, Timer0가 fast PWM으로 설정되었을 경우, COM0A1=1, COM0A0=0으로 설정하면,, TCNT0 = OCR0A 와 값이 비교일치(Compare Match)할 때, OC0A 핀으로 출력이 나옵니다. 어떻식으로 나오느냐? 아래 설명을 읽어보세요.

(원문)
"Clear OC0A on compare match, set OC0A at BOTTOM, (non-inverting mode)"

(해석)
"OC0A 핀(12번 핀: PD6 )을 클리어(논리적으로는 0, 전압으로는 0V)하고, TCNT0 = BOTTOM(0 즉 zero)일 때, 셋(set)한다.(논리적으로 1, 전압으로는 5V)"

이해 되시나요?


(atmega 168)

아무튼,, 오늘은 여기까지 해야겠네요.
글을 쓰다보니, 잔소리가 늘어서 길어지네요.
조만간 다음 글을 쓰겠습니다.

이만 총총.


2014년 5월 15일 목요일

6. AVR(atmega168) 프로그래밍 하기 - ISIS Proteus 사용해서 LED 켜보기.

좀 바뻤던 핑계로 이제 다시 글을 씁니다.
이번에는 Atmega168에 프로그램밍을 하도록 하려고 합니다.
그런데, 실물 하드웨어를 납땜해서 만들기 보다는(물론, 이미 갖고 놀만한 실물은 있지만..) Proteus를 사용해서 돌려보려고 합니다. 코드는 Atmega Studio 6.0을 사용할 거구요.

그럼, 오늘 할 것을 간단히 소개합니다.

1. 주제: Atmega168을 이용해서 LED 깜박이기
2. 준비물

  • ISIS Proteus 7.0 (아니면, 더 좋은 버전으로)
  • Atmega Studio 6.0 (아니면, 더 좋은 버전으로)
  • 끝.
3. 어떻게?
  • Proteus로 간단히 회로를 그린다.
  • Atmega Studio로 간단한 코딩을 한다.
  • 컴파일하고, ELF파일을 Proteus에 연결한다.
  • 그리고, Simultation 버튼을 누른다.
  • 끝.
말로만 하니까 뭔가 와닿지가 않죠? 그럼, 아래 그림을 보세요.



이것이  프로테우스로 시뮬레이션을 하기 위한 회로도 입니다.
회로는 최대한 간단하게,, PD0에는 LED(Green)을 연결했고, Reset을 위한 간단한 회로와 전원 연결 표시용 LED(RED)만 되어 있지요.

Green LED를 구동시키기 위해서는 PD0(Port D의 0번째)에 On(0V), Off(5V) 신호만 해주면 LED가 깜박이겠죠. 즉, Green LED(D3)의 Anode(양극:삼각형 표시쪽)가 R13에 연결되어 Vcc(5V) 전원단에 연결되어 있잖아요.. 그리고, Green LED의 Cathode는 PD0에 연결되어 있지요. 따라서, PD0의 출력상태(On or Off)에 따라서 Green LED는 켜지거나 꺼지는 거죠.


다시 요약하면,

PD0 = Off(0V) --> Green LED 동작 --> 켜짐.
PD0 = On(5V출력) --> Green LED 미동작 --> 꺼짐.

아시겠죠?

참고로, LED 사용시는 대략 200~300오옴 정도의 저항을 붙여 주세요. LED오래 쓰시려면요.
안그러면, 훌러덩 맛이 가는 사태가 발생할 수 있어요.

왜그러냐구요?

일반적으로 다이오드(LED도 다이오드니까..)는 forward voltage조건이 넘어서면 미친듯이 전류가 증가하죠. 다이오드 특성그래프 한번 찾아 보세요. 대충, 0.6V 넘어서면 훌러덩 전류가 급증하잖아요. 그러다보니, 얘를 제어할 필요가 있죠. 한마디로, 다이오드는 조울증 환자에요. 어떤때는 Off였다가 조금만 기분이 맞으면(즉, Forward voltage조건 충족시) 금새 미친듯이 전류가 증가해요. 그래서, 약이 필요한데,, 그것이 바로 R13 저항이죠. 

내친김에, 아래 스펙을 보세요. Green LED의 것인데, Vf=2.2V, If = 10mA 정도죠.
그럼, Green LED에 흐르는 전류를 계산해봅시다. 

I(D3) = (Vcc - Vf) / R13 = (5.0 -2.2) / 220 = 12.7 mA 
(시뮬레이터에서는 11.5mA 로 나오네요)


아무튼, 이렇듯 LED 사용시에는 LED를 보호하기 위한 전류제한용 저항을 꼭 잊지 마세요.


그럼, 소스코드를 좀 보겠습니다. Atmega Studio 6.0 을 사용하고 있습니다.
(Atmega Studio 관련해서는, 제가 지난 글 올린 것 참조하세요)
보시면, 직관적으로 알 수 있습니다. 순서를 간략히 얘기하자면,

  1. PORTD의 입출력 모드를 설정해주고,
  2. PORTD의 초기값을 넣어 주시고, (물론, 이 경우에는 PD0의 값만 넣어도 됨)
  3. 무한루프(while(1))에 원하는 코드 넣기.(XOR을 사용하여 PD0를 토글 시킴)
참고) 깜박이는 것이 보이게 하기 위해서 Delay 100ms를 넣어줌. 안그러면 너무 빨라서 안보임.

Proteus에는 오실로스코프도 준비되어 있어서,, PD0를 파형을 한번 볼께요.
정확히, 100ms 단위로 On/Off 되지요.



이왕 한김에, 동영상도 캡쳐했어요. 보시죠.




오늘은, 여기까지 하구요..

앞으로 조금씩 글을 올리면서 재밌는 것을 해볼께요.
저도 좀 자료도 찾아보면서 공부를 좀 해야 겠네요..^^

그럼, 이만 총총.




2014년 4월 27일 일요일

5. AVR(Atmega168) 간단히 살리기 - 내부 RC Oscillator 로 살리기(2)

지난 글에 이어서, 내부 RC Oscillator를 사용하여 Atmega 살리기를 계속 해 보겠습니다.

지난 글에서 중요한 것은, USB ISP 연결을 위한 6 Pin 연결이었습니다. 그림대로 USB ISP와 Atmega168을 연결했다면, USB ISP를 PC의 USB단자에 연결하면, Atmel Studio를 이용해서 Atmega의 내부를 프로그래밍 할 수 있습니다. 즉, 아주 간단한 것 만 셋팅하면 별다른 외부 회로 없이 Atmega를 돌릴 수 있는 거죠.

지난번에 이미 말씀드렸 듯이, 왠만한 것은 모두 데이터시트에 다 나와있다고 했죠? 예 맞습니다. 구글에서 "atmega168 datasheet"라고만 치면, 주르르르 해당 자료가 팍팍 나옵니다. 그것을 자기 PC에 다운로드해서 한번 보세요.. 그것에 익숙해져야만이 앞으로 그 어떤 것을 보더라도 두려움이 없어집니다. 그냥, 인터넷에 나오는 개개인의 간단한 테스트 내용만으로는 전체 그림을 볼 수가 없습니다. 꼭, 데이터시트를 다운로드해서 목차부터 천천히 보세요..시작이 곧 반입니다.^^

그럼, 보시죠..  아래 캡쳐 그림은, 데이터시트 28페이지 입니다.
내용은 즉,

"이 장치는 내부 RC오실레이터가 8Mhz로 맞춰져 있으며, CKDIV8 항목이 프로그램되어 있어서 최종적으로는 1Mhz 클럭으로 셋팅되어 출하됩니다."



어떠신가요? 사용자가 별도로 셋팅을 하지 않으면, 내부 RC오실레이터는 8Mhz짜리가 들어있으며, 그것을 CKDIV8 설정으로 1Mhz로 분주(Prescale)되어 내부에 클럭이 공급된다는 거죠. 만약, 분주를 하지 않고 8Mhz로 동작시키고 싶다면, CKDIV8을 셋팅하지 않으면 되는거죠. 쉽죠? 정말 쓰기 편하게 만들었네요.

그렇다면, CKDIV8은 어디에서 셋팅하는 걸까요?

그건 바로, Fuse Bit 셋팅하는 곳에 있어요. Atmel Studio에서 읽어들인 Fuse Bit셋팅을 보세요. 아래 그림 보세요. "CKDIV8"이 기본(Default)로 셋팅되어 있기때문에, 체크마크를 해제하시면, Atemga168은 8Mhz의 클럭으로 동작되는 것입니다.

쉽죠?? 직접 해보면 더 쉽다는 것을 알 수 있죠..



오늘은, 여기까지 하구요, 다음 글에서는 Atmel Studio를 가지고 간단한 프로그램을 다운로드 해 보겠습니다. 그것도 너무 쉽고 간단하게 되어 있어요. Atmel社에서 정말로 사용자를 친구로 생각해서 유저프랜들리하게 만들었습니다.~~

그럼, 이만 총총.

끝.





2014년 4월 25일 금요일

4. AVR(Atmega168) 간단히 살리기 - 내부 RC Oscillator 로 살리기

이번 글에서는, Atmega168을 살리려고 합니다.

노파심에,,, 저는 왠만한 내용은 해당 데이터시트에서 찾아봅니다. 이미 다 나와 있습니다. 그것만 잘 보면, 굳이 인터넷상의 이곳저곳 돌아보면서 내용을 찾을 필요가 없습니다. 가능하면 데이터시트를 보면서 공부하세요. 그것이 정답입니다.(물론, 좀 영어로 되어 있으니까... 좀 그렇긴 하지만..)

[데이터시트 다운로드]
Atmega168,88,48 datasheet

Q) 그런데, 흔히들 하는 외부 XTAL(크리스탈 오실레이터: 우리말로 하면, 수정발진자)을 사용하는데,, 그것 없이 어떻게 MCU(atmega168)가 동작을 하죠? 클럭을 발생시켜서 넣어줘야 하지 않나요?(아래 그림처럼)



A) 물론, 클럭이 필요합니다. 하지만, AVR에서는 꼭 외부 수정발진자(XTAL)을 사용하지 않더라도, 이미 내부에 클럭발생 장치가 들어있습니다. 그것도 8Mhz의 주파수로!! 너무나 편하지요..^^


그러니까, 외부에 굳이 크리스털오실레이터(수정발진자)를 달아주기 위한 회로가 필요없는거죠. 얼마나 간단하고 좋습니까? 돈도 절약, 수고도 절약!!

그럼, 데이터시트를 봅시다. (27페이지)
아래 그림을 보시면, 이미 내부에 Clock 소스로 선택을 여러가지로 할 수 있습니다.
즉, 외부 Crystal Oscillator 또는 내부 RC Oscillator를 선택 가능 합니다.(노란색 표시부분)
그래서, 저는 굳이 외부 크리스탈 회로를 추가하여 클럭을 넣어주기 보다는, 좀더 간단한, 아주 간단한 내부 RC Oscillator를 사용할 겁니다.


그럼, 내부 RC OSC.를 사용하기 위해서 준비해야 할 것이 뭐냐구요? 글세요.... 정답은 "준비할 것이 아무것도 없다" 입니다. 단지 Atmega168을 USB ISP를 이용하여 전원넣고 연결만 하면 끝이지요. USB ISP연결하면 기본(Default)로 내부 RC OSC.사용 준비가 끝난거죠..
너무나 쉽죠...

그럼, 시작해 보죠. 이제 간단히 살려봅시다.
준비물은 아래와 같습니다.

1. USBISP MK2
2. 6 핀 케이블
3. Atmega168(또는 자기가 가지고 있는 것으로 해도 좋음)
4. 인두기, 납, 전선 몇 가닥.
  

 아래 그림과 같이 간단히 연결하세요. 그럼,, 일단 끝입니다. 그리고 나머지는 Atmega Studio를 동작시키는 일만 남은 겁니다. 아래 연결 방법은 아시겠죠?
참고 삼아 위에도 6핀 커넥터의 번호 배치를 잘 보세요. 자기 힘으로 해보시면, 생각보다 간단하다는 것을 아실 겁니다.



위와 같이 연결하여 납땜을 끝내셨다면,,, 거의 다 한겁니다.
그러면,,

1. 6 핀 커넥터를 연결합니다.
2. USBISP 를 자기 PC의 USB단자에 연결합니다.
3. Atmel Studio 6을 실행시킵니다.
4. Tools --> Device Programming 클릭
5. Device선택(나의 경우는 Atmega168) --> Apply 클릭
6. Interface Setting에서 ISP Clock = 125kHz 선택. 좀 더 높은걸 해도 상관없음.
7. Fuses 클릭 --> 그러면, 아래에 Reading.... 어쩌구 저쩌구 나오면 성공!!

아래에 동영상을 첨부하오니, 한번 보세요. 단번에 이해될겁니다.


위와 같이 따라해서 성공하셨다면,, Atmega칩과 Atmel Studio는 서로 통신이 되는 겁니다.
부디 성공하시길..

다음번에는 Fuse bit 설정과 Atmel Studio에서 프로그래밍 하는 방법을 설명합니다.

그럼, 이만  총총..

끝.







2014년 4월 23일 수요일

3. AVR(Atmega168) 개발환경 --> 정말 간단해요!!

주제- Atmega168 개발 환경 구축(식은 죽 만들기죠)

지난번 글에 올린 Atmega168의 Pinout(다리배치)는 익숙하게 봐두셨나요?
다시 한번 복습하자면,,

PB0,1,2,3,4,5,6,7 (총 8개)
PC0,1,2,3,4,5,6   (총7개)
PD0,1,2,3,4,5,6,7 (총8개)
VCC(1개), GND(2개), AREF(1개), AVCC(1개)

간단히 산수 계산하면, 총 다리숫자는 28개죠? 데이터시트 보시면 딱 맞겠죠..
예~~ 맞습니다. 이게 전부랍니다. 이것만 알면 간단히 살리는 것은 식은 죽 먹는 것보다 더 쉽답니다. 살리는 건 좀 이따 하구,, 우선 개발환경에 대해 얘기할께요.

개발환경구축? 뭐,, 거창한 일 같지만 생각보다 간단??? 합니다. 정말로...
준비물은 다음과 같습니다.

1. PC에 Atmel Studio 6.1를 설치한다.
2. USB ISP를 하나 장만한다. (저의 경우는, USBISP MK2. 어디서 얻은거죠..)
3. Atemga168(또는 88 아니면 48, 없으면 아무거나...)
4. 인두기, 납, 전선 몇 가닥(약 6개 정도면 일단 끝!!)

하나하나 차례대로 설명합니다.

1번: 여기서 다운로드해서 PC에 설치하세요. 그냥 쭉쭉 기본으로 설치하면 됩니다.
[다운로드] Atmel Studio 6.1

2번: USB ISP MK2 (ISP6핀용 Flat Cable도 함께 사세요)
(아래 그림입니다. 다른것 쓰셔도 상관없을듯... 저는 일단 이것 씁니다. 자작 하시는 분도 있으니까,, 그리 어려운 물건은 아니지요.. 참고로, 이것 내부에도 Atmega칩 들어있어요..)


3번: 어디서 한개 구하세요. PDIP타잎이면 좋구요. 그래야 만능기판에서 하죠.


4번: 이것도 어디서 한번 구해보세요. 만물상가서 조그만 것 사셔도 되구요..



설명하다 보니까 은근히 많아지네요. 하지만 이건 별것 아니에요. 정말로 기초적인 것이니까요. 이런 준비가 있어야 Atmega의 은밀한 부분을 들여다 볼 수 있어요. 아무튼 뭔가를 하려면 기초적인 준비가 필요하죠..

오늘은 여기까지.. 꼭 해보시길.. 최소한 atmega studio와 USBISP는 갖고 계셔야만 다음에 할 얘기들이 뭔지 알수 있어요..

오늘은 여기까지..

이만 총총.






2. AVR(Atmega168) 가지고 놀아보기(1탄) - 쉽게 쉽게, 그리고 천천히..

두번째 글입니다.
우선, 제가 우연히 만나게 된 Atmega168을 가지고 설명을 하겠습니다.

(혹시나, 걱정1)
나는 Atmega168이 아니라 다른 칩을 가지고 있는데.. 어쩌지요?

(대답1)
물론, 칩마다 포트의 갯수와 일부 기능이 추가 또는 빠져 있지요. 당연히, 좀 비싼칩은 자원(주변장치)이 더 많지요. 즉, 좀더 쉽게 편하게 쓰도록 팍팍 뭔가 좋은게 들어있는거지요. 하지만, 프로그래밍적으로는 대부분 서로 갖다 쓸수 있도록 되어 있으니까 걱정마세요. AVR Studio에서 칩 선택만 하면 왠만한건 그냥 맞춰지구요. 조금 차이가 있는것은 레지스터(? 그냥 그렇구나 생각하시구요. 나중에 자연스럽게 알게됨) 이름(주소:어드레스)이 좀 차이가 있죠.


그럼, 우선 atmega168의 핀아웃(pinout: 다리배열)부터 보시죠. 껍데기부터 봐야죠..



먼저, 갖고 계신 칩이 왼쪽 모양이면 TQFP형상이라 부르고요, 오른쪽 모양이면 PDIP형상이라고 불러요. 그냥 상식으로 알고 계세요. 개인이 그냥 쓰기에는 오른쪽이 편하지요. 다리(Pin)도 크고 IC소켓에 껴서 쓰면 편하지요. 왼쪽(TQFP)것은 다리 간격이 좁아서 개인적으로 쓰기에는 좀 불편하죠. 더군다나 만능기판에 부착하기에는요.. 땜질 실력 있으신 분은 예외!

근데, 뭔가 다리 이름들을 쭉~ 살펴보니 뭐 그냥 일정한 이름 규칙이 보이네요. 그렇죠!

PB 0,1,2,3,4,5,6,7
PC 0,1,........5,6
PD 0,1,........ .,6,7
그리고, 나머지는 VCC, GND, AVCC, AREF .. 끝!!!

다리발 이름에 모든 기능이 다 나와있어요. 나중에 차차 알시게 될겁니다. 정말로, 다리에 왠만한 기능 설명이 다 나와 있어요~~~^^

우선, 오늘은 여기까지만 하구요,,
한가지, 위 그림 익숙하게 봐두세요.. 뭐 별거 없잖아요.

다음에는 이놈에게 전기를 먹여서 살리기를 할께요.. XTAL(크리스탈 오실레이터)없이 살릴수 있도록요.. 그래서, 이놈들(AVR 칩)이 참 쓰기 쉽게 만들어졌다는거에요..^^
저는 이런 것이 제일 맘에 들었지요. 그냥 전기만 넣어주면 팍팍 도니까요..
나머지는 그냥 간단한 프로그래밍!! 이것 조차도 너무 쉽게 되어있으니까요..
얼마나 쉽길래? 글세요.. 기대하시라~~

그럼, 이만 총총.

끝.


1. 내가 AVR을 마주친 계기@.@

 시간은 어느덧 흘러 거의 삽십여년이 훌쩍 지나버렸다. Z80이라는 마이크로 프로세서를 접하는 마음 설레는 공대생의 첫 느낌은 그 어느 미팅 때의 설레임보다 더 했을것이다.... Z80, CTC, 8255 PIO, SRAM, EEPROM, 애플2, CP/M, 기계어, 니모닉, 어셈블리어, 그리고 터보C 등등...
 이것만 있으면 세상의 모든 자동화는 다 될 것만 같았던 그 시절... 하지만, 세월에 묻혀 모두 까맣게 잊고 긴 세월이 지나갔다. 그리고, 몇달전에 우연히  AVR을 접하게 되었다. 세상에나,,, 세상에 이렇게 강력한 MCU와 개발환경(AVR Studio X).. 윽,, 내가 잊고 지내던 사이에 세상은 점점 발전한 것이다. 나는 또 다시 꿈을 꾼다. 이것만 있으면,, 지금 나와있는 모든 IT기기와 연동하여 아주 재밌는 것들을 만들 수 있으리라고,,, 스마트폰, 블루투스, USB연동, R/C자동차 등등.. TV리모콘도 연동할 수 있겠구나!! 점점 머릿속은 재밌는 상상으로 가득차기 시작한다. 그리고, 나는 세월에 쌓은 가냘픈 지식을 하나 둘씩 꺼낸다.

그럼, 간단히 AVR을 소개하고자 한다. 혹시나, 누군가 이 글을 읽으시는 분이 계시다면, 그냥 쉽게 생각하고 접근하시라.. 상식선에서 생각하시면 다 이해되실 겁니다. 하긴, AVR을 설계하고 제작한 사람들이 어떤 사람들이겠는가! 날고 긴다는 설계 전문가님들이 일반인이 아~~주 쉽게 쓸 수 있도록 기능을 최대한 간단 명료하게 구현하지 않았을까요.. 아마 그럴 겁니다. 그렇다고 믿습니다...

앞으로 아주 간단 명료하게,, 간단히 이해하 수 있도록 AVR에 대해서 설명하도록 하겠습니다. 저 역시 크게 깊은 지식을 갖고 있지는 않으나, 여러분이 어디가 가려운 곳인지는 알고 있습니다. 저 역시 과거에 그랬으니까요.. 그러면서 이것 저것, 일본책, 영어책을 찾아 읽으면서 조금씩 알게 되었지요.

조만간 다음 글을 올리겠습니다.

이만 총총.