제작년에 keras로 CUDA환경을 구축하려다가 정말 정보의 심각한 부족으로 실패한 적이 있었는데, 이번에는 별 문제 없이 한번에 성공하여서 그 과정을 기록하려고 합니다.


저에게도 의미있는 기록이지만, 다른 분들도 많은 도움이 되셨으면 좋겠네요.



이번에는 keras같은 상위 wrapper 없이 텐서플로 그대로 진행하였습니다.


도움을 많이 받은 문서는

https://www.tensorflow.org/install/gpu

로, 텐서플로 페이지 자체에서 제공해주고 있습니다.


아래는 제 컴이 윈도우즈인 관계로 윈도우즈를 기본으로 합니다.

만약 linux와 같은 운영체제이신 경우 위의 텐서플로 홈페이지에서 리눅스는 어떻게 설치하는지 잘 알려줍니다!


1) 본인의 GPU가 CUDA GPU 환경을 제공하는지를 확인해 봅니다.

기본적으로 CUDA가 엔비디아nVidia사에서 만든 플랫폼이므로 엔비디아의 지포스 제품이면 일단 가능성은 있지 않을까 생각해 볼 수 있을 것 같습니다.

그리고 GTX 붙으면 일단 된다고 보시면 될 것 같습니다.

요기로 가시면 CUDA가 가능한 GPU인지 확인해 보실 수 있습니다. https://developer.nvidia.com/cuda-gpus

저는 GTX 1060이라 묻지도 따지지도 않고  그냥 설치했습니다.


2) 차례대로 NVIDIA® GPU drivers, CUDA® Toolkit, CUPTI, cuDNN을 깔아줍니다.

텐서플로-gpu는 먼저 깔아도 되고 위의 4가지 프로그램을 다 깔고 깔아도 되는 것 같습니다.

CUPTI는 굳이 안깔아도 될 것 같기는 한데, 저번에 한번 CUDA하려다 안되서 작은 가슴에 그냥 깔고 진행했습니다.


2*) gpu환경을 사용하기 위해서는 tensorflow-gpu를 깔아야 합니다. 아나콘다를 사용하시면 아나콘다 프롬프트에서 conda install tensorflow-gpu를, 아니시라면 pip install tensorflow-gpu를 입력하시면 tensorflow-gpu가 깔립니다. tensorflow-gpu가 깔리면, 이전과 같이 import tensorflow하시면 됩니다.


3) 다 깐 뒤에 시스템 PATH를 설정해 주어야 합니다.

여기서는 시스템 PATH를 설정해 주는데, 깔린 위치가 정확해야 합니다.

드라이버와 툴킷을 깔면 설치파일처럼 설치가 되고, CUPTI와 cuDNN은 압축파일로 풀리게 될 것 입니다.

여기서 설치파일은 상관이 없는데, CUPTI과 cuDNN은 압축을 푼 뒤 폴더 이름을 각자 'CUPTI'와 'tools'로 바꾸어 줍니다.

그리고 CUPTI 폴더는 'C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\extras'아래에 폴더를 통채로 복사 붙여넣기 해주시고, tools 폴더는 C드라이브 아래 바로 붙여넣어 주세요.


이후 아무 명령 프롬프트나 여시고(예를 들어 실행->cmd)

SET PATH=C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\bin;%PATH%

SET PATH=C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\extras\CUPTI\libx64;%PATH%

SET PATH=C:\tools\cuda\bin;%PATH%

요렇게 세 개를 써주시면 됩니다.


텐서플로에서 9.0만 지원한다고 그래서 찾다가 저는 9.1로 설치하였는데, v10도 텐서플로에서 잘 작동하는 것 같습니다. 만약에 오류가 나시면 v9.1로 시도해 보세요.


4) 제대로 깔려서 gpu에서 사용되는지 확인하기 위해서

파이썬을 켜시고(명령프롬프트에서 python 치셔도 되고, jupyter notebook에서 cell에 입력하셔도 됩니다.)

from tensorflow.python.client import device_lib 

print(device_lib.list_local_devices())

이렇게 입력해서 무언가 주르륵 나온다 하면 설치가 제대로 된 것입니다.

그리고 이후에 tensorflow 소스코드에서


device_name = "/gpu:0"

log_device_placement = True


with tf.device(device_name):

    x = tf.placeholder(tf.float32, shape=[None, 32, 32, 3])

    y = tf.placeholder(tf.float32, shape=[None, 10])

    .

    .

    .


with tf.Session(config=tf.ConfigProto(log_device_placement=log_device_placement)) as sess:

    sess.run(tf.global_variables_initializer())

    .

    .

    .


요런식으로 소스 코드를 수정해주시면 프로그램 실행 중 명령 프롬프트에서 실제로 GPU가 사용되는 현황을 볼 수 있습니다.

중요한 단어들만 추려보았습니다.


deterioration악화
ailment질병
pinning down집어내다
tapestry태피스트리
institutionalized제도화된
emancipate해방시키다
proclamation선언서
freed자유로운
scour샅샅이 뒤지다
faring성공 정도를 가늠하다
acknowledgement인정
posit상정하다
divulge누설하다
self-actualization자기실현
adversity역경
incorporate포함하다
vernacular방언
implement시행하다
notarize공증하다
hastily급하게
disparate다른
patronizing거만한
hypocrisy위선
take a stance입장을 취하다
resonate with반향을 불러일으키다
surmise추측하다
pillage약탈하다
detour우회도로
take a detour우회하다
pull over길가에 대다
meander구불구불하다
careen위태롭게 달리다
diverge갈라지다
diverge from~에서 갈라지다
hail불러세우다, 환호하며 맞이하다
bail보석을 받게 하다
trail질질 끌다, 추적하다
hail a cab택시를 불러 세우다
charter전세 내다
designate지정하다
curb(n)도로 경계석
curb(v)억제하다, resist
moor정박시키다, dock
veer방향을 바꾸다
cramped비좁은
opposite to~의 반대편에
interruptdisturb
recommend that + ?(should) R
disregard무시하다
be bound for~행이다
be bound to V반드시 ~하게 되어있다
mode of transportation교통수단
descent하강, 혈통
make a right우회전하다
abide by따르다
ascertain확인하다
bald마모된
be backed up교통이 정체되다
behind the wheel운전하여
boulevard큰길
crooked굽은
dealership판매대리점
dent움푹 들어간
double-park이중 주차하다
go downhill더 나빠지다
grab a cab택시를 잡다
guidepost이정표
hold up traffic교통을 정체시키다
hull배의 선체
speeding ticket속도 위반 딱지
tow견인하다
attrition마찰
crackdown일제단속
deflect빗나가게 하다
desist그만두다
deviate벗어나다
drive under the influence음주운전하다
elapse시간이 경과하다
enumerate열거하다
foible약점
jaywalk무단횡단하다
jolt크게 흔들리다
rear-end~에 추돌하다
stall(v)엔진이 멎다
stall(n)노점
strident귀에 거슬리는
swerve방향을 바꾸다
trudge터덜터덜 걷다
unheeded무시된
an arm and a leg비싼
get ahead성공하다
get down to~을 시작하다
if you ask meI think
time off휴가
turn down~을 거절하다
rope off~을 차단하다
pull off해내다
cater to AA의 구미를 맞추다
soggy질퍽한
let up나아지다
tie the knot결혼하다
kick in약효가 나타나다
out of the blue뜻 밖에도
capitol국회의사당
resort to AA에게 의존하다


이 단어들은 quizlet에서도 보실 수 있습니다.


https://quizlet.com/_68ehl9

요 근래에 꾸준하게 통계에서부터 머신러닝을 거쳐 딥러닝을 배우고, 딥러닝을 배우고, 딥러닝을 또 배우다보니 뭔가 정리를 하고 싶은 욕망이 꾸물꾸물 올라오네요.


사실 인터넷에 찾아보면 정말 한 포스팅 내에 삐까뻔쩍하게 사진이랑 막 수식이랑 코드랑 막막 쓰이면서 그런 포스팅들이 넘쳐날 것을 알지만..


그래도 실제로 계속해서 배우는 사람의 입장으로 뭔가 거창한 거 빼고 담담하게 중요한 부분들만 간단하게 정리한 포스팅은 없지 않을...까? 해서 적어보는 포스팅입니다.


사실 한 포스팅안에 그 많은 딥러닝에 대한 내용을 담는 것도 어렵고 해서 제가 시간이 날 때마다 차근차근 써 볼 생각입니다.


그리고 제가 아는 한도 안에서 거창하지 않게 쓸 것이라, 이 부분에서는 이 글을 읽으시며 틀을 잡으시고 관련된 부분들을 찾아보시면 더 좋을 것 같습니다.(그리고 사실 그것이 제가 이 블로그를 만든 이유이기도 하지요.. 문턱에너지를 낮춰주는 블로그...)


그럼 시작해보겠습니다.


일단 역사보다는...


자, '딥러닝'은 왜 '딥러닝'일까요?


사실 딥러닝을 알기 전에 '머신러닝'이라는 것을 먼저 알아야 합니다.


딥러닝은 '기계가 스스로 학습한다'는 기계 학습 혹은 머신 러닝의 한 부분이기 때문이지요.


그리고 머신러닝에서는 입력과 출력 사이의, 사람으로 치자면 '추론의 단계'를 스스로 공부하는 것이죠.


이 추론의 단계를 '블랙 박스'라고 그냥 생각해 보자면


머신러닝은


'입력 -> 블랙 박스 > 출력'


이렇게 됩니다.


그리고 이 '블랙 박스'를 사람이 어느정도 수학적 알고리즘으로 만들어 주게 되면, 시행과 오차를 반복하며 스스로의 로직을 찾아갑니다.


그런데 딥러닝은 요 '블랙 박스' 부분이, "진짜로" 블랙 박스입니다.


머신 러닝은 사람이 어느정도의 수학적 알고리즘을 부여해 주고 그에 따른 답을 찾는 것이었다면(즉, 대략 찾아가는 방식을 아는 것이라면), 딥러닝에서는 아예 사람이 요 부분에 손을 대지 않습니다.


그래서 결국에 답이 나와도 '어째서 이 답이 이렇게 나오지?'하는 부분을 모르는 것입니다.


그리고 요 블랙 박스 부분이 머신 러닝과 다르게 긴 여러개의 과정을 가지기 때문에 '딥' 러닝이라고 부르는 것입니다. (긴것을 깊다고 볼수도 있지요)


반대로 머신러닝을 'Shallow learning'이라고 부르는 경우도 있습니다.


그리고 이 블랙박스 부분은 로젠 블라트라는 사람이 고안한 퍼셉트론에서 출발한 '인공 신경망'이 기본인데, 이 부분은 제가 이후에 다룰 수도 있고, 이 부분 부터는 인터넷에 정말 많은 정보들이 있으니 직접 찾아보셔도 좋을 것 같습니다.



사실 딥 러닝이라는 어려운 분야를 정말 짧고 단숨에 읽히는 포스팅으로 쓰기 위해 여러 지식을 한번에 묶어서 쓰려니 힘드네요...


그래도 이 글을 읽고 '와! 딥러닝! 아시는구나!' 하셨으면 좋겠습니다.


그럼 다음에 뵈어요~

인터넷에서 여성 호신용품(키링형 알람벨)을 샀는데, 배송이 늦어 그 중간 기간에 어떻게 할까 싶어 인터넷을 뒤져 보았습니다.


네X버에 검색한 결과, 블로그 포스팅 중 단 하나에서 다이소에서 알람벨 키링을 판다는 정보가 있어 다이소에 사러갔었는데, 현재는 팔지 않는 것 같습니다.



호신벨 키링에 대한 이미지 검색결과

요렇게 생긴 것입니다. 저 몸체를 키링에서 뽑아버리면 정말 어마어마한 소리가 뿜뿜.

<이미지 : 구글 검색>



동네에 있는 다이소 3곳, 지하철 몇 정거장 건너 있는 다이소 1곳 을 전부 확인한 결과 없었고, 가장 크다는 명동 다이소에 가서도 없었네요.


파는 것은 키링형 호루라기 2종류 뿐입니다.


혹시 저처럼 잘못된 정보에 낚여 여러 다이소를 전전하는 수고를 하지 마시기 바랍니다.



명동 다이소에 대한 이미지 검색결과

명동에 있는 8층 짜리 다이소... 여기에도 없었습니다.

<출처 : 구글 이미지 검색>



혹시나 파는 다이소가 있는 경우 댓글로 제보해 주시면 본문에 반영하겠습니다.


그 미세먼지 뿜뿜하던 주말간에 빨빨거리고 돌아다녔던 걸 생각하면 두가 아파오면서도 다른 분들은 잘못된 정보에 낚이시지 않으셨으면 좋겠어서 이렇게 포스팅 합니다.


(그러나 과연 네X버 검색에 최소한 그 글이랑 같이 올라갈 수나 있을까...)

오늘의 포스팅은 암호로 보호된 (복사 금지 된) pdf 해결 방법이다.


TIPS에 적는 것이니 만큼, 블로그 노출도는 낮겠지만, 가장 간단한 플레인 텍스트로 작성하겠다.


1) smallpdf.com

pdf 암호 해제 사이트

인터넷에서 찾아보면 가장 사람들이 많이 찾는 사이트이다.

장점 : 인터넷 상에서 사용 가능

단점 : 한시간에 2개 밖에 작업 불가, 암호 해제 속도 느림


2) allinpdf.com

pdf 암호 해제 사이트

인터넷에서 두번째로 많이 나와 있는 사이트.

장점 : 인터넷 상에서 사용 가능

단점 : 암호 해제 속도 느림


3) 짜투리 패스워드 리커버리

파일에 걸린 암호 해제 프로그램

암호라는 것이 사용하는 키의 종류가 증가하면 할수록 기하급수적으로 가짓수가 늘어나니 어느정도 암호 추측이 가능한 경우에 사용

사용 방법은 암호 생성에 사용한 종류(숫자, 특수문자, 문자 등)와 암호 길이를 입력해주면 순식간에 찾아준다.

본인이 암호 입력하고 까먹었을 때 어느정도 경우의 수를 줄여서 찾아주는 것이 기본 모토이다.


4) 알pdf

이번에는 pdf 자체의 암호를 없애는 것이 아닌 pdf에서 복사 금지된(암호 걸리면 복사도 못하게 된다) 내용만 빼보는 방법이다.

특히 어차피 pdf 자체의 암호를 풀어도 그 내용을 가지고 다시 엑셀이나 문서로 만들어야 하는 경우에는 이것이 더 빠르다.

방법은 알pdf 다운 및 설치 -> 알pdf에서 pdf파일 열기 -> 상단 리본메뉴에서 '~로'라고 써있는 부분을 클릭하여 내보내기


5) Advanced pdf password recovery

패스워드 리커버리 프로그램의 일환

30일짜리 쉐어웨어 프로그램이고 정식으로는 돈 주고 써야하는 러시아 프로그램

인터넷에 잘 찾아보면 프리 프로그램이 있다.



일단 블로그가 검색이 되게 하려면 각종 웹사이트의 웹마스터도구에 블로그를 연동시켜야 합니다.


보통 네이버, 다음, 구글 정도면 어느정도 커버가 되는데, 더 하고 싶은 분들은 , 빙, 네이트 정도를 추가적으로 하시는데 빙은 티스토리 블로그는 연동이 안되는 것 같고, 줌이 은근히 많이 들어와서 줌을 추가적으로 등록하시면 될 것 같습니다.


여기서 티스토리 블로그는 다음과 네이트에 자동으로 연동되어 있으니, 네이버와 구글(혹은 더 추가적으로 줌) 웹마스터도구에 등록하여주면 되고, 네이버 블로그는 다음에만 연동시키면 네이트까지 자동으로 연동됩니다.


줌의 경우 그냥 들어가기만 해도 가입 없이 바로 신청이 가능하며(http://help.zum.com/submit/register), 구글의 경우도 그냥 신청하면 어느정도 문제없이 잘 작동됩니다.


문제는 네이버인데, 네이버 웹 마스터 도구가 참 까다롭습니다.


네이버 웹 마스터 도구에 사이트를 등록하고 인증을 받아도, 사실 네이버에 잘 뜨지 않는데, 그 이유는 '수집'이 문제인 것 같습니다.


네이버 웹마스터도구에서는 웹페이지 수집 요청을 할 수 있습니다.(https://webmastertool.naver.com/site/request/crawl.naver?site=https%3A%2F%2Fomnil.tistory.com)

아마 로봇이 자동으로 수집하지 못하는 것을 사용자가 직접 수집 요청을 해주는 것 같은데, 저의 경우 네이버 웹마스터도구에 등록해놓아도 제 블로그가 수집이 되지 않아 한번 일괄적으로 요청을 하였습니다.


그 이후 'RSS제출'에서 RSS주소를 제출해주는데, RSS주소는 티스토리 기준 '본인의 티스토리 주소/rss'입니다. (https://omnil.tistory.com/rss)

여기서 티스토리 블로그 관리에서 '관리' -> '블로그' -> 하단의 '기타설정' 에서 RSS를 '50개'로 갱신이라고 바꾸어줍니다.


그리고 사이트맵도 만들어서 네이버와 구글에 각 업로트 해주시면 됩니다.


사이트맵 만드는 방법의 경우 인터넷에서 검색시 잘 나오니 추가적으로 참고하시면 됩니다.


자세한 설정 주소는 http://www.web-site-map.com/입니다.

자세한 설명은 https://www.sitemaps.org/ko/protocol.html#escaping입니다.



약 사이트맵은 한달 주기로 수집 요청은 매일 하는 것이 좋아 보입니다.


또한 백링크를 많이 받으면 사이트 지수가 올라가는데, 백링크란 다른 사이트에서 내 사이트를 언급하는 것을 말합니다. 평판이 높은 사이트에서 한번 링크하는 것이, 낮은 사이트에서 여러번 링크하는 것보다 더 지수가 높다고 합니다.

이제부터는 운동기록 8일차부터 계속해서 반복한다.


시험 때문에 거의 며칠을 쉬었지만, 그래도 꾸준히 하는 것에 보람이 있었다.


매 회 30초도 쉬지 않고 꾸준히 하여 약 25분이 걸렸다.

##타이머

ATMega 128에서는 4개의 타이머가 존재한다.

각 타이머는 0, 1, 2, 3과 같은 번호를 가지고 있으며, 이 번호는 나중에 레지스터를 할당할 때 사용된다. (ex, TCCR0)

이 중 0, 2번 타이머는 8비트 타이머이고 ATMega 128기준 7372800Hz를 갖는다.

그리고 나머지 1, 3번 타이머는 16비트 타이머이다.


타이머는 보통 세개~네개 정도의 레지스터만 선언해주면 사용이 가능하다. (interrupt 헤더파일은 선언해 주어야 한다.)


TCNTn(Timer/CouNTer register)

 이름에서 보이듯이 직접 타이머를 카운트하는 레지스터이다. 0~255의 값을 가질 수 있으며 만약 이 값을 우리가 임의대로 수정하면, 이후 타이머는 수정된 값 이후부터 더하고, 초기화 되어도 수정된 값으로 초기화가 된다.


OCRn (Timer/Counter Output Compare register n)

 아래에서 설명할 CTC모드와 고속 PWM 모드에서 사용되는 레지스터. 0~255사이의 값을 가지며 타이머의 속도를 조절할 수 있는 역할을 한다.


TCCRn(Timer/Counter Control Register n)

 사실상 타이머를 사용하는데 가장 중요한 레지스터이다.

 구조는 8비트로 | FOCn | WGMn1 | WGMn0 | COMn1 | COMn0 | CSn2 | CSn1 | CSn0 | 이며,

 FOCn(Force Output Compare n)과 COMn0, COMn1(Compare match Output Mode n)은 고급 제어에서 이용되며, 가장 단순하게 타이머 용도로만 사용할 정도면 WGM과 CS만 이해하여도 크게 문제가 없다.

 따라서 이번 포스팅에서는 WGM과 CS에 대해서만 설명한다.

 1) WGMn1 WGMn0 (Waveform Generation Mode n)

WGM의 경우 CS와 다르게 그 위치가 8비트 상에서 연속되어 있지 않으므로, 정확한 위치 확인이 필요하다.

아래 진리표의 경우 WGMn1 WGMn0 순으로 작성된 것으로, 실제 레지스터에 적용시에는 그 구조를 파악하여 정확히 써주어야 한다.

0 0 : 일반 (0~255->0~255) => TCNT레지스터의 값이 0부터 255까지 차례로 증가한 뒤 TOV라는 레지스터로 값이 다 찼다는 결과를 주고 다시 0으로         초기화 된 뒤 255까지 다시 올라가는 방식이다.

0 1 : 위상정정 PWM(Pulse Width Modulation) (0~255~0~255) => TCNT레지스터의 값이 0부터 255까지 차례로 증가한 뒤 일반 모드와는 다르게         바로 0으로 초기화 되는 것이 아니라, 0까지 값을 하나씩 줄여가는 방식이다. 0으로 줄은 상태에서 TOV값이 리턴된다. 물론 0이 되면 다시 값이         1씩 증가한다.

1 0 : CTC(Compare Timer on Compare match) (0~OCRn->0~OCRn) => 다른 방식들과는 다르게 0부터 OCRn 레지스터에 저장된 값까지만 증가하고,         OCRn(Timer/Counter Output Compare register n)레지스터 값과 TCNT레지스터의 값이 동일해지면 TOV를 반환하고 0으로 다시 초기화 된다.

1 1 : 고속 PWM (0~255->0~255) => TCNT레지스터의 값이 0부터 255까지 차례로 증가한 뒤 TOV라는 레지스터로 값이 다 찼다는 결과를 주고 다시         0으로 초기화 된 뒤 255까지 다시 올라가는 방식이다. 일반 모드와 다르게 고속 PWM은 0부터 255까지 증가하지만 OCRn값이 있다면, 그         시기에 즉시 OCn(Output Compare n)값을 리턴한다.

 2) CSn2 CSn1 CSn0 (Clock Select)

프리스케일러(free scaler)라고도 불리며, 분주기라고도 불린다. 이 세 비트의 상태에 따라서 한 클럭마다 신호를 발생할 것인지, 아니면 그것보다 낮은 클럭으로 신호를 발생할 것인지 선택이 가능하다.

0 0 0 : 정지

0 0 1 : 7372800(클럭상태)

0 1 0 : 7372800/8 = 921600(921600클럭으로 돌아가는 것과 같은 상태)

0 1 1 : 7372800/32

1 0 0 : /64

1 0 1 : /128

1 1 0 : /256

1 1 1 : /1024 => 약 71ms로 동작


TIMSK(Timer/Counter Interrupt MaSK register)

 TIMSK = 0x01;로 선언하면 overflow 인터럽트를 Enable한다.


TIFR(Timer/Counter Interrupt Flag Register)

 TOV 발생 시에 기록하는 레지스터.

 TIFR = 0xFF;로 선언하면 첫 인터럽트 시작이 0이 된다.


Sei(); <= 인터럽트 인에이블 함수


SIGNAL(SIG_OVERFLOW0) <= 타임 인터럽트 서비스 루틴


SIGNAL(SIG_OUTPUT_COMPARE0) <= OCR모드일 때 인터럽트 서비스 루틴



* 타이머 조작

1) TCNT를 직접 설정하는 방법 : 한번 설정 시 TCNT부터 255까지 증가

2) 프리스케일러 조작

3) CTC모드로 조작 : OCRn 설정시 0부터 OCRn까지 증가

##인터럽트

AVR에서 인터럽트를 제어하려면 네가지 선언과 한가지 include, 한가지 함수만 사용할 수 있으면 된다.


1. 4가지 선언

 1) 포트개방

 2) EICRA/B

 3) EIMSK

 4) SREG


1) 포트개방

ATMega 128에서는 D0~3번 포트 그리고 E4~7번 포트로만 인터럽트 신호를 받을 수 있다. 따라서 이에 해당하는 포트를 개방시켜주어야 한다.

DDR로 포트개방시 1은 출력 0은 입력을 뜻하므로, DDRD = 0x00; 등으로 선언해 주면 D포트에서 입력을 받겠다는 명령이 된다.

2) EICRA/B (External Interrupt Control Register A/B, 외부 인터럽트 제어 레지스터)

EICR 레지스터는 8비트로 2개 비트씩 한 쌍을 이룬다. 예를 들어, PD0에 대하여 01 00의 두개 비트를 가진다. 그리고 두개의 비트의 조합에 따라

EICRA

00 Low Level

01 예약

10 INT 하강에지

11 INT 상승에지

EICRB

00 Low Level

01 논리변화

10 INT 하강에지

11 INT 상승에지

와 같은 동작을 수행한다.


구조는 다음과 같다.                                      1bit 2bit 3bit 4bit 5bit 6bit 7bit 8bit

EICRA(외부인터럽트 0~3 트리거 설정 [PD0~3]) : | 31 | 30 | 21 | 20 | 11 | 10 | 01 | 00 |

EICRB(외부인터럽트 4~7 트리거 설정 [PE4~7]) : | 71 | 70 | 61 | 60 | 51 | 50 | 41 | 40 |


예를 들어, PD0에 대해서 상승에지에 인터럽트를 감지하고 싶다면

EICRA = 0b00000011; 이라고 선언해주면 된다.

3) EIMSK(External Interrupt MaSK, 외부 인터럽트 마스크 레지스터)

8비트이며 각 포트에서 발생한 인터럽트를 Enable할 것인지(수용할 것인지), Disable할 것인지(무시할 것인지) 판단하는 레지스터이다.

구조는 EIMSK : | INT7 | INT6 | INT5 | INT4 | INT3 | INT2 | INT1 | INT0 | 이다.

예를 들어, PD0에서 발생하는 인터럽트를 수용할 것이라면

EIMSK = 0b00000001;로 선언해주면 된다.

4) SREG(Status REGister, 상태 레지스터)

8비트이며 각 비트는 현재 CPU의 상태를 나타내준다.

최상위 I 비트가 1이 아닌 경우 인터럽트를 받지 않기 때문에, 1로 강제로 세팅해준다.

구조는 SREG : | I | T | H | S | V | N | Z | C |

I 글로벌인터럽트

T storage

H half carry

S sign

V overflow

N negative

Z zero

C carry

즉, SREG |= 0b10000000; 이며, 다른 레지스터와 다르게 원래 SREG와 or 연산을 시키는 이유는 SREG자체가 상태레지스터로 현재 프로그램이외에 다른 상태를 나타낼 수 있기 때문이다.


*) EIFR(Interrupt Flag Register)라는 것도 있는데, EIMSK와 비슷하게 각 자리가 Interrupt 포트와 매치된다. 이 레지스터는 각 포트에서 인터럽트가 발생하였는지 표시하는 레지스터이다.


2. 한가지 인클루드

#include<avr/interrupt.h>

인터럽트를 사용하려면 이 헤더파일을 인클루드 시켜주어야 한다.


3. 한가지 함수

ISR(INT4_vect)

이 함수는 INT4 포트에서 입력되는 인터럽트 신호가 있으면 작동되는 함수이다.

메모장에서는 찾기, 찾아바꾸기 시 엔터(개행문자, 줄바꿈)를 찾지 못함


한글에서는 '^n'이라는 것으로 엔터를 찾아내거 찾아서 바꿀 수 있음

+ Recent posts