수치 해석(numerical analysis)분야에서 독보적인 위치를 차지하고 있는 툴은 단연 MATLAB이다. 수치 해석에 특화된 독자적인 스크립트 언어를 가지고 있고 (문법 구조가 robust하지 않다는 평이 있긴 하지만) 다양한 분야에 적용가능한 toolbox와 폭넓은 이용자층, 개발사의 적극적 지원 등 장점이 많은 툴이다. java로 개발되어서 실행하려면 jvm을 먼저 설치해야 한다. (물론 jvm의 성능이 비약적으로 향상되었긴 하지만 속도면에서 불리한 면이 있지 않을까하는 짐작이 든다.)



 단점은 역시 꽤 고가의 툴이라는 점이며 이 점때문에 학부생들이나 가볍게 배워보려는 이들에게는 실습 도구로 사용하기에 적합하지 않다. 개발사인 mathwork사에서 라이센스를 꽤 엄격하게 관리하고 있기도 하다. (라즈베리파이에는 무료로 제공된다는 얘기도 있는데 아직 확인을 못 해 봤다. 그리고 그 사양 위에서 matlab이 원활하게 실행될 것 같지도 않다.) 국내에서 출판된 공학 수학 교재들 중에 MATLAB을 보조적으로 사용하는 것들이 있는데 이런 점에서 적절치 않다고 생각한다.


 다른 대안이 없는 것은 아니다.일단 Octave라는 걸출한 오픈 소스 프로그램이 있는데 Matlab과의 문법 호환성이 거의 100%라서 기본적인 코드는 거의 변환 없이 실행이 가능할 정도이므로 학부생들의 기초 교육은 이것을 사용하면 된다. 그동안 gui 환경이 갖춰지지 않아서 불편했는데 (베타 버전이긴 하지만) 최근에는 gui환경도 지원하기 시작해서 더욱 고무적이다.


 그 외에도 scilab이 있는데 scilab은 유럽 등지에서는 꽤 유명하고 널리 쓰이는 수치해석 툴로써 무료로 사용할 수 있는 프리웨어이다. 하지만 개인적으로는 matlab과는 많이 동떨어진 문법을 가지고 있고 익히기도 꽤 어려웠다는  경험이 있다. 그리고 freemat 이라는 것도 있는데 matlab과 100%호환되는 툴을 지향하고 개발되기 시작했으나 2013년 이후로 개발이 중지된 것 같다. 최근에는 python+numpy 라는 (역시 오픈소스) 떠오르는 방법도 있다. (필자는 이것을 가장 추천하는 편이다.)


 모든 개발 환경이 클라우드로 옮겨가고 있는 추세이다. matlab은 아니지만 가장 간편하게 (무료로) matlab 코드를 실행시킬 수 있는 방법은 온라인 옥타브이다. 접속하면 바로 코딩이 가능하고 그 결과를 즉시로 확인해 볼 수 있다.



위 그림에서와 같이 plot()명령의 결과도 바로 확인할 수 있다. 단, scrip파일을 작성하려면 로그인을 해야 한다.


mathclouds 라는 사이트도 있다. 여기에서도 matlab 문법을 지원한다.


matlab 실습을 가장 간편하게 할 수 있는 방법은 이러한 서비스들을 사용하는 것이다.



Posted by 살레시오
,

 MATLAB에서 취급되는 모든 데이터형은 기본적으로 행렬(matrix)이다. 스칼라(scalar)값은 1☓1차원의 행렬이고 벡터는 n☓1차원의 행렬이다. 일반적으로 수학 교재에서 그냥 벡터라 하면 열벡터(column vector)를 의미하는 경우가 많다. 이 책에서도 앞으로 그냥 벡터라고 하면 열벡터를 의미하는 것으로 한다. 심지어 문자열도 그 문자 각각의 아스키(ASCII)코드값의 행렬(벡터)로 표시하며 다항식은 계수들의 행렬(벡터)로 표시한다. 함수에 넘겨주는 입력 파라메터도 행렬이고 함수의 수행 결과 생성되는 출력값도 역시 행렬이다. 앞으로 다음과 같이 구분하도록 하겠다. (m,n은 양의 정수)

       ① 스칼라 : 1x1차원의 행렬

       ② 벡터 : nx1차원의 행렬 (행벡터 : 1xn 차원 행렬)

       ③ 행렬 : mxn 차원의 행렬

 이제 행렬을 저장하는 변수를 만드는 기본적인 방법을 설명한다. MATLAB에 행렬을 입력하는 방법의 하나는 원소들을 대괄호 안에 입력하는 것으로 각 원소들은 공란 또는 콤마로 분리되어야 한다. 예를 들어 다음과 같은 행렬은

아래와 같이 한 줄에 입력할 수 있다.


>> A = [1.2 10 15; 3 5.5 2; 4 6.8 7] 󰎠
A =
1.2000 10.0000 15.0000
3.0000 5.5000 2.0000
4.0000 6.8000 7.0000


위에서 보듯 행렬의 원소들을 대괄호 안에 입력해야한다. 모든 행의 원소들은 공란 또는 ‘,’로 분리되어야 하며, 마지막 행을 제외한 각 행의 끝은 세미콜론으로 구분한다.


 크기가 큰 행렬은 몇 개의 입력 줄로 펼쳐서 나타낼 수 있다. 예를 들어 다음과 같은 행렬 B를 생각해보자.

이 행렬은 다음과 같은 네 줄로 나눠서 입력할 수 있다.

>> B = [1.5630 2.4572 3.1113 4.1051;
3.2311 1.0000 2.5000 3.2601;
1.0000 2.0000 0.6667 0.0555;
0.2345 0.9090 1.0000 0.3333];


여기서 ‘]’뒤에 세미콜론 ‘;’를 사용하였는데 끝에 세미콜론을 할 경우 처리 결과를 출력하지 않는다. 또한 각행의 마지막에 세미콜론 ‘;’을 사용하였는데, 이것을 생략하여도 같은 행렬로 입력된다.

※ 다른 언어(C/C++/JAVA/C# 등등)와 달리 MATLAB에서는 하나의 명령어 끝에 반드시 세미콜론 ‘;’을 붙여야 하는 것은 아니다. MATLAB의 명령 줄의 끝에 세미콜론 ‘;’ 을 붙이면 명령을 수행한 결과 값을 화면에 표시하지 않으며 세미콜론을 붙이지 않으면 명령을 수행한 결과 값을 화면에 표시한다. 명령어들 간에 구분을 하기 위해서는 콤마‘,’를 사용하며 세미콜론으로도 명령어들을 구분하나 바로 앞의 명령어의 출력을 억제한다. 다음 예를 보자.

>> a=1, b=2; c=3 󰎠
a =
1
c =
3


 이미 만들어진 행렬을 이용하여 새로운 행렬을 만들 수도 있다.


>> A1=[A; 11 22 33]
A1 =
   1.2000   10.0000   15.0000
   3.0000    5.5000    2.0000
   4.0000    6.8000    7.0000
  11.0000   22.0000   33.0000


이 예에서는 이미 만들어진 행렬 A를 이용하여 A행 밑에 한 행을 추가하여 새로운 행렬 A1을 생성하였다.


[그림 1]  행렬 A1의 구조


새로운 열을 A행렬 오른편에 추가하고 싶다면 다음과 같이 하면 된다.


>> B=[0.5; 2; 100] 󰎠
B =
0.5000
2.0000
100.0000
>> A2=[A B] 󰎠
A2 =
1.2000 10.0000 15.0000 0.5000
3.0000 5.5000 2.0000 2.0000
4.0000 6.8000 7.0000 100.0000


또는 다음과 같이 한 번에 같은 일을 수행할 수도 있다.


>> A2 = [A [0.5; 2; 100] ]
A2 =
1.2000 10.0000 15.0000 0.5000
3.0000 5.5000 2.0000 2.0000
4.0000 6.8000 7.0000 100.0000


 다른 예로 A행렬을 두 번 이용하여 다음과 같이 새로운 AA라는 행렬을 만들 수도 있다.

>> AA=[A A]
AA =
   1.2000   10.0000   15.0000    1.2000   10.0000   15.0000
   3.0000    5.5000    2.0000    3.0000    5.5000    2.0000
   4.0000    6.8000    7.0000    4.0000    6.8000    7.0000

 

위에서 행렬 A를 옆으로 나란히 붙어서 새로운 행렬 AA를 만들었다. 또는


>> AA2=[A; A]
AA2 =
   1.2000   10.0000   15.0000
   3.0000    5.5000    2.0000
   4.0000    6.8000    7.0000
   1.2000   10.0000   15.0000
   3.0000    5.5000    2.0000
   4.0000    6.800      7.0000


위에서는 행렬 A를 밑으로 나란히 붙어서 새로운 행렬 AA2를 만들었다. 위와 같이 기존에 생성된 행렬들을 합성하여 새로운 행렬을 만들 때는 그 행렬들의 차원에 주의해야 한다. 다음의 예를 보자.


>> A=[1 2; 3 4] 󰎠
A =
1 2
3 4
>> B=[5 6 7;8 9 10; 10 11 12] 󰎠
B =
5 6 7
8 9 10
10 11 12
>> AB=[A B] 󰎠
오류 내용 : 행렬에서 dimension이나 type이 일치하지 않습니다.
>> AB_=[A; B] 󰎠
오류 내용 : 행렬에서 dimension이나 type이 일치하지 않습니다.

 

두 행렬을 옆으로 연결할 때는 행수가 같아야 하고 밑으로 붙일 때는 열수가 같아야 한다. 그렇지 않으면 위와 같이 오류가 발생한다.



Posted by 살레시오
,

 PWM이라는 것은 구형파의 듀티비(duty ratio)를 조절하는 것을 의미한다. 듀티비란 구형파의 주기와 ‘1’이 되는 구간의 시간비율을 의미한다. 다음 [그림 1]에서 T는 주기, t1은 한주기에서 ‘1’이 되는 시간을 표기하는데 듀티비는 t1/T 로 정의된다.


[그림 1] PWM과 듀티비


ATmega8(A)의 T/C2는 두가지 PWM발생 모드를 가지고 있는데 하나는 고속PWM모드이고 다른 하나는 위상교정PWM 모드이다. 이 두 가지에 대해서 각각 알아보겠다.

고속 PWM 모드

 고속 PWM모드는 TCNT2레지스터가 노멀모드에서와 같은 동작을 한다. 즉, 0x00에서 0xFF까지 1씩 증가하다가 그 다음 사이클에서 다시 0x00으로 클리어된 후 다시 1씩 증가한다. 이 때 ① TOV2 플래그가 세트되며 ②비교매치시 OC2 플래그도 세트된다. OC2 핀은 COM21:0 비트들의 설정에 따라서 동작이 결정되는데 ①의 경우에 세트되고 ②의 경우에 리셋 되거나 혹은 반대의 동작을 취할 수 있다.([표 1] 참조) 데이터쉬트에서 [그림 1]에 고속 PWM모드의 타이밍 다이어그램을 발췌하였다.


[그림 2] 고속 PWM 모드에서의 타이밍 다이어그램


[표 1] 고속 PWM 모드일 때 비교 출력핀(OC2핀) 동작

COM21

COM20

OC2핀의 동작

0

0

포트핀(PB3)으로 동작

0

1

-

1

0

TCNT2=0x00일때 OC2핀 셋,

비교매치시 OC2핀 리셋

1

1

TCNT2=0x00일때 OC2핀 리셋,

비교매치시 OC2핀 셋


OC2핀으로 발생하는 PWM파형의 주기는 다음 식과 같이 계산할 수 있다.

여기서 N 은 분주수를 나타내며 1, 8, 32, 64, 128, 256, 1024 중 하나이고, fTC2는 T/C2에 인가되는 클럭 주파수이다.


 한 가지 유용한 사실은 오버플로우 인터럽트와 비교매치 인터럽트를 이용하면 임의의 포트핀에 PWM파형을 발생시킬 수 있다는 점이다. 즉 해당하는 ISR() 함수 내부에서 원하는 포트핀을 셋시키거나 리셋시켜서 OC2핀 뿐만 아니라 임의의 포트핀에 PWM파형을 발생시킬 수 있다.


위상 교정 PWM 모드

 위상교정PWM 모드가 고속PWM 모드와 다른 점은 TCNT2레지스터가 0에서 0xFF값에 도달한 후(업-카운팅) 0x00으로 클리어되는 것이 아니고 1씩 감소하여 다시 0x00이 된다(다운-카운팅)는 점이다. 이때 비교매치는 두 가지 경우인데 업 카운팅의 경우와 다운 카운팅의 경우이다. PWM파형은 업-카운팅에서 비교매치가 일어난 경우 OC2핀을 ‘1’로, 다운-카운팅에서 비교매치가 일어난 경우 OC2핀을 ‘0’으로 설정하여 PWM파형을 발생시킨다. (혹은 그 반대의 모양으로 발생시킬 수 있다.)


[그림 3] 위상 교정 PWM 모드의 타이밍 다이어그램


OC2핀으로 발생하는 PWM파형의 주파수는 고속 PWM의 경우보다 두 배 줄어들며 다음 식과 같이 계산할 수 있다.

여기서 N은 분주수를 나타내며 1, 8, 32, 64, 128, 256, 1024 중 하나이다.


[표 2] 위상 교정 PWM 모드일 때 비교 출력핀(OC2핀) 동작

COM21

COM20

OC2핀의 동작

0

0

포트핀(PB3)으로 동작

0

1

reserved

1

0

업카운팅에서 비교매치시 OC2핀 리셋

다운카운팅에서 비교매치시 OC2핀 셋

1

1

업카운팅에서 비교매치시 OC2핀 셋

다운카운팅에서 비교매치시 OC2핀 리셋


고속 PWM모드에서와 마찬가지로 두 개의 인터럽트를 이용하면 위상교정 PWM파형도 임의의 포트핀으로 내보낼 수 있다. 단, 이번에는 앞의 경우와 달리 비교매치 인터럽트가 업-카운팅에서 발생했는지 다운-카운팅에서 발생했는지를 판별해야 할 것이다. 이것을 위해서 [그림 3]을 살펴보면 오버플로우 인터럽트는 다운-카운팅에서 0x00에 도달한 경우에 발생하는 것을 알 수 있다. 따라서, 오버플로우 인터럽트가 발생한 이후 첫 번째 비교매치 인터럽트는 업-카운팅에서, 두 번째 비교매치 인터럽트는 다운-카운팅에서 발생한 것으로 판정해야 하므로 조건 검사를 하는 코드가 앞의 경우에 비해서 더 추가가 되어야 할 것이다.




Posted by 살레시오
,

 여기에서는 이전 포스트에서 소개했던 T/C2의 정상 모드와 CTC 모드에 대해서 자세히 살펴보도록 하겠다.

정상(Normal) 모드

 정상 모드는 TCNT2레지스터가 OCR2레지스터의 값에 영향을 받지 않고 $00부터 $FF까지 1씩 증가하는 동작을 반복하며 중간에 이 값이 클리어되지 않는 가장 단순한 기능의 모드이다. TCNT2레지스터가 $00값이 되는 동시에 TOV2 (overflow flag)가 ‘1’이 되고 만약 오버플로 인터럽트가 활성화되어 있다면 ISR이 호출된 후 TOV2는 자동으로 ‘0’으로 클리어된다. 또한 TCNT2값이 OCR2값과 일치되는 순간 TOCI2가 ‘1’이 되고 만약 OCIE2 비트가 ‘1’로 설정되었다면 비교 매치 인터럽트가 발생된다.


 따라서 이 모드는 일정한 시간 주기로 인터럽트를 발생하는 용도로 사용되나 그 주기를 정밀하게 결정하지는 못하는 단점이 있다. 또한 normal 모드에서도 COM21:0비트를 설정하여 OCR2의 비교매치를 사용할 수는 있으나 데이터쉬트에 의하면 normal모드에서 OC2핀을 활성화시키는 것은 권장되지 않는다.


 이제 노멀모드의 두 개의 인터럽트를 이용해서 LED의 밝기를 조절하는 예제를 작성해 보자. 다음 프로그램을 실행시켜보면 LED전체가 점점 밝아졌다가 꺼진후 다시 점점 밝아지는 동작을 반복한다.


#define F_CPU 16000000
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "am8USBasp.h"
ISR(TIMER2_OVF_vect) {
   TurnLEDOn;
}
ISR(TIMER2_COMP_vect) {
   TurnOffAll;
}
int main(void){
   uint uiA;
   InitAM8();
   ASSR=0x00;
   TCCR2=0x04;//0b00000100
   TIMSK=0xC0;//0b11000000
   TCNT2=0x00;
   OCR2=00;
   sei();// global interrupt enable
   LED(0xFF);
   while(1) {
       for(uiA=0;uiA<256;uiA+=5) {
           OCR2 = (uchar)uiA;
           _delay_ms(100);
       }
   }
}


이 예제에서 보면 오버플로 인터럽트에서는 LED를 모두 켜고 비교매치 인터럽트에서는 LED를 모두 끄게 되어 있다. 이러한 동작이 1초에 약 977번 일어나기 때문에 눈으로 보기에는 깜빡이는 것이 아니라 밝기가 다르게 보이는 것이다. OCR2의 값이 클수록 LED가 켜져 있는 구간이 길어지므로 OCR2값이 0에 가까우면 거의 꺼진 것 같이 보이고 커질수록 더 밝아보이게 된다. 이러한 동작을 펄스폭 변조(PWM) 제어라고 하는데 디지털 회로에서 그 응용폭이 넓기 때문에 AVR에는 PWM을 발생시키는 별도의 기능이 마련되어 있으며 7.3.3절에서 자세히 설명하도록 하겠다.


CTC (Clear Timer on Compare match) 모드

 정상 모드에 비해서 CTC 모드는 조건 TCNT2 == OCR2 이 만족되는 그 다음 순간에 TCNT2레지스터가 $00으로 초기화 된다는 점이 다르다. non-PWM모드 (노멀 모드와 CTC 모드)에서 COM21:0비트의 설정에 따라 OC2핀이 어떻게 동작하는 지는 다음 표에 정리하였다. 두 개의 COM21, COM20 비트 중 하나라도 0이 아니면 ATmega8(A)의 17번 핀은 PB3로 동작하는 것이 아니라 OC2핀으로 동작한다.


[표 1] non-PWM 모드일 때 비교 출력 모드

COM21

COM20

OC2핀의 동작

0

0

포트핀(PB3)으로 동작

0

1

비교매치 시 OC2 토글(toggle)

1

0

비교매치 시 OC2 클리어(‘0’)

1

1

비교매치 시 OC2 세트(‘1’)


[그림 1] CTC모드의 타이밍 다이어그램


또한 TIMSK레지스터의 OCIE2 비트를 ‘1’로 설정하여 TCNT2가 OCR2값과 같을 때 인터럽트(비교매치 인터럽트)를 발생하게 설정할 수도 있다. 그리고 노멀모드와 마찬가지로 TOV2 플래그는 TCNT2레지스터가 OCR2레지스터 값에 도달하여 0x00으로 클리어되는 순간 ‘1’로 세트되지만 이 모드에서는 오버플로우 인터럽트가 별로 의미가 없다. 왜냐하면 같은 시점에서 OCI2 인터럽트가 발생하기 때문이다.

CTC모드의 가장 큰 장점은 사용자가 원하는 정밀한 주기의 인터럽트를 발생할 수 있다는 점, 그리고 [그림 1]에서 보듯이 COM21:0=01로 설정하면 원하는 주기를 가지는 구형파를 생성하여 OC2핀으로 내보낼 수 있다는 점이다. 이 경우에는 반드시 DDRB3를 ‘1’로 하여 출력모드로 설정해두어야만 한다. 이 경우 주파수의 계산식은 다음과 같다.

여기서 N은 분주수(1, 8, 32, 64, 128, 256, 1024 중 하나)이고 fdk 는 T/C2에 인가되는 클럭의 주파수이다.



Posted by 살레시오
,

 이전 포스트에 이어서 T/C2에 관련된 레지스터들에 대해서 알아보자. T/C2와 관련된 레지스터들은 다음과 같다.


[표 1] T/C2와 관련된 레지스터들

레지스터

용도

TCNT2

클럭의 계수값을 실시간으로 저장하는 레지스터

OCR2

(Overflow Compare Register) 이  레지스터의 값이 오버플로가 발생하는  값으로 설정된다.

TCCR2

T/C2의 전체적인 동작을 설정하고 제어하는 레지스터

TIMSK

T/C2의 인터럽트를 사용할 수 있도록 설정

TIFR

T/C2의 인터럽트가 발생했는지를 표시하는 레지스터

ASSR

어떤 클럭 소스를 이용할 것인가를 설정


ASSR 레지스터

 ASSR2 레지스터를 이용하여 어떤 클럭 소스를 이용할 것인가를 설정할 수 있다.


[그림 1] ASSR 레지스터의 구조


이 ASSR레지스터의 b3는 AS2인데 이 비트가 ‘0’이면 시스템 클럭을, ‘1’이면 TOSC1, TOSC2핀으로 인가되는 외부 클럭을 T/C2의 클럭소스로 선택한다.

TCCR2 레지스터

 TCCR2 레지스트는 T/C2의 전체적인 동작을 설정하고 제어하는 레지스터이다.


[그림 2] TCCR 레지스터


FOC2는 b7인데 이 비트는 항상 ‘0’으로만 읽혀지며 PWM모드가 아닐 때만 ‘1’을 쓸 때 강제로 비교매치가 수행된다. (Force Output Compare) 이 경우 OC2핀의 출력은 COM21:0비트의 설정에 따라 변하게 된다.

그리고 b6과 b3 두 개의 비트는 WGM21:0로 표기하면 T/C2의 동작 모드를 설정하는데 사용되며  다음 표에 각각의 모드를 수록하였다.


[표 2] Waveform Generation Mode (WGM) 비트 설정

No

WGM21:0

모드

TOP

OCR2갱신

TOV2 세트

0

00

Normal

$FF

즉시

MAX

1

01

Phase Correct PWM

$FF

TOP

BOTTOM

2

10

CTC

OCR2

즉시

MAX

3

11

Fast PWM

$FF

BOTTOM

MAX


COM21:0 비트는 OC2핀의 출력을 제어하며 이 두 비트 중 하나라도 ‘1’로 세트되어 있다면 17번 핀은 포트핀(PB3)으로 동작하지 않고 OC2핀으로 동작하게 된다. 단 OC2핀으로 사용하기 위한서는 DDRB3는 반드시 출력(‘1’)으로 설정해야 된다는 것을 주의해야 한다. 또한 COM21:0 설정에 따른 동작은 어떤 모드로 동작하느냐에 따라서 값은 값이라도 다르다는 것에도 유의해야 한다.


 CS22:0 비트는 입력 클럭의 분주비를 설정하는 비트들이다.


[표 3] T/C2 프리스케일 선택

CS22

CS21

CS20

설명

clkT2S =16MHz일 때 TOI 발생 주파수

0

0

0

클럭 소스 없음

(T/C2 비동작)

발생 안 함

0

0

1

clkT2S

62,500 Hz

0

1

0

clkT2S /8

7,812 Hz

0

1

1

clkT2S /32

1,953 Hz

1

0

0

clkT2S /64

977 Hz

1

0

1

clkT2S /128

488 Hz

1

1

0

clkT2S /256

244 Hz

1

1

1

clkT2S /1024

61 Hz


TIMSK 레지스터

 T/C0에서도 소개한 바 있는 TIMSK 레지스터는 T/C2의 인터럽트를 사용할 수 있도록 설정하는 비트들을 가지고 있다. 여기서는 T/C2와 관련된 b6, b7 비트들을 확인하자.


[그림 3] TIMSK 레지스터


이 중 b6은 TOIE2 (Timer/counter Overflow Interrupt Enable 2)라고 명명되어 있다. TOIE2는 T/C2에서 오버플로우가 발생했을 때 인터럽트를 발생시킬 것인지 아닌지를 설정하는 비트인데 “0”으로 설정되면 인터럽트를 발생시키지 않는다. 만약 TOIE2가 “1”로 설정되어있고 글로벌 인터럽트가 인에이블이면 (즉 SREG의 I비트가 1로 되어 있으면) 인터럽트가 발생된다. b7은 비교매치 시에 인터럽트를 발생시킬 것인지 아닌지를 설정하는 비트이고 ‘1’로 설정되면 비교매치 인터럽트가 발생한다.



Posted by 살레시오
,

 타이머/카운터2(이하 T/C2)는 T/C0와 마찬가지로 8비트로 동작하고 그 계수값은 TCNT2 레지스터에 저장된다. 하지만 T/C0와 비교해서 T/C2는 다음과 같은 몇 가지 기능을 더 가지고 있다.

  • 비교매치 (compare match) 시 TCNT2 클리어.

  • PWM (pulse-witdth modulator) 파형 발생.

  • TOSC0/TOSC1 외부 핀에 32.765KHz 리얼타임클럭을 연결하여 사용 가능.

T/C0에서는 TCNT0레지스터의 값은 항상 $00에서 시작해서 $FF(255)까지 증가했다가 다시 $00으로 돌아가서 증가를 계속했으며 그 중간에서 다시 0으로 되돌릴 수 없었다. 즉, 사용자가 원하는 숫자에 도달하면 0으로 되돌리거나 혹은 그 시점에서 인터럽트를 발생할 방법이 없었다. 비교매치는 이러한 기능을 수행한다. 다음 [그림 1]에서 보면 OCR2레지스터가 있는데 여기에 저장된 값과 TCNT2값이 같은 시점에서 인터럽트를 발생하거나 OC2핀(17번 핀)으로 구형파를 내보낼 수 있다.


[그림 1] T/C2의 기능별 블럭도


 PWM(pulse-width modulation)은  led의 밝기 제어나 dc모터의 속도 제어 등에 사용되는 매우 중요한 기능 중 하나이다.. PWM 발생기는 구형파가 ‘1’이 되는 구간과 ‘0’이 되는 구간의 비율을 사용자가 조정할 수 있으며 이 비율을 듀티비(duty ratio)라고 하는데 모터의 속도제어와 같은 분야에서 중요하게 사용된다. PWM발생모드는 크게 두 가지로 나뉘는데 고속 PWM모드와 위상교정(phase correct) PWM 모드이다. 이에 대해서는 이후에 더 자세히 설명할 것이다.


[그림 2] T/C2와 관련된 핀들


 T/C2의 동작은 [표 1]과 같이 크게 세 가지로 분류할 수 있으며 각각의 모드는 TCCR2의 WGM20:1 두 비트를 설정함으로서 선택할 수 있다.


[표 1] T/C2의 세 가지 동작 모드 요약


 T/C2의 클럭 소스는 시스템 클럭 clk와 외부핀 TOSC1:2 으로 인가되는 외부클럭(32.765KHz) 두 가지 중 하나를 선택할 수 있으며 T/C1과 달리 프리스케일러를 사용하지 않는다. ASSR 레지스터의 AS2비트가 ‘1’로 세트되면 후자가 선택된다.



Posted by 살레시오
,

 이전 포스트에서 T/C0에 대해서 소개를 하였다. 여기에서는 관련 IOCR에 대해서 자세히 알아보도록 하겠다.

TCCR0 레지스터

 T/C0가 어떤 클럭 소스을 사용할 것인지는 TCCR0(Timer/Counter Control Register 0)의 b2:0 비트의 CS02, CS01, CS00에 의해서 선택되게 된다.

[그림 1] TCCR0의 비트 구조


TCCR0의 비트 3번부터 7번까지는 예약한 비트들로서 사용되지 않으며 항상 0으로 읽혀진다. 그리고 b2, b1, b0은 다음 표와 같이 T/C0의 프리스케일링 소스를 정의한다.


[표 1] T/C0의 프리스케일 선택

CS02

CS01

CS00

설명

0

0

0

정지, 타이머/카운터0를 정지시킴

0

0

1

clk

0

1

0

clk/8

0

1

1

clk/64

1

0

0

clk/256

1

0

1

clk/1024

1

1

0

외부핀 T0 하강에지

1

1

1

외부핀 T0 상승에지

TCNT0 레지스터

 TCNT0는 클럭 소스의 카운트 값을 실시간으로 저장하는 레지스터로서 읽고 쓰기가 가능하다. 만약 TCNT0에 어떤 값이 쓰여 지면 그 쓰기 동작에 뒤이어 그 값에서부터 계수 작업이 수행되게 된다.


[그림 2] TCNT0 레지스터

이 레지스터는 초기값 $00 (0b00000000)으로 부터 최대값 $FF (0b11111111)까지 순차적으로 업카운팅(up-counting)을 하게 된다. 그리고 최대값 $FF가 되고 나서 그 다음 클럭이 들어오면 $FF + 1 = $00 가 되고 오버플로우(overflow)가 발생하게 된다. 이때 오버플로우 인터럽트가 발생하게 설정이 되었다면 인터럽트가 발생하게 될 것이다.


TIMSK (Timer/counter Interrupt MaSK) 레지스터

 TIMSK는 TC0와 TC1의 인터럽트를 사용할 수 있도록 설정하는 레지스터이다. 여기서는 TC0와 관련된 1번 비트만 확인하자.

[그림 3] TIMSK 레지스터


비트0은 TOIE0 (Timer/counter Overflow Interrupt Enable 0)라고 명명되어 있는데 T/C0에서 오버플로우가 발생했을 때 인터럽트를 발생시킬 것인지 아닌지를 설정하는 비트이다. “0”으로 설정되면 인터럽트를 발생시키지 않으며 “1”로 설정하면 글로벌 인터럽트가 인에이블이면 (즉 SREG의 I비트가 1로 되어 있으면) 인터럽트가 발생된다.

TIFR (Timer/counter Interrupt Flag Register) 레지스터

 TIFR의 구조는 TIMSK의 구조와 유사하며 다음과 같다.

[그림 4] TIFR 레지스터


이 중 TC0와 관련된 비트는 0번이며 만약 TC0에서 오버플로우가 발생하면 b1인 TOV0가 자동적으로 세트가 된다. 이 경우에 TIMSK의 b0가 (TOIE0) “1”로 설정이 되어 있다면 인터럽트가 발생되어 해당하는 ISR 함수가 호출되게 된다.


T/C0와 T/C1의 프리스케일러

 프리스케일링(prescaling)이라는 것은 입력된 클럭의 주기를 정해진 배수로 변형시키는 것이다. 다음 그림 7.2.2에서 보듯이 만약 CK/8이라면 입력 클럭 clk 의 주기가 8배로 늘어나게 됨을 알 수 있다. 만약 CK/64라면 주기가 64배로 늘어날 것이다. 이러한 기능을 수행하는 유닛을 프리스케일러(prescaler)라고 한다. (나누기로 표시되어있어서 주기가 줄어든다고 오해하면 안 된다.)


[그림 5] 프리스케일링의 개념도


T/C0와 T/C1은 같은 프리스케일러 모듈을 사용하지만 설정은 각각 다르게 할 수 있다. 이 프리스케일러는 T/C의 설정과는 무관하게 연속적으로 동작하고 하나의 프리스케일러를 T/C0과 T/C1이 공유한다. 프리스케일러를 리셋하려면 SFIOR 레지스어의 0번 비트 (PSR10)을 ‘1’로 쓰면 된다. 이후에 리셋동작이 끝나면 이 비트는 하드웨어적으로 (자동으로) ‘0’으로 클리어된다.


[그림 6] T/C0와 T/C1의 프리스케일러




Posted by 살레시오
,

 AVR의 내장 장치들 중에서 타이머/카운터는 그 기능이 많고 설정이 복잡하므로 익히는데 노력이 필요한 것 같다. 타이머(timer)는 그 단어가 의미하듯이 시간에 관계되는 것으로 우리가 원하는 시간 간격으로 변하는 신호를 만들어 주거나 특정한 시간에 인터럽트를 발생해 주는 장치이다. 또한 카운터(counter)란 숫자를 세는 것을 의미하며 내/외부의 이벤트(event)나 펄스의 숫자 등을 세는 기능을 가지고 있다. 이러한 기능을 하는 AVR의 내장 장치를 타이머/카운터라고 하며 이후에는 이것을 줄여서 T/C로 표기한다.


 ATmega8(A)에는 세 개의 T/C가 내장되어 있으며 하나는 16비트 T/C이고 다른 두 개는 8비트로 동작한다. T/C의 가장 기본적인 동작은 펄스를 세는 것인데 이 때 이 수를 저장하는 레지스터의 크기에 따라 8비트와 16비트로 구분한다. 즉, 펄스를 255개(8비트의 최대값)까지 셀 수 있다면 8비트 카운터고 65,535(16비트의 최대값)개까지 셀 수 있다면 16비트 카운터이다. 내장된 세 개의 T/C는 0번, 1번, 2번 이렇게 번호가 매겨져 있는데 0번 T/C와 (T/C0) 2번 T/C가 (T/C2) 8비트 T/C이고 이 계수가 저장되는 레지스터가 TCNT0($32번지), TCNT2($24번지)이다. 1번 T/C는 (T/C1) 16비트 T/C이고 그 계수 값은 TCNT1H:TCNT1L 두 개의 레지스터에 걸쳐서 저장된다.


 T/C 기능을 사용하기 위해서는 클럭신호가 필요한데 이것을 입력클럭(CK)로 그대로 사용할 수도 있고 또는 CK를 프리스케일링(prescaling)하여 사용하거나(CK/8, CK/64, CK/256, Ck/1024 등) 외부 핀(TOSC1:0, T1:0)으로 들어오는 클럭 신호를 입력으로 사용할 수도 있다.


T/C0(8비트)

 전술한 바와 같이 ATmega8A는 8비트 T/C 두 개를 내장하고 있으며 각각 T/C0, T/C2으로 표기한다. 이번에는 그 중 기능이 제일 단순한 T/C0에 대해서 알아본다.


 T/C0는 시스템 클럭(CK), 프리스케일된 클럭(CK/n) 또는 외부핀(T0:6번 핀)으로부터 입력되는 클럭 신호들 중 하나를 선택하여 사용하게 된다. 선택된 클럭을 clkT0 라고 표기한다. [그림 1]의 제어 유닛(control unit)은 클럭 입력을 계수하여 TCNT0레지스터의 값을 하나씩 증가시킨다. 그리고 오버플로우 인터럽트가 설정되어 있다면 TCNT0가 $FF에서 $00으로 변하는 순간 인터럽트(TOV0)를 발생시키기도 한다.

[그림 1] T/C0의 기능별 블럭 다이어그램

T/C0에 관련된 I/O레지스터로는 다음과 같은 것들이 있으며, 다른 IOCR과 마찬가지로 그 기능을 나타내는 말의 줄임말로 이름을 붙였다.


  • TCNT0 : Timer/CouNTer 0

  • TCCR0 : Timer/Counter Control Register 0

  • TIMSK : Timer/counter Interrupt MaSK 0

  • TIFR : Timer/counter Interrupt Flag Register


[그림 2] T/C0와 관련된 핀들


위 그림은 T/C0와 관련된 핀(T0핀)을 표시한 것이다.



Posted by 살레시오
,

 파이썬에서 심볼릭 (symbolic) 수학을 지원하는 sympy 라는 모듈이 있다. winPython을 사용한다면 기본적으로 설치되어 있으므로 사용하고 싶다면


>>> import sympy as sp

라고 하면 된다. 흥미로운 것은 수학 계산식을 LaTex 스타일로 깔끔하게 표시할 수 있다. 이를 위해서는 다음과 같은 이 모듈 내의 함수를 호출하면 된다.

>>> sp.init_printing() # 수식을 LaTex 스타일로 표시한다.


만약 배경색을 검은 색으로 사용하고 있다면 다음과 같이 글자색을 흰색으로 지정해 줄 수 있다.


>>> sp.init_printing(forecolor='White')

이 함수를 맨 처음 실행시킬 때는 별도의 패키지를 인스톨하라는 대화창이 뜨며 한 번만 인스톨해주면 된다. 이렇게 하면 이후에 수학식이 LaTex 스타일로 굉장히 깔끔하게 표시된다. 예를 들면 아래와 같다.


유니코드를 사용하여 수식을 표시하는 함수로 pprint()가 있다. 만약 아스키코드로만 표시하고 싶다면 use_unicode = False 옵션을 주면 된다.


>>> expr = sp.sqrt(x/(x**2+1))+sp.pi
>>> sp.pprint(expr) # 유니코드를 이용하여 수식 표시
         ________    
       ╱   x        
     ╱  ──────  + π
   ╱    2         
╲╱    x  + 1     
>>> sp.pprint(expr,use_unicode=False) #아스키코드로 수식 표시
    ________     
   /   x         
  /  ------  + pi
 /    2          
\/    x  + 1      


 그런데 sympy 에는 init_session() 이라는 함수가 있는데 이 함수의 옵션으로 ipython=True 를 주면 sympy 모듈이 전역 공간으로 임포트되며 LaTeX 모드가 활성화된다.

init_session()함수를 호출하면 내부에서 from sympy import * 가 수행되므로 이 모듈의 모든 함수/변수가 전역 공간에 올라온다. 따라서 이후에는 ipython 콘솔을 sympy 위주의 쉘로 활용할 수 있다.

다른 방법으로 위와 같이 명령어로 입력하지 않고 설정창에서 지정해 줄 수 있다.


만약 sympy 위주로 쉘을 사용하고 싶다면 이 옵션을 지정해 주는 것도 좋을 것이다.

하지만 sympy 도 다른 모듈들(numpy 등)과 구분하여 사용하고 싶다면 맨 처음에 소개한 명령어를 사용하는 것이 좋다.

>>> import sympy as sp
>>> sp.init_printing() # LaTex 스타일로 수식 표시

 ipython의 매직 명령어인 %matplotlib inline 이라고 하면 ipython 창에 그래프를 그려준다.


>>> %matplotlib [gui]


여기서 [gui] 옵션으로 inline, gtk4, qt4 등을 줄 수 있으며 inline 을 주면 ipython 창 내부에 그래프를 도시해 준다. 이후에 예를 들어 sympy.plot() 함수 등을 사용하면 ipython 내부 창에 그래프를 띄워준다.

 만약 초기에 이러한 설정으로 시작하고 싶다면 옵션으로 지정하여 ipython 창이 생성될 때 자동으로 설정되도록 할 수 있다. 아래 그림과 같이 Support for graphics (Matplotlib) 항목 내의 Active support 를 체크하면 ipython 이 시작될 때 그래프 기능을 활성화시킨다.

단 이 옵션은 자동으로 numpy 와 matplotlib.pyplot 모듈을 np, plt 이름으로 임포트시킨다. 이것은 dir() 명령으로 확인할 수 있다.


 두 번째 항목인 automatically load pylab 은 비활성화시키기를 권장한다. pylab 은 내부에서 numpy와 matplotlib.pyplot 등의 모듈들을 전역공간으로 임포트하여 함수들을 관리하는데 혼동을 주기 때문이다.



Posted by 살레시오
,

 오토데스크사의 인벤터를 사용하다 보니 이것과 비슷한 워크플로우로 작업을 할 수 있는 오픈 소스나 무료 프로그램이 있을까 해서 찾아보았는데 다음과 같은 것들이 눈에 띈다.

 

123d Design 은 인벤터 개발사인 autodesk사가 만든 것인데 프로버전은 구매를 해야 하지만 기 본적으로 무료로 사용할 수 있고 인벤터에 익숙하다면 곧바로 사용할 수 있을 정도로 구성이나 메뉴가 유사하다. 간단한 기계부품을 설계하는데 손색이 없다. 독립적인 프로그램을 설치해서 사용할 수도 있고 웹버젼도 있다는 것이 특징이다.


[그림 1] autodesk 사의 123d design


 freeCAD는 아직 버전이 0.15 이지만 싱당히 강력해 보이는 3d캐드이다. 오픈소스로 개발되고 있으며 가강 강력한 인벤터의 alternative가 아닐까 개인적으로 생각된다. 향후 발전이 상당히 기대된다.


[그림 2] freecad 오픈소스 무료 3d 캐드 프로그램이다.

 

 designspark mechanical은 rs 사에서 제공하는 무료 기계설계 3d캐드 프로그램이다. 현재 (2014년 10월) 버전은 1.0이지만 기능은 빈약한 것 같다.

[그림 3]  designspark mechanical


 이 중에서 가장 인벤터와 비슷하게 사용할 수 있는 것을 꼽으라면 freecad 이다. 인벤터에서의 설계 순서(2d 스케치 -> 돌출 -> 2d 스케치 -> 돌출…)와 비슷하게 기계 부품을 설계해 나갈 수 있다.




Posted by 살레시오
,