레이블이 ATMEL인 게시물을 표시합니다. 모든 게시물 표시
레이블이 ATMEL인 게시물을 표시합니다. 모든 게시물 표시

2016년 2월 16일 화요일

Atmel Studio 7.0으로 아두이노 메가/우노 사용하기 (Programming Arduino Mega/Uno using Atmel Studio 7.0)

아두이노 IDE를 사용하면 아두이노 보드들을 쉽게 프로그래밍 할 수 있지만 레지스터를 직접 조작해 다양한 peripheral들을 세부적으로 조작하려면 Atmel studio를 사용할 수 밖에 없는 경우가 생긴다.

먼저 arduino ide를 설치해 준다. 아두이노 메가의 플래쉬에 프로그램을 집어 넣기 위해 avrdude라는 툴을 사용하는데 아두이노 IDE에 포함되어 있기 때문이다. avrdude의 위치는 c:\Program files\Arduino\hardware\tools\avr\bin 폴더에 들어 있다. 사용하기 쉽게 하기 위해 저 폴더에 있는 avrdude.exe 파일과 c:\Program files\Arduino\hardware\tools\avr\etc 폴더에 있는 avrdude.conf 파일을 사용하기 편한 위치의같은 폴더에 집어 넣어 준다.



여기서는 C:\Utils 폴더에 avrdude.exe와 avrdude.conf 파일을 넣어 주었다.

이제 Atmel studio 7.0을 실행한 후 상단의 메뉴 항목에서 Tools->External Tools 를 선택한다.

창이 열리면 우측의 'Add' 버튼을 누른 후 아래쪽 4개의 칸을 다음과 같이 입력해 준다.



Title: MEGA writing  <- 임의의 이름을 지정
Command: C:\Utils\avrdude.exe <- avrdude.exe 파일의 위치를 지정
Arguments: -v -v -patmega2560 -cwiring -PCOM9 -D -Uflash:w:$(TargetDir)\$(TargetName).hex:i <- avrdude를 호출할 때 사용할 파라미터들. 여기서 COM9는 자신의 환경(아두이노 메가의 시리얼 포트)에 맞게 변경해 줘야 함
Initial directory: $(TargetDir) <- 이대로 지정

그리고 Use Output window 항목을 체크해 주고 'OK' 버튼을 눌러주면 된다.



다시 메뉴에서 Tools를 선택하면 MEGA writing 이라는 항목이 생긴걸 볼 수 있다.

이제 프로젝트를 만들어 프로그램을 빌드한 후 'MEGA writing' 을 선택하면 빌드 된 hex 파일이 아두이노 메가의 플래쉬에 기록되어 실행되게 된다.

프로젝트를 만드는 방법은 이전 포스트(Atmel Studio에서 아두이노 듀에 사용하기)를 참고하면 된다. 다만 프로세서는 아두이노 메가에 맞는 것으로 선택해 줘야 한다.



프로그램을 완성해서 빌드한 후 방금 추가한 'MEGA writing' 을 선택하면 아두이노에서보다 훨씬 빨리 hex 파일이 플래쉬에 기록되는걸 확인할 수 있다.

----

그리고 프로그램을 만들어 컴파일 하다 보면 _delay_ms() 함수등에서 F_CPU가 선언되어 있지 않다고 에러가 나는 경우가 있다. 이런 경우 상단 메뉴바에서 Project 항목을 누른 후 맨 아래쪽에 프로젝트 Properties... 항목을 선택한다. (여기서는 megatest라는 이름의 프로젝트이므로 megatest Properties...라고 나왔지만 실제 megatest 대신 각자 프로젝트 이름이 나온다)



 Properties 탭이 열리면 Toolchain -> AVR/GNU C Compiler -> Symbols를 선택한다.
 기본적으로 Defined symbols 항목에 'DEBUG' 하나만 들어 있다.



Defined Symbols 오른쪽 끝의 + 버튼을 누르면 'Add Defined Symbols'라는 창이 열린다.


여기에 위와 같이 'F_CPU=16000000UL' 이라고 넣어주고 'OK' 버튼을 눌러주면 된다. 이제 다시 빌드 해 보면 에러가 없어졌을 것이다.

또한 printf() 함수로 출력되는 내용을 시리얼 포트로 보내주려고 하는 경우 '-Wl,-u,vfprintf -lprintf_flt -lm' 같은 내용의 링커 옵션을 추가해 줘야 하는 경우도 있다.

이 때는 Toolchain -> AVR/GNU Linker -> Miscellaneous 를 선택한 후 'Other Linker Flags'에 원하는 옵션을 추가해 주면 된다.

 


---
아두이노 우노를 사용하는 경우도 위와 동일하다. 다만 차이점은

Arguments: -v -v -patmega328p -carduino -PCOM9 -D -Uflash:w:$(TargetDir)\$(TargetName).hex:i

저기서 atmega2560 대신 atmega328p로, wiring을 arduino로 바꿔주는것 뿐이다. 그 이후는 프로젝트를 만들 때 프로세서만 atmega2560 대신 아두이노 우노의 프로세서인 atmega328p를 선택해 주면 된다.

2016년 2월 3일 수요일

Atmel Studio에서 아두이노 듀에(arduino due) 사용하기

Atmel studio에서 아두이노 듀에에 바이너리 파일을 넣으려면 bossa라는 프로그램이 필요하다. BOSSA(http://www.shumatech.com/web/products/bossa)는 Basic Open-Source Samba Application의 약자로 ATMEL의 ARM 프로세서 플래쉬에 writing을 위한 프로그램이다. 원래 ATMEL에서 SAMBA라는 툴을 제공하나 설정이나 사용이 복잡해 이 SAMBA를 기반으로 사용하기 쉽게 만든 프로그램이 BOSSA이다.

다만 기존의 bossa로는 아두이노 듀에에 사용할 수 없어 아두이노용으로 수정된 bossa가 필요하다. 혹시 자신의 컴퓨터에 bossac (BOSSA command line)이 설치되어 있으면 프롬프트에서 bossac -h 명령으로 버젼을 확인할 수 있다.


이렇게 나오면 아두이노 용으로 수정된 버젼이다. 만일 그렇지 않으면 아두이노용 bossa를 구해야 한다.

가장 쉬운 방법은 먼저 아두이노를 설치해서 실행한다. 실행한 후 화면 상단 메뉴 '툴->보드->보드 매니저'를 선택한다. 아래 스크린샷은 이미 설치가 되어 있지만 아두이노를 처음 설치하면 Arduino Due는 사용할 수 없는 상태이기 때문에 먼저 패키지를 설치해 줘야 한다.


 보드 매니저 윈도우에서 Arduino SAM Boards (32-bits ARM Cortex-M3) 를 선택한다.


 선택하면 오른쪽에 '설치' 버튼이 나타나므로 버튼을 눌러 패키지를 설치한다.


 설치가 끝나면 '닫기'를 눌러 보드매니저 윈도우를 닫고 다시 '툴->보드' 메뉴로 가 보면 이제 보드 목록 아래쪽에 Arduino Due 항목들이 보일 것이다.


 아두이노 듀에를 위한 툴체인이 설치된 것이다. 이제 설치된 툴체인에서 bossac을 찾으면 되는데 아두이노 1.6.5부터 툴체인 설치 위치가 이전 버젼과 달라졌을 뿐 아니라 시스템 숨김 파일로 되어 있어 그냥 찾으려고 하면 컴퓨터를 다 뒤져 봐도 찾을 수가 없다.

먼저 탐색기를 열어 사용자->[자신의ID] 폴더로 간다.


 탐색기의 '구성->폴더 및 검색 옵션' 메뉴을 선택한다.


폴더 옵션 윈도우가 열리면 '보기' 탭을 선택한 다음 '고급설정' 리스트를 아래로 스크롤 해 보면 아래 항목이 보일 것이다. 따로 설정을 변경하지 않았으면 디폴트로는 '보호된 운영 체제 파일 숨기기(권장)'가 체크 되어 있고, '숨김 파일 및 폴더'는 '숨김 파일, 폴더 또는 드라이브 표시 안 함'이 선택되어 있다.


 '보호된 운영 체제 파일 숨기기(권장)'는 체크를 없애고, '숨김 파일 및 폴더'는 '숨김 파일, 폴더 또는 드라이브 표시'를 선택한 다음 '확인' 버튼을 눌러준다.


이제 약간 희미한 폴더 아이콘들이 몇개 더 보이게 되었다. 여기서 'AppData' 폴더를 연다.


그 아래로 계속 쫒아가면 '...\AppData\Local\Arduino15\packages\arduino\tools' 에 bossac 폴더가 보인다. bossac 폴더 안에 폴더가 하나 더 있고 그 안에 bossac.exe 파일이 들어있다. 그냥 그 위치에 두고 사용해도 되지만 매번 찾기 귀찮으니 c 드라이브의 최 상단에 \utils 같은 폴더를 하나 만들어 그곳에 bossac.exe를 복사해 놓고 사용하면 편리하다.


이제 Atmel Studio를 실행한 후 상단 메뉴에서 'Tools->External Tools...'를 선택한다.


External Tools 윈도우가 열리면 초기 상태는 아래와 같다.


내용을 다음과 같이 변경한 후 'OK'버튼을 눌러 준다.

Title: Due writing <- 자신이 원하는 임의의 이름
Command: C:\Utils\bossac.exe   <- 아두이노용 bossac.exe 파일의 위치
Arguments: -e -w -v -b $(TargetDir)\$(TargetName).bin -R  <- 이대로 똑같이 입력
Initial directory: $(TargetDir)       <- 이대로 똑같이 입력

Use Output window는 체크


이제 Tools 메뉴를 보면 자신이 선택한 이름의 항목이 추가된 걸 볼 수 있다.


듀에에 USB 케이블은 Native USB 쪽에 꼽아주면 된다.


이제 SAM3X8E 프로세서용으로 프로젝트를 만들어 Build 한 후 위에서 추가한 메뉴항목(여기서는 Due writing)을 선택하면 bin 파일을 듀에의 플래쉬에 writing 해 준다. 만일 writing 하는데 포트를 찾을 수 없다고 에러가 나오면 먼저 ERASE 버튼을 잠시 눌러 준 후 듀에를 리셋 시키고 writing 을 하면 된다.




2010년 6월 12일 토요일

아뒤노에서 포트를 직접 억세스 (Direct Port Manipulation in Arduino)



아뒤노에서도 포트 레지스터를 사용하면 마이크로 컨트롤러의 I/O핀을 로우레벨에서 고속으로 조작할 수 있다. 아뒤노 보드(ATmega8과 ATmega168)에 사용된 칩은 3개의 포트를 가지고 있다.

  • B (digital pin 8~13)
  • C (analog input pins)
  • D (digital pin 0~7)

각 포트는 3개의 레지스터로 제어되고 레지스터들은 아뒤노에 변수로 정의되어 있다. DDR 레지스터는 각 핀이 INPUT 또는 OUTPUT인지를 결정한다. PORT레지스터는 핀의 출력값을 HIGH또는 LOW로 제어한다. PIN레지스터는 INPUT모드인 핀의 상태값을 읽는다.

DDR과 PORT레지스터는 읽고 쓰기가 가능하다. PIN레지스터는 입력 상태에 대응하며 읽기 전용이다.



PORTD는 아뒤노의 digital pin 0~7에 매핑된다.
  •   DDRD - 포트 D 데이터 방향 레지스터 (R/W)
  •   PORTD - 포트 D 데이터 레지스터 (R/W)
  •   PIND - 포트 D 입력 핀 레지스터 (R)

PORTB는 아뒤노의 digital pin 8~13에 매핑된다. 상위 2 비트는 crystal핀에 매핑되고 사용할 수 없다.
  •   DDRB - 포트 B 데이터 방향 레지스터 (R/W)
  •   PORTB - 포트 B 데이터 레지스터 (R/W)
  •   PINB - 포트 B 입력 핀 레지스터 (R)

PORTD는 아뒤노의 analog pin 0~5에 매핑된다. 핀 6, 7은 아뒤노 미니에서만 억세스할 수 있다.
  •   DDRC - 포트 C 데이터 방향 레지스터 (R/W)
  •   PORTC - 포트 C 데이터 레지스터 (R/W)
  •   PINC - 포트 C 입력 핀 레지스터 (R)
 
이 레지스터들의 각 비트는 핀 하나에 대응한다. 아뒤노 핀 번호와 포트/비트간의 전체 매핑은 칩의 다이어그램을 보면 된다. (포트의 일부 비트는 I/O이외의 용도로 사용될 수도 있기 때문에 그에 해당하는 레지스터 비트 값을 바꾸지 않도록 주의해야 한다.)

예제

위의 핀 맵을 참조하면 PortD 레지스터는 아뒤노 디지털 핀 0~7을 제어한다.

하지만 핀 0과 1은 아뒤노 프로그래밍과 디버깅을 위한 시리얼 통신에 사용되기 때문에 시리얼 입/출력 함수를 위해 필요하지 않는 이상 이 핀을 바꾸는건 피하는게 좋다. 이 값을 잘못 바꾸면 프로그램 다운로드나 디버깅을 방해받을 수 있다.

DDRD는 포트 D의 방향 레지스터이다. 레지스터의 각 비트는 포트 D의 핀이 INPUT 또는 OUTPUT으로 설정되도록 제어한다.

DDRD = B11111110;  // 아뒤노 핀 1~7은 출력으로, 핀 0는 입력으로 설정
DDRD = DDRD | B11111100;  // 더 안전한 방법. Rx/Tx로 사용되는 핀0과 1의 값은 변경하지 않고 핀 2~7을 출력으로 설정

PORTD는 출력 상태를 위한 레지스터이다.

PORTD = B10101000;  // 디지털 핀 7,5,3을 HIGH로 만듬

DDRD레지스터 또는 pinMode()를 사용해 저 핀들을 OUTPUT으로 설정해 놓은 경우 핀에서 5V가 출력되는걸 볼 수 있다.

PIND는 입력 레지스터 변수로 모든 디지털 입력 핀의 값을 동시에 읽는다.

포트 조작 팁

#define B0 B00000001
#define B1 B00000010
#define B2 B00000100
#define B3 B00001000
#define B4 B00010000
#define B5 B00100000
#define B6 B01000000
#define B7 B10000000

이렇게 비트를 정의해 놓으면 여러 핀을 동시에 H로 만들 경우는

PORTD |= B7 | B5 | B4;  // 디지털 핀 7, 5, 4를 HIGH로

여러 핀을 동시에 L로 만들 경우는

PORTD &= ~(B7 | B5 | B4);  // 디지털 핀 7, 5, 4를 LOW로

여러 핀의 값을 토글(현재값이 H면 L로, 현재값이 L이면 H로) 시키는 경우는

PORTD ^= B7 | B5 | B4;  // 디지털 핀 7, 5, 4의 값을 토글

Port manipulation을 사용하는 이유

일반적으로 이런식으로 포트를 직접 조작하는건 별로 좋은 생각이 아니다. 그 이유는

  • 코드 디버깅 및 관리하기가 더 힘들어지고 다른 사람이 이해하기 힘들다. 마이크로 프로세서가 코드를 실행하는건 몇 마이크로초밖에 안 걸리지만 그 코드가 왜 동작하지 않는가 찾아내고 수정하는데는 몇시간이 걸린다. 시간이 중요하지 않은가? 컴퓨터의 시간은 사용전력으로 따져보면 매우 싸다. 가능한 가장 확실한 방법으로 코드를 작성하는게 좋다.
  • 코드의 이식성이 떨어진다. digitalRead()와 digitalWrite()를 사용하면 모든 Atmel 마이크로 컨트롤러에서 실행시키는게 훨씬 쉽지만 컨트롤과 포트 레지스터는 각 마이크로컨트롤러마다 다를 수 있어 코드를 바로 사용하기 힘들수 있다.
  • 직접 포트 레지스터를 억세스하다 보면 의도하지 않은 문제를 만들기 쉬워진다. 위의 예제에서 DDRD = B11111110; 에서처럼 핀 0은 입력으로 남겨둬야만 한다. 핀 0는 시리얼 포트의 Rx이다. 하지만 실수로 핀 0을 OUTPUT으로 만들어버리면 갑자기 시리얼포트가 동작하지 않게 만들기 쉽다. 갑자기 시리얼 포트에서 데이터를 받을 수 없으면 매우 혼란스러울 것이다.

그럼에도 불구하고 왜 포트 레지스터를 직접 조작해야 하는가? 포트 레지스터를 직접 억세스하면 다음의 장점이 있다.

  • 핀의 출력을 H/L로 매우 빠르게(몇 나노초 이내에) 바꾸는게 필요한 경우가 있다. lib/targets/arduino/wiring.c 소스코드를 보면 digitalRead()와 digitalWrite()는 각각 몇십줄의 코드로 된 걸 볼 수 있는데 이는 컴파일되면 상당한 양의 기계어 명령어가 된다. 각 기계어 명령어는 16MHz 클럭사이클에서 한 클럭사이클이 필요한데 시간에 민감한 어플리케이션에서는 상당한 부담이 된다. 그에 비해 포트를 직접 억세스하면 훨씬 적은 클럭 사이클로 동일한 작업을 할 수 있다.
  • 때로는 여러개의 출력핀의 값을 정확히 동시에 바꿔줘야 할 필요가 있다. digitalWrite(10, HIGH); 다음에 digitalWrite(11, HIGH)를 호출하면 먼저 핀 10이 HIGH로 바뀌고 몇 마이크로초 후에 핀 11이 HIGH로 바뀌게 된다. 때로는 외부의 시간에 민감한 디지털 회로의 동작에 혼란을 줄 수 있다. 이 경우 PORTB |= B1100; 을 사용하면 동시에 두 핀을 HIGH로 바꿔줄 수 있다.
  • 프로그램 메모리가 부족한 경우 이 방식을 사용하면 코드 크기를 작게 줄일 수 있다. 루프를 사용해 각 핀을 독립적으로 조작하는것에 비해 포트 레지스터를 통해 동시에 여러 하드웨어 핀에 값을 쓰는게 훨씬 작은 명령어를 사용하게 된다. 때로는 이 방식을 사용여부가 프로그램이 플래쉬 메모리에 들어갈 수 있는가 못들어가는가를 결정하는 차이가 될 수도 있다.



2009년 4월 24일 금요일

Arduino에 카드리더기 연결 (Use magnetic card reader with Arduino)

Arduino에 Magtek의 magnetic strip reader를 연결하여 보았다.


현재 가지고 있는 리더기는 TTL 인터페이스를 가지고 있는 single track reader이다. 5핀 커넥터를 가지고 있고 Vcc, GND, Card present, Clock(Strobe), Data 신호를 제공해 준다.


신호 타이밍은 아래와 같다.


Arduino의 D2, D3, D5를 각각 리더기의 Data, Clock, Card present에 연결해 주면 된다.

코드는 다음과 같다.


View source code

카드를 리더기에 긁어주면 아래와 같이 카드의 데이터가 시리얼포트로 출력된다.

문제점은 위의 코드로는 디코딩 루틴이 카드를 정방향인 경우에만 동작하고 반대 방향으로 긁어주는 경우에는 데이터를 정상적으로 디코딩 해 주지 못한다. 역방향인 경우도 정상적으로 디코딩이 가능하도록 코드를 수정 할 예정이다.

2009년 4월 23일 목요일

PD2437을 Arduino에서 사용하기 (Connect PD2437 (5x7 character 4-digit display) to Arduino)

동네의 부품샵을 구경하다 우연히 구하게 된 부품이다. 저렴한 가격($1.99)때문에 메뉴얼 여부에 관계 없이 일단 구입하여 버렸다. 물론 '구글신'을 믿고 있었기 때문이지만...


부품 명칭은 PD2437로 OSRAM에서 나온 4-character 5x7 dot matrix alphanumeric programmable display with built-in CMOS control functions 이다. DIL 패키지 안에 5x7 매트릭스가 4개 들어있고 디스플레이 컨트롤러를 내장하고 있다.

이 부품을 사용하기 위해 구글의 도움으로 유저메뉴얼과 어플리케이션 노트를 찾아내었다.


일반적인 메모리같이 8-bit bidirectional data bus를 사용해서 마이크로컨트롤러와 데이터를 교환하고 ASCII 코드를 입력받아 그에 해당하는 문자를 표시하게 되어 있었다.

Arduino에 연결하려고 하는데 8-bit data bus를 모두 digital i/o에 연결해 버리면 arduino에 다른 주변기기를 붙일 수 없을거 같아 74LS164(8-Bit Parallel-Out Serial-In Shift Registers)를 같이 사용하기로 하였다.

이를 토대로 구성한 회로는 다음과 같다.


Arduino의 D2-D9까지를 사용하였다.

실제 기판에 만들기 전에 먼저 브레드보드에서 프로토타입으로 확인을 해 보았다.


큰 문제 없이 원하는 글자를 표시해 주었다. 테스트에 사용한 코드는 다음과 같다.

View source code


PD2437은 매우 쉽게 여러개를 cascading이 가능하기 때문에 현재 총 10개의 PD2437을 연결하여 20x2 LED display를 만들어 볼까 생각중이다. LCD에 비해 직접 발광을 하기 때문에 시야각 문제도 없고 시중에서 구할 수 있는 20x2 LCD보다 크기도 크기 때문에 야간에도 글자를 정확하게 확인할 수 있기 때문에 signboard로 적합할 거 같다.

2009년 4월 18일 토요일

Arduino 설치 및 프로그램 실행 (Installing and setup Arduino)

http://arduino.cc 에서 arduino 소프트웨어를 다운받을 수 있다. Mac OS X, Linux, Windows를 모두 다 지원한다.

또한 OS용 디바이스 드라이버도 이 사이트에서 다운받을 수 있다.

다운받은 압축파일을 풀어주면 프로그램을 가지고 있는 폴더가 생긴다. 별도 설치 할 필요가 없이 그 폴더에서 arduino 프로그램을 바로 실행해주면 된다.

프로그램을 실행하면 다음과 같은 창이 열리게 된다..

먼저 arduino 보드에 맞게 환경설정을 해 주어야 한다. Tools 메뉴로 가 보면 아래와 같은 서브메뉴가 나온다.

먼저 통신에 사용할 시리얼 포트를 지정해 준다. Arduino보드를 USB 케이블에 연결하고 디바이스 드라이버가 제대로 설치되어 있으면 아래와 같이 포트가 보이게 된다. 아래 화면은 맥의 경우이고 윈도우 인 경우 COMx 란 이름으로 보이게 된다. 보드를 연결했는데도 포트가 보이지 않는다면 디바이스 드라이버를 다시 설치하고 프로그램을 실행하면 보일 것이다.

그 다음은 보드를 설정해 준다. Arduino도 여러 종류가 있어서 그에 해당하는 보드를 선택해주면 된다.


여기서는 아래의 보드를 사용할 것이기 때문에 Arduino Diecimila를 선택해주면 된다.


설정이 끝났으면 예제 프로그램을 실행시켜 보겠다. 아래 화면에서처럼 File -> Sketchbook -> Example -> Digital -> Blink 를 선택해 준다.

그러면 Blink 예제 파일이 열리고 내용을 볼 수 있게 된다. 여기서 맨 왼쪽의 플레이버튼을 누르면 프로그램이 컴파일 된다.

컴파일이 정상적으로 끝나면 화면 아래쪽에 다음과 같은 메세지가 나온다.

하지만 컴파일이 끝났어도 아직 프로그램이 arduino 보드로 옮겨진건 아니다. 프로그램을 arduino 보드로 전송하려면 오른쪽 두번째 버튼을 눌러준다.

그러면 arduino 보드의 TX, RX LED가 빠르게 번쩍이면서 프로그램이 전송되는걸 볼 수 있다. 전송이 끝나면 컴파일의 경우와 마찬가지로 메시지 창에 업로드가 끝났다는 메시지가 표시된다.

프로그램이 전송되고 나면 arduino 보드는 자동으로 reset이 되면서 프로그램이 바로 실행된다. 이 예제 프로그램은 보드에 있는 LED를 깜빡이게 하는 것이기 때문에 아래의 LED가 1초 간격으로 반짝이는걸 확인할 수 있을 것이다.

또한 arduino에는 시리얼 터미널 기능도 가지고 있다. 위의 예제에서는 시리얼 포트를 사용하지 않았지만 프로그램에 따라서는 시리얼 포트를 통해 데이터를 주고받을 수 있다. 맨 오른쪽의 아이콘을 눌러주면 아래쪽 메시지 윈도우가 시리얼 터미널 역활을 하게 된다.

검은 부분에 수신한 데이터가 표시되고 송신할 데이터는 입력창에 넣어주면 된다. 또한 통신속도도 임의로 변경할 수 있다. 물론 arduino보드의 시리얼 포트 설정속도와 동일하게 맞춰줘야만 한다.