<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>NTREXGO - 디바이스마트, 엔티렉스 컨텐츠 통합 사이트 &#187; 16호</title>
	<atom:link href="http://www.ntrexgo.com/archives/tag/16%ed%98%b8/feed" rel="self" type="application/rss+xml" />
	<link>http://www.ntrexgo.com</link>
	<description>엔티렉스, 디바이스마트 컨텐츠 통합 사이트</description>
	<lastBuildDate>Thu, 03 Mar 2022 06:47:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>[16호]인크리메탈 타입의 로터리엔코더 (EN40-AB-256) 출시!</title>
		<link>http://www.ntrexgo.com/archives/1048</link>
		<comments>http://www.ntrexgo.com/archives/1048#comments</comments>
		<pubDate>Thu, 10 Jan 2013 11:11:04 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[프로덕트 뉴스]]></category>
		<category><![CDATA[16호]]></category>
		<category><![CDATA[매거진]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=1048</guid>
		<description><![CDATA[디바이스마트 매거진 16호 &#124; ㈜케이디메카텍에서 기존의 로터리엔코더(EN40-AB-128)에서 분해능을 2배 높인 인크리메탈 타입의 로터리엔코더(EN40-AB-256)을 출시했다.]]></description>
				<content:encoded><![CDATA[<p style="text-align: center"><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/product163.jpg" rel="lightbox[1048]"><img class="aligncenter" alt="로터리엔코더" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/product163-300x225.jpg" width="300" height="225" /></a></p>
<p>㈜케이디메카텍에서 기존의 로터리엔코더(EN40-AB-128)에서 분해능을 2배 높인 인크리메탈 타입의 로터리엔코더(EN40-AB-256)을 출시했다.</p>
<p>90도의 위상차를 갖는 두 개의 펄스(A,B)가 출력되며 이를 이용하여 회전 방향을 검출할 수 있으며, 주로 일정한 시간동안 누적된 펄스를 계산하여 회전속도를 검출하거나 상대각도를 측정하는 용도로 활용된다. 견고한 알루미늄 프레임에 듀얼 베어링을 적용하였으며, 정전기 방전 대책과 역전압 방지회로가 적용되었다.</p>
<p><strong><span style="color: #008000">■ 로터리엔코더(EN40-AB-256)의 주요기능 ■</span></strong></p>
<ul>
<li>증분형(Incremental) 로터리 엔코더</li>
<li>한 회전당 256개의 펄스 발생</li>
<li>두 개의 펄스(A,B)출력</li>
<li>A상과 B상은 90도의 위상차가 발생하여 회전 방향을 검출</li>
<li>5V CMOS 출력</li>
</ul>
<div class="symple-toggle"><h3 class="symple-toggle-trigger">제품 설명 더보기</h3><div class="symple-toggle-container">
<p><a name="detail"></a><a name="detail"></a></p>
<table style="width: 600px" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<table style="width: 600px" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td align="center">
<table style="width: 600px" border="0" cellspacing="0" cellpadding="0" align="center">
<tbody>
<tr>
<td width="600">
<table style="width: 600px" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="600"><span style="color: #0000ff"><strong>FEATURES</strong></span></td>
</tr>
<tr>
<td colspan="2" width="600" height="10"></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td width="600">
<ul>
<li>ELECTRICAL CHARACTERISTICS</li>
</ul>
<table style="width: 600px" border="1" cellspacing="0" cellpadding="2" align="center">
<tbody>
<tr>
<td align="middle" bgcolor="#f7f7f7"><b>입력전압</b></td>
<td>DC5V±5%</td>
</tr>
<tr>
<td align="middle" bgcolor="#f7f7f7"><b>분해능</b></td>
<td>256 P/R</td>
</tr>
<tr>
<td align="middle" bgcolor="#f7f7f7"><b>출력상</b></td>
<td>A, B</td>
</tr>
<tr>
<td align="middle" bgcolor="#f7f7f7"><b>위상차</b></td>
<td>90°±45°</td>
</tr>
<tr>
<td align="middle" bgcolor="#f7f7f7"><b>입력전류</b></td>
<td>15mA</td>
</tr>
</tbody>
</table>
<ul>
<li>ELECTRICAL WIRING</li>
</ul>
<table style="width: 600px" border="1" cellspacing="0" cellpadding="2" align="center">
<tbody>
<tr>
<td rowspan="2" align="middle" bgcolor="#f7f7f7">전원</td>
<td align="middle">Red</td>
<td align="middle">5V(+)</td>
</tr>
<tr>
<td align="middle">Green</td>
<td align="middle">0V(-)</td>
</tr>
<tr>
<td rowspan="2" align="middle" bgcolor="#f7f7f7">출력</td>
<td align="middle">White</td>
<td align="middle">OUT A</td>
</tr>
<tr>
<td align="middle">Yellow</td>
<td align="middle">OUT B</td>
</tr>
</tbody>
</table>
<ul>
<li>MECHANICAL CHARACTERISTICS</li>
</ul>
<table style="width: 600px" border="1" cellspacing="0" cellpadding="2" align="center">
<tbody>
<tr>
<td bgcolor="#f7f7f7">축관성모멘트</td>
<td>1.1g·cm2</td>
</tr>
<tr>
<td bgcolor="#f7f7f7">축허용하중</td>
<td>1kgf</td>
</tr>
<tr>
<td bgcolor="#f7f7f7">최대허용회전수</td>
<td>5000rpm</td>
</tr>
<tr>
<td bgcolor="#f7f7f7">중량</td>
<td>120g</td>
</tr>
</tbody>
</table>
<p>&nbsp;</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div></div>
<p><a href="http://www.devicemart.co.kr/goods/view.php?seq=38042" target="_blank">제품 구입하러 가기</a></p>
<p>TEL. 043-213-1531</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/1048/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[16호]파워서플라이 RDP-303AU, RDP-305AU 출시!</title>
		<link>http://www.ntrexgo.com/archives/1051</link>
		<comments>http://www.ntrexgo.com/archives/1051#comments</comments>
		<pubDate>Thu, 10 Jan 2013 11:04:07 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[프로덕트 뉴스]]></category>
		<category><![CDATA[16호]]></category>
		<category><![CDATA[매거진]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=1051</guid>
		<description><![CDATA[디바이스마트 매거진 16호 &#124; ㈜지이에스티에서 직류전원공급기 2종을 출시했다.]]></description>
				<content:encoded><![CDATA[<p style="text-align: center"><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/product167.jpg" rel="lightbox[1051]"><img class="aligncenter" alt="RDP-303AU" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/product167-300x219.jpg" width="300" height="219" /></a></p>
<p>㈜지이에스티에서 직류전원공급기 2종을 출시했다.<br />
기존 아날로그 방식의 표기에 따른 계측 오차가 발생함에 따라 이를 개선하고자 마이크로프로세서를 사용하여 실제 사용하는 전압, 전류를 실시간으로 계측하여 디스플레이에 표기함으로써 정확한 측정 값을 빠르게 표시할 수 있다. 뿐만 아니라 충분히 검증된 안정회로를 사용함으로서 부하의 종류에 상관없이 안정적인 출력 전원 공급이 가능하다.</p>
<p><span style="color: #3366ff"><strong>■ RDP-303AU, RDP-305AU 특징 ■</strong></span></p>
<ul>
<li>심플한 디자인 및 사이즈</li>
<li>디지털 디스플레이</li>
<li>안정적인 전압 전류 조절</li>
<li>가변 전압 : 0~30V 2CH, 고정 5V, 3개 채널 제공</li>
<li>가변 전압 : 0~3A 2CH or 0~5A 2CH, 고정 2A, 3개 채널 제공</li>
<li>직렬 or 병렬 연결시 트래킹 동작</li>
<li>작은 리플 및 노이즈</li>
<li>사이즈 : 215 x 300 x140 (mm)</li>
</ul>
<div class="symple-toggle"><h3 class="symple-toggle-trigger">파워서플라이 RDP-303AU 상세 설명 더보기</h3><div class="symple-toggle-container">
<p><a name="detail"></a><a name="detail"></a></p>
<table style="width: 100%" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<table style="width: 100%" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td align="left"><img alt="" src="http://www.devicemart.co.kr/skin/goods/detail/37909_1.jpg" width="544" height="2475" /></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div></div>
<div class="symple-toggle"><h3 class="symple-toggle-trigger">파워서플라이 RDP-305AU 상세 설명 더보기</h3><div class="symple-toggle-container">
<p><a name="detail"></a><a name="detail"></a></p>
<table style="width: 100%" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<table style="width: 100%" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td align="left"><img alt="" src="http://www.devicemart.co.kr/skin/goods/detail/37910_1.jpg" width="544" height="2510" /></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div></div>
<p>&nbsp;</p>
<p><a href="http://www.devicemart.co.kr/goods/view.php?seq=37909" target="_blank">파워서플라이 RDP-303AU 제품 구입하러 가기</a></p>
<p><a title="제품 구입하러 가기" href="http://www.devicemart.co.kr/goods/view.php?seq=37910" target="_blank">파워서플라이 RDP-305AU </a><a href="http://www.devicemart.co.kr/goods/view.php?seq=37909" target="_blank">제품 구입하러 가기</a></p>
<p>TEL. 032-765-7795</p>
<p>FAX. 032-765-7794<br />
www.gestek.co.kr</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/1051/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[16호]이더넷 관련 모듈 ECM5200-WIO, ECM5200-UART 출시</title>
		<link>http://www.ntrexgo.com/archives/1055</link>
		<comments>http://www.ntrexgo.com/archives/1055#comments</comments>
		<pubDate>Thu, 10 Jan 2013 10:52:17 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[프로덕트 뉴스]]></category>
		<category><![CDATA[16호]]></category>
		<category><![CDATA[NEWS]]></category>
		<category><![CDATA[product]]></category>
		<category><![CDATA[매거진]]></category>
		<category><![CDATA[모듈]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=1055</guid>
		<description><![CDATA[디바이스마트 매거진 16호 &#124; EM Tech에서 ECM5200-WIO와 UART 두 모델이 새롭게 출시됐다.]]></description>
				<content:encoded><![CDATA[<p>&nbsp;</p>
<p style="text-align: center"><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/product165.jpg" rel="lightbox[1055]"><img class="size-medium wp-image-1094 aligncenter" alt="이더넷" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/product165-300x225.jpg" width="300" height="225" /></a></p>
<p>EM Tech에서 ECM5200-WIO와 UART 두 모델이 새롭게 출시됐다.<br />
ECM5200-WIO제품은 이더넷으로 WEB 서버 모드를 구축하거나 TCP/UDP통신을 통해서 원격으로 아날로그 입/출력이나 디지털 입/출력이 가능한 모듈이다.</p>
<p>WEB 서버로 동작 시 로그인/아웃 기능을 모듈에서 지원하여 손쉽게 사용할 수 있다. 또한 다양한 장비 및 환경 지원을 위한 펌웨어 업그레이드가 가능하고, Configuration Tool Program(ecmConfig), 보안을 위한 User ID/Password, 시리얼과 TCP/IP 가상드라이버 VSP(Virtual Serial Port) 프로그램 등이 제공된다.</p>
<p>ECM5200-UART는 UART 프로토콜을 TCP/IP 프로토콜로 변환시키는 이더넷 &lt;-&gt; 시리얼 변환 모듈로, UART 시리얼 인터페이스가 장착된 장비를 이더넷을 통해 TCP/IP 망에 연결하여 원격 측정, 관리 및 제어가 가능하게 하는 제품이다.</p>
<p>WIO와 같이 펌웨어 업그레이드, ecmConfig, User ID/Password, VSP 프로그램 등이 포함되어 있으며, 사용자 편의를 위해 테스트 보드가 같이 출시되었다.</p>
<div class="symple-toggle"><h3 class="symple-toggle-trigger"> ECM5200-WIO제품 설명 더보기</h3><div class="symple-toggle-container">
<p><strong>제품설명</strong></p>
<p>ECM5200-WIO제품은 이더넷으로 WEB 서버모드나 TCP/UDP통신을 통해서 원격으로 아날로그 입/출력이나 디지털 입/출력이 가능한 모듈이며, WEB서버로 동작 시 로그인/아웃 기능을 모듈에서 지원하여 손쉽게 로그인/아웃 기능을 사용할 수 있다.</p>
<p><img alt="" src="http://www.devicemart.co.kr/mart7/upload/fd_html_img/EMTech/38095s_img1.jpg" /></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table style="width: 550px" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="550"><strong>주요규격 및 기능</strong></td>
</tr>
<tr>
<td colspan="2" width="550" height="10"></td>
</tr>
</tbody>
</table>
<table style="width: 550px" border="1" cellspacing="0" cellpadding="5">
<tbody>
<tr>
<td align="middle" width="94">
<h3>I/O</h3>
</td>
<td width="506">1. UART: 1 채널<br />
2. Digital 출력: 4 채널<br />
3. Digital 입력: 4 채널<br />
4. PWM 출력: 2 채널 (256 step) =&gt; <span style="color: #ff0000">조명 밝기/모터 속도 제어</span>용도로 사용 가능<br />
5. Analog 입력(10bit ADC): 2채널 + 전원 전압(1 채널) + MCU 온도(1 채널)<br />
6. 사용자 WEB 페이지: 16KB<br />
7. 송수신 상태 LED 제어 출력: 2 EA</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<ul>
<li>사용자 WEB 페이지 다운로드</li>
<li>WEB 서버 모드에서 로그인/로그아웃 기능 지원</li>
<li>일반적인 TCP/UDP통신용을 위한 간단한 통신 프로토콜 내장</li>
<li>다양한 장비 및 환경 지원을 위한 펌웨어 업그레이드 기능</li>
<li>W5200 하드웨어 칩에 의한 안정성 및 신뢰성 확보</li>
<li>손쉬운 설정을 위한 Configuration Tool Program(ecmConfig) 제공</li>
<li>보안을 위한 User ID/Password 기능</li>
<li>10/100 Base-T Ethernet 인터페이스</li>
<li>자동 MDI/MDIX (다이렉트/크로스 케이블 인식)</li>
<li>UART: 3.3V-TTL 레벨, 1200 ~ 115.2K bps, parity bit 지원</li>
<li>Static(고정 IP), DHCP(유동 IP) 설정 지원</li>
<li>호스트 네임을 통한 간편한 접속(DNS) 기능 지원</li>
<li>Keep Alive 지원</li>
<li>동작 상태 LED 3EA 장착, 송/수신 상태 LED 제어 신호: 2EA =&gt; 동작 확인이 쉽다.</li>
<li>시리얼&lt;-&gt; TCP/IP 가상 드라이버 VSP(Virtual Serial Port) 프로그램 제공</li>
</ul>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table style="width: 550px" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="550"><strong>설정 프로그램(ecmConfig) 제공</strong></td>
</tr>
<tr>
<td colspan="2" width="550" height="10"></td>
</tr>
</tbody>
</table>
<p>ecmConfig 프로그램은 펌웨어 업그레이드나 네트워크 설정을 손쉽게 할 수 있도록 지원해 주는 프로그램이다.</p>
<div><a href="//www.devicemart.co.kr/mart7/upload/fd_html_img/EMTech/38095s"><img alt="" src="http://www.devicemart.co.kr/mart7/upload/fd_html_img/EMTech/38089s_img4.jpg" width="600" /></a></div>
<p>&nbsp;</p>
<table style="width: 550px" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="550">예) 스마트폰 이용 웹 서버 접속</td>
</tr>
<tr>
<td colspan="2" width="550" height="10"></td>
</tr>
</tbody>
</table>
<p>아래의 사진은 공유기의 DDNS 기능을 사용하여 ECM5200-WIO를 웹서버로 동작시켜 스마트폰으로 접속한 화면이다.<br />
<img alt="" src="http://www.devicemart.co.kr/mart7/upload/fd_html_img/EMTech/38095s_img3.jpg" width="600" height="435" /></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table style="width: 550px" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="550"><strong>VSP (Virtual Serial Port) 제공</strong></td>
</tr>
<tr>
<td colspan="2" width="550" height="10"></td>
</tr>
</tbody>
</table>
<p>시리얼 통신 프로그램을 VSP을 통해서 TCP/IP 통신을 할 수 있도록 변환 기능을 해주는 프로그램으로 VSP를 사용하면 시리얼 통신으로 되어 있는 프로그램을 수정없이 그대로 사용이 가능하다.<img alt="" src="http://www.devicemart.co.kr/mart7/upload/fd_html_img/EMTech/38089s_img5.jpg" /></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
</div></div>
<p>&nbsp;</p>
<p><a href="http://www.devicemart.co.kr/goods/view.php?seq=38095" target="_blank">제품 구입하러 가기</a></p>
<p>TEL. 042-623-4470<br />
www.wgmsk.com</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/1055/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[16호]JK전자와 함께하는 ARM 완전정복 2부</title>
		<link>http://www.ntrexgo.com/archives/2515</link>
		<comments>http://www.ntrexgo.com/archives/2515#comments</comments>
		<pubDate>Thu, 10 Jan 2013 07:36:52 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[16호]]></category>
		<category><![CDATA[arm]]></category>
		<category><![CDATA[jk전자]]></category>
		<category><![CDATA[매거진]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=2515</guid>
		<description><![CDATA[디바이스마트 매거진 16호 &#124; 자료는 ARM을 처음 접하는 입문자로서 S/W 엔지니어 혹은 H/W 엔지니어를 대상으로 하였습니다. 처음에는 Cortex-M3 구조를 목표로 하였으나 전통적인 ARM(주로 ARM7, ARM9)의 구조에 대해서 먼저 이야기한 다음 Cortex-M3 구조에 대해서 하기로 마음을 고쳐 먹었습니다. Cortex-M3도 ARM 이기 때문에 전통적인 ARM의 구조에 대해서 잘 이해하고 Cortex-M3 구조와 비교해 보면서 공부한다면 큰 도움이 될 것입니다. ]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/archives/2867" target="_blank">1부 계속</a></p>
<p>&nbsp;</p>
<p><span style="color: #800000"><strong>7. ARM Instruction Sets</strong></span><a id="1342322528" name="7"></a></p>
<p><span style="color: #ff0000"><strong>7.1 Understanding ARM Instruction set</strong></span><a id="13423225282" name="7.1"></a></p>
<p>ARM Instruction Set은 ARM 명령어들 즉 어셈블리어를 이야기하는 것입니다. 대부분은 C 코드를 이용해서 작업을 합니다만, 어셈블리어도 어느 정도는 숙지하고 있어야 하는 몇가지 이유가 있습니다.</p>
<p>(1) ARM 어셈블리어를 잘 파악하고 있으면 ARM의 구조를 더 잘 이해할 수 있습니다.</p>
<p>(2) 전통적인 ARM의 Startup 코드는 스택이 초기화 되기 전에는 C로 작성을 할 수가 없습니다. 최근 Cortex 계열은 Reset 벡터의 초기 번지가 Stackaddress여서 C코드만으로도 부트로더 작성이 가능합니다.</p>
<p>(3) C컴파일러의 최적화가 아주 잘 되어 있지만, 사람이 주의해서 작성하는 어셈블리 코드보다는 최적화할 수 없습니다.</p>
<p>(4) Debugging in detail (instruction level debugging)</p>
<p>일반적인 ARM 어셈블리어 형식입니다.</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14023.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2623" alt="16FJK14023" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14023-300x134.jpg" width="300" height="134" /></a></td>
</tr>
</tbody>
</table>
<p>· Directive : 어셈블리 코드의 특성을 지정하는 지시어입니다.<br />
· Label : 반드시 Space 없이 첫번째 컬럼에 위치해야 하고, Label 자체가 Address가 됩니다.<br />
· Comment : 주석은 &#8220;;&#8221; 문자 이후로 작성을 하면 됩니다.<br />
· Instructions(ADD, MOV, LDR &#8230;) : 명령어들은 반드시 앞 부분에 적어도 하나 이상의 Space가 있어야 합니다.</p>
<p><span style="color: #ff0000"><strong>7.2 ARM Instruction sets</strong></span><a id="134232252822" name="7.2"></a></p>
<p>ARM Processor는 2가지 명령어 세트를 지원하는데 32bit ARM 명령어와 16bit Thumb 명령어가 있습니다. Thumb 명령어는 모든 ARM 프로세서에서 지원하는 것은 아니고 Thumb 특성을 지원하는 Core에서만 사용이 가능합니다. 최근 Cortex 계열에서는 16bit, 32bit 명령어를 같이 사용할 수 있는 Thumb-2 Instruction도 지원합니다. 심지어 Cortex-M3의 경우에는 Thumb-2 Instruction만 사용이 가능 합니다. 8bit 길이의 Jave Byte Code도 사용할 수 있는데 이것도 Thumb 명령어와 같이 모든 ARM Processor가 지원하는 것은 아닙니다.</p>
<table style="width: 550px" border="1" cellspacing="0" cellpadding="8">
<tbody>
<tr>
<td align="center" bgcolor="#FF6600" height="39">Instruction Type</td>
<td align="center" bgcolor="#FF6600" height="39">Instructions</td>
</tr>
<tr>
<td bgcolor="#FFFFFF" width="192">Data Processing</td>
<td align="left" bgcolor="#FFFFFF" width="654">ADD, ADC, SUB, SBC, RSB, AND, ORR, BIC, MOV, CMP, TEQ, …</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">Multiply</td>
<td align="left" bgcolor="#FFFFFF">MUL, MULS, MLA, SMULL, UMLAL, …</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">Load/Store</td>
<td align="left" bgcolor="#FFFFFF">LDR, LDRB, LDRH, LDRSH, LDM, STR, STRB, STRH, STRSH, STM, …</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">Branch</td>
<td align="left" bgcolor="#FFFFFF">B, BL, BX, BLX, …</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">Status Access</td>
<td align="left" bgcolor="#FFFFFF">MRS, MSR</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">Swap</td>
<td align="left" bgcolor="#FFFFFF">SWP, SWPB</td>
</tr>
<tr>
<td bgcolor="#FFFFFF">Coprocessor</td>
<td align="left" bgcolor="#FFFFFF">MRC, MCR, LDC, STC</td>
</tr>
</tbody>
</table>
<p><span style="color: #ff0000"><strong>7.3 Data Processing Instructions</strong></span> <a id="134232252823" name="7.3"></a></p>
<p><span style="color: #ff6600">(1) Instructions</span></p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1488.jpg" rel="lightbox[2515]"><img class="alignnone size-large wp-image-2688" alt="16FJK1488" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1488-620x69.jpg" width="620" height="69" /></a></td>
</tr>
</tbody>
</table>
<p><span style="text-decoration: underline">&lt; Cond &gt;</span><br />
해당 명령의 조건 실행 플래그입니다. 해당 플래그를 통해 명령을 CPSR의 플래그 상태에 따라 선택적으로 실행을 할 수 있습니다. ARM에서 지원하는 굉장히 강력한 기능으로 조건부 실행을 잘 이용하면 분기문을 최대한 줄여 시스템 성능을 향상 시킬 수 있습니다.</p>
<p><span style="text-decoration: underline">&lt; I &gt;</span><br />
Operand 2로 지정되어 있는 부분이 Immediate Operand 인지 아닌지 여부를 나타내는 비트입니다. 즉 25번필드[I] 가 &#8220;0&#8243; 이면 [11 : 0] 가 shifter operand로 동작을 하고 &#8220;1&#8243; 이면 Immediate Operand로 동작합니다. Immediate Operand라 함은, 예를 들어 MOV R0, #0&#215;01234 라고 했을 경우 #0&#215;1234를 가리키는 말입니다.</p>
<p><span style="text-decoration: underline">&lt; Opcode &gt;</span><br />
데이터 프로세싱 명령중 어떤 명령인지를 나타내는 필드입니다. 해당 필드와 명령어는 아래와 같습니다.</p>
<table style="width: 550px" border="1" cellspacing="0" cellpadding="8">
<tbody>
<tr>
<td align="center" bgcolor="#FF6600" height="20">Opcode</td>
<td align="center" bgcolor="#FF6600" height="20">Mnemonic</td>
<td align="center" bgcolor="#FF6600">Meaning</td>
<td align="center" bgcolor="#FF6600">Action</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF" width="69">0000</td>
<td align="center" bgcolor="#FFFFFF" width="107">AND</td>
<td align="left" bgcolor="#FFFFFF" width="190">Logical AND</td>
<td align="left" bgcolor="#FFFFFF" width="444">Rd = Rn AND shifter_operand</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">0001</td>
<td align="center" bgcolor="#FFFFFF">EOR</td>
<td align="left" bgcolor="#FFFFFF">Logical Exclusive OR</td>
<td align="left" bgcolor="#FFFFFF">Rd = Rn EOR shifter_operand</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">0010</td>
<td align="center" bgcolor="#FFFFFF">SUB</td>
<td align="left" bgcolor="#FFFFFF">Subtract</td>
<td align="left" bgcolor="#FFFFFF">Rd = Rn &#8211; shifter_operand</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">0011</td>
<td align="center" bgcolor="#FFFFFF">RSB</td>
<td align="left" bgcolor="#FFFFFF">Reverse subtract</td>
<td align="left" bgcolor="#FFFFFF">Rd = shifter_operand &#8211; Rn</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">0100</td>
<td align="center" bgcolor="#FFFFFF">ADD</td>
<td align="left" bgcolor="#FFFFFF">Add</td>
<td align="left" bgcolor="#FFFFFF">Rd = Rn + shifter_operand</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">0101</td>
<td align="center" bgcolor="#FFFFFF">ADC</td>
<td align="left" bgcolor="#FFFFFF">Add with carry</td>
<td align="left" bgcolor="#FFFFFF">Rd = Rn + shifter_operand + Carry</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">0110</td>
<td align="center" bgcolor="#FFFFFF">SBC</td>
<td align="left" bgcolor="#FFFFFF">Subract with carry</td>
<td align="left" bgcolor="#FFFFFF">Rd = Rn – shifter_operand – NOT(Carry)</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">0111</td>
<td align="center" bgcolor="#FFFFFF">RSC</td>
<td align="left" bgcolor="#FFFFFF">Reverse Subract with carry</td>
<td align="left" bgcolor="#FFFFFF">Rd = shifter_operand &#8211; Rn – NOT(Carry)</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">1000</td>
<td align="center" bgcolor="#FFFFFF">TST</td>
<td align="left" bgcolor="#FFFFFF">Test</td>
<td align="left" bgcolor="#FFFFFF">Update flags after Rn AND shifer_opernad</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">1001</td>
<td align="center" bgcolor="#FFFFFF">TEQ</td>
<td align="left" bgcolor="#FFFFFF">Test Equivalence</td>
<td align="left" bgcolor="#FFFFFF">Update flags after Rn EOR shifer_opernad</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">1010</td>
<td align="center" bgcolor="#FFFFFF">CMP</td>
<td align="left" bgcolor="#FFFFFF">Compare</td>
<td align="left" bgcolor="#FFFFFF">Update flags after Rn &#8211; shifer_opernad</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">1011</td>
<td align="center" bgcolor="#FFFFFF">CMN</td>
<td align="left" bgcolor="#FFFFFF">Commom</td>
<td align="left" bgcolor="#FFFFFF">Update flags after Rn + shifer_opernad</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">1100</td>
<td align="center" bgcolor="#FFFFFF">ORR</td>
<td align="left" bgcolor="#FFFFFF">Logical OR</td>
<td align="left" bgcolor="#FFFFFF">Rd = Rn OR shifter_operand</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">1101</td>
<td align="center" bgcolor="#FFFFFF">MOV</td>
<td align="left" bgcolor="#FFFFFF">Move</td>
<td align="left" bgcolor="#FFFFFF">Rd = shifter_operand</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">1110</td>
<td align="center" bgcolor="#FFFFFF">BIC</td>
<td align="left" bgcolor="#FFFFFF">Bit clear</td>
<td align="left" bgcolor="#FFFFFF">Rd = Rn AND NOT(shifter_operand)</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">1111</td>
<td align="center" bgcolor="#FFFFFF">MVN</td>
<td align="left" bgcolor="#FFFFFF">Move Not</td>
<td align="left" bgcolor="#FFFFFF">Rd = NOT(shifter_operand)</td>
</tr>
</tbody>
</table>
<p><span style="text-decoration: underline">&lt; S &gt;</span><br />
S 비트가 1인 경우는 데이터 프로세싱 명령의 결과가 CPSR에 영향(Rd의 레지스터가 PC인 경우 SPSR의 값으로 CPSR을 복원)을 미칩니다. 즉, 0인 경우에는 CPSR은 변하지 않습니다.</p>
<p><span style="text-decoration: underline">&lt; Rn &gt;</span><br />
ARM 데이터 프로세싱 명령은 그 결과와 첫 번째 오퍼랜드는 항상 레지스터로 지정해야 합니다. Rn은 첫 번째 오퍼랜드를 가리키는 것으로 위에서 Op1으로 표기한 것에 해당합니다. ARM에서 한번에 볼 수 있는 범용 레지스터는 sp, lr, pc 등을 포함해서 r0~r15 까지입니다. 즉, 4bit를 통해 레지스터를 나타내게 됩니다. 해당 필드는 명령에 따라 사용되지 않기도 합니다. MOV나 MVN등이 이에 해당합니다.</p>
<p><span style="text-decoration: underline">&lt; Rd &gt;</span><br />
오퍼레이션의 결과가 저장될 레지스터를 의미합니다. 역시 레지스터를 가리키므로 4bit를 사용하고 모든 명령에서 디폴트로 사용되는 필드. ARM의 데이터 프로세싱 명령의 결과는 항상 레지스터로 들어갑니다.</p>
<p><span style="text-decoration: underline">&lt; Operand 2 &gt;</span><br />
Immediate Operand 혹은 레지스터 Operand 입니다. &lt;I&gt; 필드가 0일 경우 레지스터입니다.</p>
<p><span style="color: #ff6600">(2) Syntax : &lt;operation&gt;{cond}{s} Rd, Rn, operand2</span></p>
<p>·Operand2 is a register<br />
ADD R0, R1, R2</p>
<p>·Operand2 is immediate value<br />
BIC R1, R2, #0xFF</p>
<p>· Operand2 shifted value<br />
ADD R0, R1, R2, LSL #2<br />
SUB R0, R1, R2, LSR R3</p>
<p>·Data movement<br />
MOV R0, R1<br />
MOV R0, #0&#215;1</p>
<p>·Comparisons set flags only<br />
CMP R0, R1<br />
CMP R2, #0&#215;01</p>
<p><span style="color: #ff6600">(3) Immediate value</span></p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14007.jpg" rel="lightbox[2515]"><img class="alignnone size-large wp-image-2690" alt="16FJK14007" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14007-620x64.jpg" width="620" height="64" /></a></td>
</tr>
</tbody>
</table>
<p>Immediate value(상수 값)= ROR immed_8 by 2*rot</p>
<p>MOV R0, #0xFF000000<br />
MOV R0, #0&#215;12<br />
MOV R0, #0&#215;104 ; 100000100 &#8211;&gt; permitted<br />
MOV R0, #0&#215;102 ; 100000010 &#8211;&gt; not permitted<br />
MOV R0, #0&#215;12345678 ; 10010001101000101011001111000 &#8211;&gt; not permitted</p>
<p>위의 예제에서 상수 값으로 &#8220;#0&#215;104&#8243;는 사용할 수 있는데 &#8220;#0&#215;102&#8243;, &#8220;#0&#215;12345678&#8243; 값으로 올 수 없는 이유는 무엇일까요?<br />
&#8220;ROR immed_8 by 2*rot&#8221; 의 수식을 잘 살펴 보시기 바랍니다. 어렵다구요? 네, 쉬운 계산이 아닐 수 있습니다.<br />
우선 &#8220;#0&#215;12345678&#8243; 값은 쉽게 판단이 될 것 같은데요. Rotate없이 표현 가능한 값의 범위가 8bit 를 넘었습니다.<br />
&#8220;#0&#215;102&#8243; 는 왜 안될까요? 쉽게 생각하면 8-bit immediate 값을 #rot 값을 2배 한만큼 오른쪽으로 로테이션을(ROR) 해서 Immediate value을 만들 수 있는 값을 반드시 상수로 사용해야 한다는 말입니다. 역시 말로는 잘 설명이 되지 않네요. 아래 그림들을 참조 하시기 바랍니다.</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14006.jpg" rel="lightbox[2515]"><img class="alignnone  wp-image-2689" alt="16FJK14006" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14006-620x367.jpg" width="502" height="297" /></a></td>
</tr>
</tbody>
</table>
<p>아래 Immediate value의 또 다른 예제 입니다.<br />
MOV r0, #0xfc000003 ; 11111100000000000000000000000011<br />
r0에 상수 값 0xfc000003을 넣는 명령입니다. 해당 값은 8bit 값 0xFF를 32bit로 확장하고 오른쪽으로 6번 Rotate 시킨 값입니다. 그래서 에러가 나지 않습니다.</p>
<p><span style="color: #ff6600">(4) 32-bit Instruction format</span><br />
MOV R0, #1</p>
<p>굉장히 단순한 예제인데요. 위에서 배운 32-bit Instructions 포맷을 분석해 보도록 하겠습니다. 코드를 Disassebly 해보면 &#8220;0xE3A00001(1110 001 1101 0 0000 0000 0000 00000001)&#8221; 입니다.</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1426.jpg" rel="lightbox[2515]"><img class="alignnone size-full wp-image-2626" alt="16FJK1426" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1426.jpg" width="518" height="41" /></a></td>
</tr>
</tbody>
</table>
<p>Instruction 포맷을 다시 한번 살펴보면 아래와 같습니다.</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14008.jpg" rel="lightbox[2515]"><img class="alignnone size-large wp-image-2691" alt="16FJK14008" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14008-620x59.jpg" width="620" height="59" /></a></td>
</tr>
</tbody>
</table>
[31:28] : 1110 &#8211; 7.11 Conditional Execution 에서 배울 예정입니다. 우선은 그냥 &#8220;1110&#8243; 은 Always execution flag 라고 알아 두시기 바랍니다.<br />
[27:25] : 001 &#8211; Operland 2로 지정되어 있는 부분이 Immediate Operand이므로 25번 비트가 &#8220;1&#8243; 입니다.<br />
[24:21] : 1101 &#8211; Opcode &#8220;MOV&#8221; 는 &#8220;1101&#8243; 입니다.<br />
[20] : 0 &#8211; 명령어 Opcode에 &#8220;S&#8221; 가 붙지 않았으므로 CPSR에 영향을 미치는 명령어는 아닙니다.<br />
[19:16] : 0000 &#8211; Rn 부분으로 레지스터 번호를 표현합니다. 만약 &#8220;MOV R2, #1&#8243; 였다면 Rn 이 &#8220;0000&#8243; 이 아니라 &#8220;0010&#8243; 일 것입니다.<br />
[15:12] : 0000 &#8211; Rd 부분이 없으므로 &#8220;0000&#8243; 입니다.<br />
[11:0] : 8bit Immediate value 로서 &#8220;#1&#8243; 에 해당하는 &#8220;00000001&#8243; 입니다.</p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>*참고<br />
MOV R2, #1 명령에 대한 32-bit Instruction 포맷 =<br />
0xE3A02001(1110 001 1101 0 0000 0010 0000 00000001)</p>
</div>
<p><span style="color: #ff6600">(5) Examples</span></p>
<p><strong>R0 = 0&#215;00</strong></p>
<p>R1 = 0&#215;22<br />
R2 = 0&#215;02<br />
R3 = 0&#215;00<br />
R4 = 0&#215;00</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1427.jpg" rel="lightbox[2515]"><img class="alignnone size-full wp-image-2627" alt="16FJK1427" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1427.jpg" width="388" height="150" /></a></td>
</tr>
</tbody>
</table>
<p>레지스터의 값들이 위와 같을때 아래 예제들을 차례대로 수행 했을때의 각각의 레지스터 값은?</p>
<p><strong>AND R0, R0, #0xFF ; 0&#215;00 &amp; 0xff = R0의 값은 변환 없음</strong></p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1430.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2630" alt="16FJK1430" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1430-300x81.jpg" width="300" height="81" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1427.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2627" alt="16FJK1427" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1427-300x115.jpg" width="300" height="115" /></a></td>
</tr>
</tbody>
</table>
<p><strong>ADD R0, R0, #1</strong> ; R0 = R0 + 1 = 0&#215;1</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1431.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2631" alt="16FJK1431" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1431-300x101.jpg" width="300" height="101" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1428.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2628" alt="16FJK1428" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1428-300x112.jpg" width="300" height="112" /></a>/td&gt;</td>
</tr>
</tbody>
</table>
<p><strong>ADD R0, R0, R1</strong> ; R0 = R0 + R1 = 0&#215;01 + 0&#215;22 = 0&#215;23</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1430.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2630" alt="16FJK1430" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1430-300x81.jpg" width="300" height="81" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1432.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2632" alt="16FJK1432" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1432-300x109.jpg" width="300" height="109" /></a></td>
</tr>
</tbody>
</table>
<p><strong>LSL R1, R0, #2</strong> ; 0&#215;23(100011) LSL #2 = 0x8C(10001100) -&gt; 참고로 왼쪽으로 2번 쉬프트 하면 *4 를 한것과 같습니다.</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1433.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2633" alt="16FJK1433" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1433-300x67.jpg" width="300" height="67" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1434.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2634" alt="16FJK1434" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1434-300x107.jpg" width="300" height="107" /></a></td>
</tr>
</tbody>
</table>
<p><strong>SUB R3, R2, R1, LSR R2</strong><br />
R3의 값이 0xFFFFFFDF로 복잡한 값이 나왔습니다. 왜 이런 결과가 나왔을까요?<br />
우선 R1을 오른쪽으로 2번 쉬프트 시키면 0&#215;23이 되고 R2(0&#215;02) 에서 R1(0&#215;23) 을 빼면 결과 값이 -0&#215;21가 되고 이 값을 2의 보수로 표시하면 0xFFFFFFDF 가 됩니다.</p>
<p>0&#215;21 = 00000000000000000000000000100001<br />
- 0&#215;21 = 11111111111111111111111111011111<br />
&#8211;&gt; 0&#215;21의 2의 보수</p>
<p>참고로 2의 보수를 취하는 방법은 원래의 2진수에서 0-&gt;1, 1-&gt;0 으로 바꾼 후에 1을 더하면 되겠지요.</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1435.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2635" alt="16FJK1435" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1435-300x55.jpg" width="300" height="55" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1436.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2636" alt="16FJK1436" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1436-300x109.jpg" width="300" height="109" /></a></td>
</tr>
</tbody>
</table>
<p><strong>BIC R0, R1, #0xFF00</strong></p>
<p>R1(0x8C) = 0000000010001100</p>
<p>0xFF00(65280) = 1111111100000000</p>
<p>BIC = 0000000010001100 ; 0xFF00 로 bit clear를 해도 R1의 값은 변화가 없네요.</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1437.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2637" alt="16FJK1437" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1437-300x74.jpg" width="300" height="74" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1438.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2638" alt="16FJK1438" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1438-300x110.jpg" width="300" height="110" /></a></td>
</tr>
</tbody>
</table>
<p><strong>RSB R0, R1, #0</strong> ; #0 &#8211; R1(0x8C) = 0xFFFFFF74(0x8C 의 2의 보수 값)<br />
RSB 명령어는 SUB와는 반대로 마이너스 연산을 수행합니다.</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1439.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2639" alt="16FJK1439" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1439-300x65.jpg" width="300" height="65" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1440.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2640" alt="16FJK1440" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1440-300x112.jpg" width="300" height="112" /></a></td>
</tr>
</tbody>
</table>
<p><span style="color: #ff0000"><strong>7.4 Multiply Instructions</strong></span><a id="1342322528232" name="7.4"></a></p>
<p><span style="color: #ff6600">(1)Multiply (Accumulate) Syntax</span><br />
MUL{&lt;cond&gt;}{S} Rd, Rm, Rs ; Rd = Rm * Rs<br />
MUA{&lt;cond&gt;}{S} Rd, Rm, Rs, Rn ; Rd = (Rm * Rs) + Rn</p>
<p><span style="color: #ff6600">(2) Examples</span><br />
<strong>R0 = 0&#215;01</strong><br />
<strong>R1 = 0&#215;02</strong><br />
<strong>R2 = 0&#215;03</strong><br />
<strong>R3 = 0&#215;04</strong><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1441.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2641" alt="16FJK1441" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1441-300x111.jpg" width="300" height="111" /></a></p>
<p>레지스터의 값들이 위와 같을 때 아래 예제들을 차례대로 수행했을 때의 각각의 레지스터 값은?</p>
<p><strong>MUL R2, R0, R1</strong> ; R2 = R0*R1 = 0&#215;02</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1443.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2643" alt="16FJK1443" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1443-300x109.jpg" width="300" height="109" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1442.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2642" alt="16FJK1442" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1442-300x64.jpg" width="300" height="64" /></a></td>
</tr>
</tbody>
</table>
<p><strong>MULS R2, R0, R1</strong> ; R2 = R0*R1 = 0&#215;02<br />
MUL 명령과 같은 명령입니다. 하지만 MUL뒤에 &#8220;S&#8221; 가 붙으면 명령어 처리가 끝난 이후에 CPSR의 Flag Field 가 연산 결과에 따라서 업데이트가 됩니다.<br />
자세한 사항은 7.11 Conditional Execution 에서 자세히 다루도록 하겠습니다.</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1443.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2643" alt="16FJK1443" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1443-300x109.jpg" width="300" height="109" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1444.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2644" alt="16FJK1444" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1444-300x76.jpg" width="300" height="76" /></a></td>
</tr>
</tbody>
</table>
<p><strong>MLA R3, R2, R1, R0</strong> ; R3 = R2*R1 + R0</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1446.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2646" alt="16FJK1446" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1446-300x110.jpg" width="300" height="110" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1445.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2645" alt="16FJK1445" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1445-300x82.jpg" width="300" height="82" /></a></td>
</tr>
</tbody>
</table>
<p>참 효율적이네요. 명령어 하나로 곱하기 연산과 더하기 연산을 같이 할 수 있습니다.</p>
<p><strong>SMULL R3, R2, R1, R0</strong> ; R3,R2 = R1*R0</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1447.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2647" alt="16FJK1447" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1447-300x109.jpg" width="300" height="109" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1448.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2648" alt="16FJK1448" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1448-300x93.jpg" width="300" height="93" /></a></td>
</tr>
</tbody>
</table>
<p>부호있는 64비트 곱셈 명령어 입니다. R1*R0 하여 상위 32비트는 R2에 하위 32비트는 R3에 저장합니다.<br />
위에서 부호있는 연산이 나왔는데, 좀더 복잡한 예제를 풀어 보도록 하겠습니다.</p>
<p><strong>R0 = 0xF0000002</strong><br />
<strong>R1 = 0&#215;02</strong><br />
<strong>R2 = 0&#215;00</strong><br />
<strong>R3 = 0&#215;00</strong></p>
<p>초기 레지스터의 값이 위와 같을때 SMULL 연산 이후의 R2, R3 의 값은 어떻게 될까요?<br />
우선 0xF0000002가 음수이기 때문에 연산을 하기 위해서는 2의 보수값(F0000002의 2의 보수 = 0xFFFFFFE)을 먼저 취합니다. 그리고 나서 0xFFFFFFE * 0&#215;02 = 0x1FFFFFFC 를 합니다. 연산이 끝나고 나서 음수를 표현하기 위해서 다시 0x1FFFFFFC 의 2의 보수를 취합니다. 이때 SMULL이 64비트 곱셈 명령어이므로 64비트로 확장합니다. 이렇게 하면 상위 32비트는 0xFFFFFFFF 이고 하위 32비트는 0&#215;04가 됩니다.</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1449.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2649" alt="16FJK1449" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1449-300x112.jpg" width="300" height="112" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1450.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2650" alt="16FJK1450" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1450-300x67.jpg" width="300" height="67" /></a></td>
</tr>
</tbody>
</table>
<p>위의 그림에서 &#8220;MOV R0, #-268435454&#8243; 라고 R0를 초기화하고 있습니다. 이것은 0xf0000002의 값이 음수(최상위 비트가 1이면 음수이죠)이기 때문에 컴파일러에서 알기 쉽도록 음수 10진수로 표현을 해준 것입니다.</p>
<p><span style="color: #ff0000"><strong>7.5 Load/Store Instructions</strong></span><a id="134232252824" name="7.5"></a></p>
<p>Memory의 내용을 레지스터로 이동(Load)하거나 레지스터의 내용을 메모리에 저장(Store) 하는 명령어입니다. 데이터 Access단위에 따라서 아래와 같이 분류됩니다. Load, Store는 ARM 명령어 가운데 가장 많이 사용되는 명령어이며 굉장히 중요합니다. 반드시 숙지 하고 있어야 합니다.<br />
- Word : LDR, STR<br />
- Byte : LDRB, STRB<br />
- Halfword : LDRH, STRH<br />
- Signed byte : LDRSB<br />
- Signed halfword : LDRSH</p>
<p><span style="color: #ff6600">(1) Syntax</span><br />
LDR{cond}{size} Rd, &lt;address&gt;<br />
STR{cond}{size} Rd, &lt;address&gt;</p>
<p><span style="color: #ff6600">(2) Addressing Mode</span><br />
- Pre Index : Rd 레지스터에 데이터를 먼저 이동시킨 후 &lt;address&gt; offset을 증가 혹은 감소합니다.<br />
<strong>R0 = 0&#215;31000000</strong><br />
<strong>R1 = 0&#215;00</strong><br />
<strong>R2 = 0&#215;00</strong></p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1461.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2661" alt="16FJK1461" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1461-300x112.jpg" width="300" height="112" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1450.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2650" alt="16FJK1450" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1450-300x67.jpg" width="300" height="67" /></a></td>
</tr>
</tbody>
</table>
<p>레지스터의 값들과 메모리(메모리 배열은 리틀 엔디언) 값이 위와 같을 때 아래 예제들을 차례대로 수행했을 때의 각각의 레지스터와 메모리의 값은?</p>
<p><strong>LDR R1, [R0]</strong> ; R1 &lt;&#8211; M[R0]
<p>R0가 가르키고 있는 0&#215;31000000 번지의 메모리 값은 0&#215;67452301 입니다. 그러므로 LDR 연산 이후에 R1에는 0&#215;67452301 값이 저장됩니다.</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1454.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2654" alt="16FJK1454" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1454-300x107.jpg" width="300" height="107" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1453.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2653" alt="16FJK1453" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1453-300x51.jpg" width="300" height="51" /></a></td>
</tr>
</tbody>
</table>
<p><strong>STR R1, [R0, #4]</strong> ; R1 &lt;&#8211; M[R0+4]
R0가 가르키는 0&#215;31000000 번지에서 4-byte 를 더한 번지의 메모리 위치에 R1(0&#215;67452301) 값을 저장합니다.</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1456.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2656" alt="16FJK1456" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1456-300x93.jpg" width="300" height="93" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1455.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2655" alt="16FJK1455" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1455-300x66.jpg" width="300" height="66" /></a></td>
</tr>
</tbody>
</table>
<p><strong>STR R1, [R0, #4]!</strong> ; R1 &lt;&#8211; M[R0+4], then R0 &lt;&#8211; R0+4</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1458.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2658" alt="16FJK1458" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1458-300x111.jpg" width="300" height="111" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1459.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2659" alt="16FJK1459" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1459-300x93.jpg" width="300" height="93" /></a></td>
</tr>
</tbody>
</table>
<p>R1에 0&#215;31000004번지의 메모리 내용 0&#215;67452301을 저장하고 난 이후에 R0의 레지스터값 + 0&#215;04 를 수행합니다.</p>
<p>예제에서 0&#215;30000000, 0&#215;30000004 번지의 내용이 동일해서 혼동될 수도 있지만 R1에는 R0레지스터값 + 0&#215;04 = 0&#215;30000004 번지의 값이 저장이 된다는 것을 기억하시기 바랍니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1463.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2663" alt="16FJK1463" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1463-300x66.jpg" width="300" height="66" /></a></p>
<p>- Post Index: Offset calculation after data transfer</p>
<p><strong>R0 = 0&#215;31000000</strong><br />
<strong>R1 = 0&#215;00</strong><br />
<strong>R2 = 0&#215;04</strong></p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1461.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2661" alt="16FJK1461" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1461-300x112.jpg" width="300" height="112" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1452.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2652" alt="16FJK1452" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1452-300x140.jpg" width="300" height="140" /></a></td>
</tr>
</tbody>
</table>
<p>레지스터의 값들과 메모리(메모리 배열은 리틀 엔디언) 값이 위와 같을 때 아래 예제들을 차례대로 수행했을 때의 각각의 레지스터와 메모리의 값은?</p>
<p><strong>LDR R1, [R0], R2</strong> ; R1 &lt;&#8211; M[R0], then R0 &lt;&#8211; R0+R2</p>
<p>R1에 R0가 가르키는 0&#215;31000000번지의 메모리값 0&#215;67452301의 값을 저장하고 나서 R0 = R0(0&#215;31000000) + R2(0&#215;04)가 됩니다. Preindex 방식에서는 R0를 먼저 계산하고 나서 메모리 번지의 값을 R1에 저장하였으나 Postindex 방식에서는 순서가 반대가 됩니다.</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1462.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2662" alt="16FJK1462" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1462-300x113.jpg" width="300" height="113" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1460.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2660" alt="16FJK1460" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1460-300x57.jpg" width="300" height="57" /></a></td>
</tr>
</tbody>
</table>
<p><strong>STR R1, [R0], #4</strong> ; R1 &lt;&#8211; M[R0], then R0 &lt;&#8211; R0+4</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1464.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2664" alt="16FJK1464" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1464-300x110.jpg" width="300" height="110" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1456.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2656" alt="16FJK1456" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1456-300x93.jpg" width="300" height="93" /></a></td>
</tr>
</tbody>
</table>
<p>레지스터 R1의 값 0&#215;67452301을 메모리 0&#215;31000004 번지에 저장을 하고난 이후에 R0 = R0(0&#215;310000004) + 0&#215;04 를 수행합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1457.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2657" alt="16FJK1457" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1457-300x77.jpg" width="300" height="77" /></a></p>
<p><span style="color: #ff6600">(3) Literal Pool</span><br />
32bit의 모든 값을 가질 수 없고 12bit를 가지고 일정 형식에 맞추어서 사용해야 합니다. Immediate value 에서 자세히 설명했던 내용입니다.</p>
<p><strong>MOV R0, #0&#215;12345678</strong> ; illegal (build error)<br />
<strong>LDR R0, =0&#215;12345678</strong> ; legal (build success)<br />
<strong>MOV R0, #0&#215;104</strong> ; legal<br />
<strong>MOV R0, #0&#215;102</strong> ; illegal</p>
<p>위의 예제에서 0&#215;12345678 값을 LDR 명령어를 사용하면 제약 없이 사용이 가능한 것을 알 수 있습니다. LDR 명령어를 사용하는 것이 편해보이기는 하지만 메모리에 접근하기 때문에 속도는 많이 느려지겠지요..</p>
<p><span style="color: #ff0000"><strong>7.6 Load/Store Multiple Instructions</strong></span><a id="1342322528242" name="7.6"></a></p>
<p>LDR, STR 명령어와 기능은 동일 하지만 Rn레지스터 값이 가르키는 메모리 위치에 여러 개 레지스터 값들을 저장할 수 있습니다.</p>
<p><span style="color: #ff6600">(1) Syntax</span><br />
LDM{cond}{addr_mode} Rn{!}, &lt;register_list&gt;{^}<br />
STM{cond}{addr_mode} Rn{!}, &lt;register_list&gt;{^}</p>
<p><span style="color: #ff6600">(2) Addressing Mode</span><br />
- IA : increment after<br />
- IB : increment before<br />
- DA : decrement after<br />
- DB : decrement before</p>
<p><span style="color: #ff6600">(3) Examples</span><br />
-레지스터 값들</p>
<p><strong>R0 = 0x000A</strong><br />
<strong>R4 = 0x000B</strong><br />
<strong>R5 = 0x000C</strong><br />
<strong>R13 = 0xFFF0</strong></p>
<p>STMIA R13!, {R0,R4-R5} 연산의 결과는?<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14013.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2694" alt="16FJK14013" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14013-300x138.jpg" width="300" height="138" /></a></p>
<p>STMIB R13!, {R0,R4-R5} 연산의 결과는?<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14014.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2695" alt="16FJK14014" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14014-300x140.jpg" width="300" height="140" /></a></p>
<p>STMDA R13!, {R0,R4-R5} 연산의 결과는?<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14015.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2696" alt="16FJK14015" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14015-300x138.jpg" width="300" height="138" /></a></p>
<p>STMDB R13!, {R0,R4-R5} 연산의 결과는?<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14016.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2697" alt="16FJK14016" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14016-300x141.jpg" width="300" height="141" /></a></p>
<p>참고로 ARM Compiler는 Stack 동작시 Full Descending Stack 방식으로 동작하고 있습니다. STMDA 명령어와 동일한 방식입니다. 즉 Stack Pointer는 항상 유효한 데이터를 가르키고 있고 주소가 감소하는 방향으로 저장이 됩니다.</p>
<p>- Stack에서 PUSH, STMDB 대신에 아래와 같이 사용이 가능합니다.<br />
STMFD SP!, {R4-R12, LR}</p>
<p>- Stack에서 POP, LDMIA 대신에 아래와 같이 사용이 가능합니다.<br />
LDMFD SP!, {R4-R12, PC}<br />
LDMFD SP!, {R0-R12, PC}^</p>
<p>&#8220;^&#8221; 연산자는 목적지의 레지스터(Rd)가 PC인 경우에 SPSR을 CPSR로 복구까지 하라는 명령입니다.</p>
<p><span style="color: #ff0000"><strong>7.7 Branch Instructions</strong></span><a id="1342322528243" name="7.7"></a></p>
<p>혹시 서브 함수와 서브 프로시져의 차이점을 알고 있나요? 2가지 모두 메인 프로그램 흐름에서 벗어(분기하여)나 특정 작업을 수행하는 것은 동일합니다. 하지만 엄밀하게 차이점을 이야기하면 서브 프로시져는 분기 이후에 분기하기 이전의 흐름으로 되돌아 오지 않고 분기한 주소에서부터 프로그램 수행이 계속될 경우에 사용을 하고 서브 함수는 분기한 주소에서 특정 작업을 수행하다가 분기 이전의 주소로 복귀하여 프로그램을 수행하도록 합니다. 설명이 길어 졌네요. 그림을 통해서 차이점을 구분해 보도록 합시다.</p>
<p><span style="text-decoration: underline">서브 프로시져 호출 시 프로그램 흐름</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14017.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2698" alt="16FJK14017" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14017-300x165.jpg" width="300" height="165" /></a></p>
<p><span style="text-decoration: underline">서브 함수 호출 시 프로그램 흐름</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14018.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2699" alt="16FJK14018" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14018-300x166.jpg" width="300" height="166" /></a></p>
<p><span style="color: #ff6600">(1) Syntax</span><br />
B{L}{cond} &lt;target_addr&gt;<br />
target_addr &lt;&#8211; pc + SignExtended(immed_24)&lt;&lt;2<br />
·여기서 PC는 Pipeline 에서 설명했듯이 Branch Instruction의 주소에서 8을 더한 위치가 됩니다.</p>
<p><span style="color: #ff6600">(2) Branch Range</span><br />
-32MB ~ +32MB<br />
분기 범위가 +- 32MB 까지로 제한이 되는 이유는 2^24 = 16MB &lt;&lt; 2를 하면 64MB이고 이를 +- 로 하면 32MB까지가 되는 것입니다.</p>
<p><span style="color: #ff6600">(3) Examples</span><br />
<strong>B Label</strong><br />
<strong>MOV PC, #0</strong><br />
<strong>MOV PC, LR</strong><br />
레지스터 R15(PC) 에 직접 분기할 주소를 저장하여도 분기가 가능합니다.<br />
<strong>LDR PC, =func</strong><br />
참고로 LDR 명령어를 사용하면 Branch명령어를 사용했을 때보다 1가지 잇점이 있는데 4GB이내에서는 어디든지 분기가 가능하다는 것입니다. Branch 명령어의 분기 range는 -32MB ~ +32MB의 제약이 있습니다. 물론 메모리에서 주소를 읽어와야 하므로 성능면에서는 좋지 않겠지요.</p>
<p><span style="color: #ff6600">(4) 함수 호출(BL)</span><br />
- 함수 호출시<br />
BL func &#8211;&gt; B 명령어와 다른 점은 LR레지스터에 PC-4 의 Address값이 H/W적으로 저장이 됩니다.<br />
- ARM 모드 함수 종료시<br />
MOV PC, LR &#8211;&gt; LR 에는 이미 BL 명령어의 주소 +4 의 값이 저장이 되어 있어 BL 명령어 다음부터 명령을 수행할 수 있도록 합니다.<br />
- Thumb 모드 함수 종료시<br />
BX LR</p>
<p><span style="color: #ff6600">(5) Subsequent Function Calls</span><br />
함수안에서 함수를 다시 호출을 하면 어떤 일이 발생할까요. 예제 코드를 가지고 분석해 보도록 하겠습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14019.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2700" alt="16FJK140" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14019-300x115.jpg" width="300" height="115" /></a></p>
<p>위의 예제에서 서브함수를 호출하고난 이후에 main 루틴에 있는 R2에는 #3이 저장이 되어있어야 합니다. 언뜻 보기에 #11이 저장이 되어있을 것 같습니다.</p>
<p>R0, R1은 func1에서 각각 #3, #4 가 저장이 되고 func2를 거치면서 #5, #6이 저장이 됩니다. 그래서 #11이 될 것이라고 예상이 될 수 있지만 사실은 func1의 ADD 명령어만 반복해서 실행이 될 것입니다. 왜냐하면 main에서 func1으로 branch할때까지는 LR에는 BL명령어 Address+4 가 저장이 되고 func1에서 func2로 분기할 때 다시 LR에는 func2로 분기하는 BL명령어 Address+4가 저장이 되어 최종 func2에서 MOV PC, LR 을 실행하면 func1의 ADD 명령어로 PC가 이동을 하고 다시 func1에서 MOV PC, LR 이 실행되면 LR 값에 의해서 다시 func1의 ADD 명령어가 반복해서 실행이 될 것입니다. 조금 복잡한듯 하지만 잘 따라가 보면 알 수 있습니다. 이 예제에서 알 수있는 것은 서브함수를 호출할 경우에는 서브함수 내에서 반드시 LR과 서브함수에서 사용할 레지스터들을 Stack에 백업을 하고 서브함수에서 복귀전에 다시 Stack에서 복원을 해야 한다는 것을 알 수 있습니다. 그러면 위의 예제를 main 루틴에 있는 R2에 #3이 저장이 되도록 수정을 하면 어떻게 될까요?</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1466.jpg" rel="lightbox[2515]"><img class="alignnone  wp-image-2666" alt="16FJK1466" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1466.jpg" width="370" height="299" /></a></p>
<p>위의 그림에서 MOV SP, #98304 를 하는 이유는 Stack을 사용하기 위해서 Supervisor 모드의 Stack 포인터를 초기화하는 것입니다. 참고로 Stack 포인터의 주소는 실제 타겟마다 다를 수 있습니다. Stack 포인터는 주로 시스템의 주 메모리에 위치합니다.</p>
<p><span style="color: #ff6600">(7) Veneer</span><br />
베니어라는 용어가 나오네요. 혹시 베니어 합판이라는 말을 들어 보셨나요? 작은 나무 조각들을 겹겹이 붙여서 만든 합판입니다. 여기 나오는 Veneer라는 개념이 흡사 베니어 합판을 만드는 것과 유사한 것 같습니다. 사실 Veneer라는 것은 ARM의 특성은 아니고 컴파일러에서 지원하는 기능입니다. 원래 B, BL 등의 분기 명령어는 -32MB~32MB 범위내에서 분기가 가능하다고 하였습니다. 하지만 아래 그림과 같이 MyFunc2을 호출할 때 컴파일러에서 자동으로 Veneer라는 중간 분기점을 만들어서 32MB 범위를 벗어나도 서브 함수를 호출 가능하도록 만들어 줍니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1424.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2624" alt="16FJK1424" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1424-300x69.jpg" width="300" height="69" /></a></p>
<p>위의 기능 이외에도 추가로 아래와 같은 기능이 있습니다.</p>
<p>- ARM to ARM or Thumb to Thumb 으로 분기<br />
: Long branch capability<br />
- ARM to Thumb or Thumb to ARM 으로 분기<br />
: Long branch capability and interworking capability</p>
<p><span style="color: #ff0000"><strong>7.8 Status Register Access Instructions</strong></span><a id="1342322528244" name="7.8"></a></p>
<p><span style="color: #ff6600">(1) Syntax</span><br />
MRS{cond} Rd, CPSR ; CPSR의 값을 Rd 레지스터로 읽어 옵니다.<br />
MRS{cond} Rd, SPSR ; SPSR의 값을 Rd 레지스터로 읽어 옵니다.<br />
MSR{cond} CPSR_&lt;fields&gt;, #&lt;immediate&gt;<br />
MSR{cond} CPSR_&lt;fields&gt;, &lt;Rm&gt; ; Rm 레지스터의 값을 CPSR에 저장합니다.<br />
MSR{cond} SPSR_&lt;fields&gt;, #&lt;immediate&gt;<br />
MSR{cond} SPSR_&lt;fields&gt;, &lt;Rm&gt; ; Rm 레지스터의 값을 SPSR에 저장합니다.<br />
이전에도 설명했지만 CPSR 레지스터의 구조를 다시 한번 확인 바랍니다.</p>
<p><span style="color: #ff6600">(2) Examples</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14020.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2701" alt="16FJK14020" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14020-300x185.jpg" width="300" height="185" /></a><br />
- IRQ 를 Enable 하는 코드 입니다.<br />
아래 명령어들이 수행되는 동안의 CPSR레지스터의 변화 값을 확인해보시기 바랍니다.</p>
<p><strong>MRS R0, CPSR</strong><br />
<strong>BIC R0, R0, #0&#215;80</strong> ; 7번 비트를 clear 하면 인터럽트가 활성화 됩니다.<br />
<strong>MSR CPSR, R0</strong></p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1468.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2668" alt="16FJK1468" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1468-300x164.jpg" width="300" height="164" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1467.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2667" alt="16FJK1467" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1467-300x44.jpg" width="300" height="44" /></a></td>
</tr>
</tbody>
</table>
<p>BIC, MSR 명령에 의해서 CPSR의 I 가 &#8220;0&#8243; 으로 변경(Unmask) 되어 Interrupt가 가능하게 되었습니다. 참고로 CPSR_fc 와 CPSR은 같은 레지스터입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1469.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2669" alt="16FJK1469" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1469-300x165.jpg" width="300" height="165" /></a></p>
<p>- IRQ를 Disable 하는 코드 입니다.</p>
<p><strong>MRS R0, CPSR</strong><br />
<strong>ORR R0, R0, #0&#215;80</strong> ; 7번 비트를 set 하면 인터럽트를 사용할 수 없습니다.<br />
<strong>MSR CPSR, R0</strong></p>
<p>간혹 MSR_c, MRS_x 등으로 사용되는 예제들이 있는데 밑줄 다음에 오는 flag의 의미는 아래와 같습니다. 그리고 밑줄 다음의 _c, _x 등은 의미를 명확하게 하기 위해서 사용하는 것일뿐 생략해도 아무 문제가 되지는 않습니다.</p>
<p>c = PSR[7:0]
x = PSR[15:8]
s = PSR[23:16]
F = PSR[31:24]
<span style="color: #ff0000"><strong>7.9 Software Interrupt Instruction</strong></span><a id="1342322528245" name="7.9"></a></p>
<p><span style="color: #ff6600">(1) Syntax</span><br />
SWI{cond} &lt;immed_24&gt;<br />
SEI 명령어는 S/W 적으로 강제적으로 ARM에 IRQ 예외를 발생 시킵니다. 주로 OS에서 User application들이 운영체제 서비스 루틴을 호출할 경우에 특권모드에서 콜하기 위해서 많이 사용됩니다.</p>
<p><span style="color: #ff6600">(2) Examples</span><br />
SWI #0&#215;123456</p>
<p><span style="color: #ff0000"><strong>7.10 SWP Instruction</strong></span><a id="1342322528246" name="7.10"></a></p>
<p><span style="color: #ff6600">(1) Syntax</span><br />
SWP{cond}{B} Rd, Rm, [Rn]
<p><span style="color: #ff6600">(2) Operation</span><br />
Temp &lt;&#8211; [Rn]
[Rn] &lt;&#8211; Rm<br />
Rd &lt;&#8211; Temp</p>
<p><span style="color: #ff6600">(3) Semaphore Instruction</span><br />
명령어 수행중에 인터럽트없이 메모리의 Read, Write 를 할 수 있는 Atomic 동작을 할 수 있습니다. Atomic이라는 용어가 나오는데요, 이것은 어떤 동작을 1개의 오퍼레이션으로 완료하는 것을 의미합니다. 즉 Atomic 오퍼레이션이 수행되는 동안에는 인터럽트가 발생하지 않는 것입니다.</p>
<p><span style="color: #ff6600">(4) Examples</span><br />
<strong>R0 = 0&#215;01</strong><br />
<strong>R1 = 0&#215;02</strong><br />
<strong>R2 = 0&#215;31000000</strong></p>
<p>&nbsp;</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1470.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2670" alt="16FJK1470" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1470-300x158.jpg" width="300" height="158" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1472.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2672" alt="16FJK1472" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1472-300x152.jpg" width="300" height="152" /></a></td>
</tr>
</tbody>
</table>
<p>레지스터의 값들이 위와 같을 때 아래 예제들을 차례대로 수행했을 때의 각각의 레지스터 값은?</p>
<p><strong>SWP R0, R1, [R2]</strong><br />
R2 가 가르키는 주소(0&#215;31000000)의 값 0&#215;78563412의 값이 R0에 저장이 되었고,</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1474.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2674" alt="16FJK1474" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1474-300x154.jpg" width="300" height="154" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1471.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2671" alt="16FJK1471" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1471-300x64.jpg" width="300" height="64" /></a></td>
</tr>
</tbody>
</table>
<p>R1의 값 0&#215;02가 R2가 가르키는 0&#215;31000000 메모리에 저장이 되었습니다.<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1473.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2673" alt="16FJK1473" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1473-300x142.jpg" width="300" height="142" /></a></p>
<p>아래의 예는 바이트 명령어입니다. SWPB 명령어를 사용했을 경우 R0 에는 어떤 값이 저장이 될까요?<br />
<strong>SWPB R0, R1, [R2]</strong></p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1477.jpg" rel="lightbox[2515]"><img class="alignnone  wp-image-2677" alt="16FJK1477" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1477-300x155.jpg" width="168" height="87" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1475.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2675" alt="16FJK1475" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1475-300x55.jpg" width="300" height="55" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1476.jpg" rel="lightbox[2515]"><img class="alignnone  wp-image-2676" alt="16FJK1476" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1476.jpg" width="164" height="82" /></a></td>
</tr>
</tbody>
</table>
<p>동작은 SWP와 동일하고 단지 바이트 단위로 SWP가 된다는 것만 다릅니다. 위의 그림들을 참조 하시기 바랍니다.</p>
<p><span style="color: #ff0000"><strong>7.11 Conditional Execution</strong></span><a id="1342322528247" name="7.11"></a></p>
<p>ARM모드 에서 굉장히 강력한 기능으로 명령어들을 특정 조건이 만족했을 때에만 실행시킬 수 있습니다. 이렇게 조건부 실행이 가능하면 성능면에서 아래와 같은 잇점이 있습니다.</p>
<p>- Increase code density<br />
- Decrease the number of branches</p>
<p>Thumb모드에서는 분기명령어 이외에는 이 조건부 실행 기능을 사용할 수 없습니다. 그 이유는 명령어의 길이가 Thumb 모드에서는 16bit로 제한이 되어서 조건부 실행을 할만큼 레지스터 공간이 충분하지 못하기 때문입니다. 그러면 실행 가능한 조건이라는 것은 어떤것들이 있을까요?<br />
ARM명령어 설명할 때 맨처음에 나왔던 그림인데요. 아래 그림을 보고 실행 조건에 대해서 설명하도록 하겠습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14008.jpg" rel="lightbox[2515]"><img class="alignnone  wp-image-2691" alt="16FJK14008" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14008-620x59.jpg" width="558" height="53" /></a></p>
<p><span style="text-decoration: underline">&lt; Cond &gt;</span></p>
<p>해당 명령의 조건 실행 플래그입니다. 데이터 프로세싱 명령어에도 당연히 포함됩니다. 해당 플래그를 통해 명령을 현재 플래그 레지스터(CPSR)의 상태에 따라 실행 여부를 결정하는데 사용되는 플래그입니다.<br />
ARM 명령어의 길이는 32bit라고 하였습니다. 32bit 중에서 4bit를 조건부 실행을 하는데 할당하고 있습니다. [31:28] bit가 바로 &lt;Cond&gt; 비트입니다.<br />
그리고 &lt;Cond&gt; 필드에 올 수 있는 것들은 아래 표와 같습니다.</p>
<table style="width: 550px" border="1" cellspacing="0" cellpadding="8">
<tbody>
<tr>
<td align="center" bgcolor="#FF6600" height="39">Cond</td>
<td align="center" bgcolor="#FF6600" height="39">Mnemonic</td>
<td align="center" bgcolor="#FF6600">Meaning</td>
<td align="center" bgcolor="#FF6600">Condition flag state</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF" width="69">0000</td>
<td align="center" bgcolor="#FFFFFF" width="107">EQ</td>
<td align="left" bgcolor="#FFFFFF" width="190">Equal</td>
<td align="left" bgcolor="#FFFFFF" width="444">Z = 1</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">0001</td>
<td align="center" bgcolor="#FFFFFF">NE</td>
<td align="left" bgcolor="#FFFFFF">Not Equal</td>
<td align="left" bgcolor="#FFFFFF">Z = 0</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">0010</td>
<td align="center" bgcolor="#FFFFFF">CS/HS</td>
<td align="left" bgcolor="#FFFFFF">Carry set / unsigned &gt;=</td>
<td align="left" bgcolor="#FFFFFF">C = 1</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">0011</td>
<td align="center" bgcolor="#FFFFFF">CC/LO</td>
<td align="left" bgcolor="#FFFFFF">Carry clear / unsigned &lt;</td>
<td align="left" bgcolor="#FFFFFF">C = 0</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">0100</td>
<td align="center" bgcolor="#FFFFFF">MI</td>
<td align="left" bgcolor="#FFFFFF">Minus/Negative</td>
<td align="left" bgcolor="#FFFFFF">N = 1</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">0101</td>
<td align="center" bgcolor="#FFFFFF">PL</td>
<td align="left" bgcolor="#FFFFFF">Plus/Positive or Zero</td>
<td align="left" bgcolor="#FFFFFF">N = 0</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">0110</td>
<td align="center" bgcolor="#FFFFFF">VS</td>
<td align="left" bgcolor="#FFFFFF">Overflow</td>
<td align="left" bgcolor="#FFFFFF">O = 1</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">0111</td>
<td align="center" bgcolor="#FFFFFF">VC</td>
<td align="left" bgcolor="#FFFFFF">No overflow</td>
<td align="left" bgcolor="#FFFFFF">O = 0</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">1000</td>
<td align="center" bgcolor="#FFFFFF">HI</td>
<td align="left" bgcolor="#FFFFFF">Unsigned higher</td>
<td align="left" bgcolor="#FFFFFF">C = 1 &amp; Z = 0</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">1001</td>
<td align="center" bgcolor="#FFFFFF">LS</td>
<td align="left" bgcolor="#FFFFFF">Unsigned lower or same</td>
<td align="left" bgcolor="#FFFFFF">C = 0 | Z = 1</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">1010</td>
<td align="center" bgcolor="#FFFFFF">GE</td>
<td align="left" bgcolor="#FFFFFF">Signed &gt;=</td>
<td align="left" bgcolor="#FFFFFF">N == V</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">1011</td>
<td align="center" bgcolor="#FFFFFF">LT</td>
<td align="left" bgcolor="#FFFFFF">Signed &lt;</td>
<td align="left" bgcolor="#FFFFFF">N != V</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">1100</td>
<td align="center" bgcolor="#FFFFFF">GT</td>
<td align="left" bgcolor="#FFFFFF">Signed &gt;</td>
<td align="left" bgcolor="#FFFFFF">Z == 0, N == V</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">1101</td>
<td align="center" bgcolor="#FFFFFF">LE</td>
<td align="left" bgcolor="#FFFFFF">Signed &lt;=</td>
<td align="left" bgcolor="#FFFFFF">Z == 1 or N! = V</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">1110</td>
<td align="center" bgcolor="#FFFFFF">AL</td>
<td align="left" bgcolor="#FFFFFF">Always</td>
<td align="left" bgcolor="#FFFFFF"></td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">1111</td>
<td align="center" bgcolor="#FFFFFF">(NV)</td>
<td align="left" bgcolor="#FFFFFF">Unpredictable</td>
<td align="left" bgcolor="#FFFFFF"></td>
</tr>
</tbody>
</table>
<p>참고로 우리가 지금까지 사용해왔던 MOV, ADD 명령어 뒤에 Mnemonic 없이 사용을 하면 &#8220;Always&#8221; 가 적용되어서 실행이 된 것입니다.</p>
<p><span style="color: #ff6600">(1) Condition Flag Change</span><br />
Condition Flag변경은 Data Processing Instructions에 의해서만 영향을 받으면 명령어 뒤에 &#8220;S&#8221; Prefix를 사용해야만 합니다.<br />
Condition Flag는 CPSR레지스터의 [31:24] 비트 필드에 정의되어 있습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14012.jpg" rel="lightbox[2515]"><img class="alignnone  wp-image-2693" alt="16FJK14012" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14012-620x382.jpg" width="446" height="275" /></a></p>
<p>설명이 조금 복잡한가요. 예제를 통해서 살펴 보도록 합시다.</p>
<p><span style="color: #ff6600">(1) Examples1</span><br />
NZCV 플래그가 변화하는 예제들입니다. 여기서 N(Negative), Z(Zero result)까지는 명확한 것 같은데 Carry, Overflower는 어떻게 다른 것일까요?<br />
아래 예제들을 수행하면서 차이점을 비교해보시기 바랍니다.</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1484.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2684" alt="16FJK1484" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1484-300x148.jpg" width="300" height="148" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1481.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2681" alt="16FJK1481" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1481-300x37.jpg" width="300" height="37" /></a></td>
</tr>
</tbody>
</table>
<p>· N : 연산의 결과 R2(0&#215;40000000)의 최상위 비트가 &#8220;1&#8243; 이 아님<br />
· Z : 연산의 결과 R2가 0&#215;0 이 아님<br />
· C : 32-bit 를 넘어섰으므로 Carry가 발생<br />
· V : ARM에서 Overflow 를 검출하는 방식은 MSB 이전 비트에서 발생한 Carry(&#8220;0&#8243; 과 &#8220;1&#8243; 을 더해도 Carry가 발생하지 않았으므로 &#8220;0&#8243;)와 MSB에서 발생한 Carry(&#8220;1&#8243; 과 &#8220;1&#8243; 을 더해서 Carry 가 발생했으므로 &#8220;1&#8243;)의 값이 달라지는 경우에 Overflow가 검출됩니다.</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1485.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2685" alt="16FJK1485" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1485-300x150.jpg" width="300" height="150" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1482.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2682" alt="16FJK1482" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1482-300x38.jpg" width="300" height="38" /></a></td>
</tr>
</tbody>
</table>
<p>· N : 연산의 결과 R2(0&#215;00000000)의 최상위 비트가 &#8220;0&#8243; 이므로 Negative 발생하지 않음<br />
· Z : 연산의 결과 R2가 0&#215;0 이므로 세팅<br />
· C : 32-bit 를 넘어섰으므로 Carry 가 발생<br />
· V : MSB 이전 비트에서 발생한 Carry(&#8220;0&#8243;과 &#8220;0&#8243;을 더해도 Carry가 발생하지 않았으므로 &#8220;0&#8243;)와 MSB에서 발생한 Carry(&#8220;1&#8243; 과 &#8220;1&#8243; 을 더해서 Carry 가 발생했으므로 &#8220;1&#8243;)의 값이 달라지는 경우에 Overflow가 검출됩니다.</p>
<table>
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1486.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2686" alt="16FJK1486" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1486-300x147.jpg" width="300" height="147" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1483.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2683" alt="16FJK1483" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1483-300x38.jpg" width="300" height="38" /></a></td>
</tr>
</tbody>
</table>
<p>· N : 연산의 결과 R2(0&#215;80000000)의 최상위 비트가 &#8220;1&#8243;이므로 Negative 발생<br />
· Z : 연산의 결과 R2가 0&#215;0 이 아님<br />
· C : 32-bit 를 넘어섰으므로 Carry가 발생<br />
· V : MSB 이전 비트에서 발생한 Carry(&#8220;1&#8243; 과 &#8220;1&#8243; 을 더해서 Carry가 발생했으므로 &#8220;1&#8243;)와 MSB에서 발생한 Carry(&#8220;1&#8243; 과 &#8220;1&#8243; 을 더해서 Carry 가 발생 했으므로 &#8220;1&#8243;)의 값이 다르지 않으므로Overflow가 검출되지 않습니다.</p>
<p><span style="color: #ff6600">(2) Examples2</span><br />
ADD R0, R1, R2 -&gt; does not update the flags( &#8220;S&#8221;Prefix가 없음)<br />
ADDS R0, R1, R2 -&gt; update the flags ( &#8220;S&#8221;Prefix가 있음)</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14009.jpg" rel="lightbox[2515]"><img class="alignnone  wp-image-2692" alt="16FJK14009" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14009-620x173.jpg" width="434" height="121" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>SUBS R2, R1, R0 : SUBS 명령 실행 이후에 CPSR의 condition flag가 업데이트 됩니다.</p>
<p>ADDEQ R3, R1, R0 : condition field 에 Z flag 가 Set 되어 있으면 실행이 되고 그렇지 않으면 NOP(단순히 CPU의 1Clock을 소비) 명령이 실행됩니다.<br />
condition field 에 Z flag 가 Set 되었다는 의미는 R1, R0 의 값이 같아서 R3에 &#8220;0&#8243;이 저장이 되었다는 의미입니다. 참고로 CMP, TST, CMN, TEQ instructions 등의 비교, 검사 명령어들은 &#8220;S&#8221; Prefix가 없이도 CPSR의 condition flag가 업데이트 됩니다.</p>
<p>다음 구문을 Conditional Execution을 사용했을 경우와 안했을 경우로 구분해서 비교해 보세요.</p>
<p>if(a==0) a = a + 1;<br />
else a = a &#8211; 1;</p>
<table style="width: 550px" border="1" cellspacing="0" cellpadding="8">
<tbody>
<tr>
<td align="center" bgcolor="#FF6600" height="39">Non Conditional Execution</td>
<td align="center" bgcolor="#FF6600" height="39">Conditional Execution</td>
</tr>
<tr>
<td align="left" bgcolor="#FFFFFF" width="346">      cmp r0, #0bne AAAadd r0, r0, #1b BBBAAAsub r0, r0, #1BBB</td>
<td align="left" bgcolor="#FFFFFF" width="376">cmp r0, #0addeq r0, r0, #1subne r0, r0, #1</td>
</tr>
<tr>
<td align="left" bgcolor="#FFFFFF">5 instructions1 branch execution</td>
<td align="left" bgcolor="#FFFFFF">3 instructions0 branch execution</td>
</tr>
</tbody>
</table>
<p>조건부 명령을 사용함으로서 instructions을 2개나 줄였고 가장 중요한 것은 branch 명령없이 구현을 했다는 것입니다.<br />
branch 명령은 ARM pipeline을 무너뜨리기 때문에 성능에서 굉장히 치명적입니다.</p>
<p><span style="color: #993300"><strong>8. Thumb Instruction Sets</strong></span><a id="1342322528248" name="8"></a></p>
<p>Thumb 명령어는 ARM 명령어에 비해서 16bit라는 명령어의 길이 때문에 많은 제약이 있습니다. 가장 단점은 조건부 실행 명령을 사용할 수가 없다는 것입니다.<br />
Thumb 명령어는 ARM을 이해하는 있어서 큰 부분을 차지하지는 않다고 생각되기 때문에 간단하게 특성 정도만 확인하고 넘어 가도록 하겠습니다.</p>
<p><span style="color: #ff0000"><strong>8.1 Thumb Instruction 특징</strong></span><a id="1342322528249" name="8.1"></a></p>
<p>(1) 16-bit length instruction set<br />
(2) ARM 명령어보다 코드의 집적도가 높습니다.( about 65% of ARM instruction )<br />
(3) 일반적으로는 32bit ARM명령어 보다는 속도가 느리지만 16bit memory 시스템에서는 그렇지 않을 수도 있습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1487.jpg" rel="lightbox[2515]"><img class="alignnone  wp-image-2687" alt="16FJK1487" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1487-620x223.jpg" width="434" height="156" /></a></p>
<p><strong style="color: #ff0000">8.2 Thumb Instruction 제약 사항</strong></p>
<p><a id="13423225282492" name="8.2"></a></p>
<p>· Limited Access to Registers : R0-R7 registers are accessible.<br />
· Narrow Range of Immediate Value<br />
· Not Flexible for Exception Mode<br />
· Exception Handler should be executed in ARM mode. : Exception이 발생하면 항상 ARM 모드로 전환이 됩니다.<br />
· Limited conditional instruction.<br />
· Branch instructions can be executed conditionally.<br />
· Inline Barrel Shifter is not used.</p>
<p><span style="color: #ff0000"><strong>8.3 Thumb, ARM Instruction 비교</strong></span><a id="13423225282493" name="8.3"></a><br />
아래 코드를 ARM 명령어와 Thumb 명령어로 작성하고 비교해보시기 바랍니다.</p>
<p>if(x&gt;=0) return x;<br />
else return -x;</p>
<table style="width: 550px" border="1" cellspacing="0" cellpadding="8">
<tbody>
<tr>
<td align="center" bgcolor="#FF6600" height="39">ARM Instruction</td>
<td align="center" bgcolor="#FF6600" height="39">Thumb Instruction</td>
</tr>
<tr>
<td align="left" bgcolor="#FFFFFF" width="346">abs_rtnCMP r0, #0RSBLT r0, r0, #0MOV pc, lr</td>
<td align="left" bgcolor="#FFFFFF" width="376">abs_rtnCMP r0, #0BGE returnNEG r0 r0returnMOV pc, lr</td>
</tr>
<tr>
<td align="left" bgcolor="#FFFFFF">- Instructions : 3- Size : 12Bytes- 16-bit bus : 6access- 32-bit bus : 3access</td>
<td align="left" bgcolor="#FFFFFF">- Instructions : 4- Size : 8Bytes- 16-bit bus : 4access- 32-bit bus : 4access</td>
</tr>
</tbody>
</table>
<p>위의 표에서 16-bit bus일경우의 access 횟수를 보면 오히려 Thumb 명령어가 효율을 보이기도 합니다.</p>
<p><span style="color: #ff0000"><strong>8.4 ARM/Thumb Interworking</strong></span><a id="13423225282494" name="8.4"></a></p>
<p>ARM 모드와 Thumb 모드를 같이 사용할 수가 있습니다. 하지만 동시에 명령어들을 섞어서 사용할 수 있는 것은 아니고 ARM 모드에서 BX branch명령어에 의해서 Thumb 모드로 전환을 할 수가 있고 다시 Thumb 모드에서 BX 명령어를 이용해서 ARM 모드로 복귀할 수 있습니다.</p>
<p><span style="color: #ff6600">(1) BX</span><br />
Instruction<br />
BX{cond} Rm<br />
CPSR.T &lt;&#8211; Rm[0], PC &lt;&#8211; Rm &amp; 0xFFFFFFFE</p>
<p>BX명령어는 일반 분기명령어와 비슷한 것 같지만 조금 다릅니다. 이유는 32bit ARM 모드에서 Thumb 모드로 전환을 할때 32bit 명령어에서 16bit로 변경되면서 PC의 주소 증가하는 값이 4byte에서 2byte로 바뀌기 때문에 그런 것입니다. 당연히 Thumb 모드에서 ARM 모드로 다시 복귀할 때는 반대의 경우이겠죠? 조금 어렵죠? 예를 들어서 설명하도록 하겠습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1479.jpg" rel="lightbox[2515]"><img class="alignnone  wp-image-2679" alt="16FJK1479" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1479.jpg" width="418" height="203" /></a></p>
<p>위의 그림에서 붉은 박스를 잘 보시면 armcode 부분은 32비트 코드 사이즈이고, thumbcode 부분은 16비트 길이의 코드 사이즈임을 알 수 있습니다.</p>
<p>0x5C address의 코드 BX, R0 코드가 수행이 되었을 때 레지스터의 상태를 보면 아래와 같습니다.<br />
thumbcode가 시작되는 주소는 0x6C인데, armcode의 &#8220;BX, R0(0x6d)&#8221; 코드에 의해서 0x6C가 아닌 0x6D로 분기하라고 되어 있습니다. 올바르게 수행이 될까요? 물론 잘 수행이 됩니다. 이것의 비밀은 위에서 설명한 &#8220;CPSR.T &lt;&#8211; Rm[0], PC &lt;&#8211; Rm &amp; 0xFFFFFFFE&#8221;에 있습니다.<br />
우선 CPSR.T = 1 로 변경이 되는 것은 Rm(1101101) 의 최하위 비트가 &#8220;1&#8243; 이기 때문입니다. 또한 Rm(1101101) &amp; 0xFFFFFFFE 에 의해서 실제 BX분기 명령어에 의해서 분기되는 주소는 0x6C가 됩니다. BX 명령어에서 Rm(1101101) &amp; 0xFFFFFFFE 해서 분기를 하는 이유는 ARM 모드(32비트)이건 Thumbmode(16비트) 이건 PC의 주소를 항상 2의 배수를 유지하기 위해서 입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1480.jpg" rel="lightbox[2515]"><img class="alignnone size-medium wp-image-2680" alt="16FJK1480" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK1480-300x150.jpg" width="300" height="150" /></a></p>
<p><span style="color: #800000"><strong>9. AAPCS</strong></span><a id="13423225282495" name="9"></a></p>
<p><span style="color: #ff0000"><strong>9.1 Procedure Call Standard for the ARM Architecture</strong></span><a id="13423225282496" name="9.1"></a></p>
<p>쉽게 이야기 하면 ARM에서 서브 루틴을 호출할 때의 레지스터, 스택 사용 방법에 대한 것입니다. 아래 표는 Procedure call시 사용되는 레지스터들을 표로 정리한 것입니다.</p>
<table style="width: 550px" border="1" cellspacing="0" cellpadding="8">
<tbody>
<tr>
<td align="center" bgcolor="#FF6600" height="39">Register</td>
<td align="center" bgcolor="#FF6600" height="39">Synonym</td>
<td align="center" bgcolor="#FF6600">Special</td>
<td align="center" bgcolor="#FF6600">Role in ther procedure call standard</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF" width="69">r15</td>
<td align="center" bgcolor="#FFFFFF" width="107"></td>
<td align="left" bgcolor="#FFFFFF" width="190">PC</td>
<td align="left" bgcolor="#FFFFFF" width="444">Program Count</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">r14</td>
<td align="center" bgcolor="#FFFFFF"></td>
<td align="left" bgcolor="#FFFFFF">LR</td>
<td align="left" bgcolor="#FFFFFF">Link Register</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">r13</td>
<td align="center" bgcolor="#FFFFFF"></td>
<td align="left" bgcolor="#FFFFFF">SP</td>
<td align="left" bgcolor="#FFFFFF">Stack Pointer</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">r12</td>
<td align="center" bgcolor="#FFFFFF"></td>
<td align="left" bgcolor="#FFFFFF">IP</td>
<td align="left" bgcolor="#FFFFFF">The Intra-procedure-call scratch register</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">r11</td>
<td align="center" bgcolor="#FFFFFF">v8</td>
<td align="left" bgcolor="#FFFFFF"></td>
<td align="left" bgcolor="#FFFFFF">Variable register8</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">r10</td>
<td align="center" bgcolor="#FFFFFF">v7</td>
<td align="left" bgcolor="#FFFFFF"></td>
<td align="left" bgcolor="#FFFFFF">Variable register7</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">r9</td>
<td align="center" bgcolor="#FFFFFF">v6</td>
<td align="left" bgcolor="#FFFFFF"></td>
<td align="left" bgcolor="#FFFFFF">Variable register6Platform registerTher meaning of the register is defined by the platform standad</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">r8</td>
<td align="center" bgcolor="#FFFFFF">v5</td>
<td align="left" bgcolor="#FFFFFF"></td>
<td align="left" bgcolor="#FFFFFF">Variable register5</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">r7</td>
<td align="center" bgcolor="#FFFFFF">v4</td>
<td align="left" bgcolor="#FFFFFF"></td>
<td align="left" bgcolor="#FFFFFF">Variable register4</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">r6</td>
<td align="center" bgcolor="#FFFFFF">v3</td>
<td align="left" bgcolor="#FFFFFF"></td>
<td align="left" bgcolor="#FFFFFF">Variable register3</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">r5</td>
<td align="center" bgcolor="#FFFFFF">v2</td>
<td align="left" bgcolor="#FFFFFF"></td>
<td align="left" bgcolor="#FFFFFF">Variable register2</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">r4</td>
<td align="center" bgcolor="#FFFFFF">v1</td>
<td align="left" bgcolor="#FFFFFF"></td>
<td align="left" bgcolor="#FFFFFF">Variable register1</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">r3</td>
<td align="center" bgcolor="#FFFFFF">a4</td>
<td align="left" bgcolor="#FFFFFF"></td>
<td align="left" bgcolor="#FFFFFF">Argument / scratch register4</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">r2</td>
<td align="center" bgcolor="#FFFFFF">a3</td>
<td align="left" bgcolor="#FFFFFF"></td>
<td align="left" bgcolor="#FFFFFF">Argument / scratch register3</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">r1</td>
<td align="center" bgcolor="#FFFFFF">a2</td>
<td align="left" bgcolor="#FFFFFF"></td>
<td align="left" bgcolor="#FFFFFF">Argument / scratch register2</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">r0</td>
<td align="center" bgcolor="#FFFFFF">a1</td>
<td align="left" bgcolor="#FFFFFF"></td>
<td align="left" bgcolor="#FFFFFF">Argument / result / scratch register1</td>
</tr>
</tbody>
</table>
<p>■ 참고로 scratch register들은 서브루틴 호출시 변경이 있을 수 있는 위험이 있는 레지스터입니다. 그러므로 서브루틴 호출시 Stack에 백업한 이후 서브루틴을 호출해야 합니다.</p>
<p>위의 표에서 알수 있는 것은 함수를 호출할 때 함수의 인자 4개까지는 r0 ~ r3에 저장이 되어 호출이 되고 함수에서 return에 의한 결과 값은 r0에 담아서 함수를 호출한 메인 함수로 값을 전달하고 있음을 알수 있습니다. 그럼 함수의 인자가 4개 이상인 경우에는 어떻게 되는 것일까요? 5번째 인자부터는 Stack에 저장한 후 함수에서 POP해서 사용합니다. Stack은 메인 메모리를 사용하므로 가능하면 함수 인자는 4개까지만 사용하는 것이 성능 향상에 도움이 됩니다.</p>
<p><span style="color: #ff0000"><strong> 9.2 Function Parameter Passing</strong></span><a id="13423225282497" name="9.2"></a></p>
<p>void main(void)</p>
<p>{</p>
<p>int sum;</p>
<p>// R0 레지스터에 a+b+c+d+e 의 합이 저장되어 return이 됩니다.</p>
<p>sum = func1(0, 1, 2, 3, 99);</p>
<p>}</p>
<p>int a &#8211;&gt; R0</p>
<p>int b &#8211;&gt; R1</p>
<p>int c &#8211;&gt; R2</p>
<p>int d &#8211;&gt; R3</p>
<p>int e &#8211;&gt; Stack</p>
<p>Return Value &#8211;&gt; R0</p>
<p>int func1(int a, int b, int c, int d, int e)</p>
<p>{</p>
<p>return a+b+c+d+e;</p>
<p>}</p>
<p>위의 C 코드를 Disassembly 해보면 다음과 같습니다. 오른쪽 설명을 참조 하시기 바랍니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14022.jpg" rel="lightbox[2515]"><img class="alignnone  wp-image-2622" alt="16FJK14022" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/16FJK14022-571x620.jpg" width="457" height="496" /></a></p>
<p>ARM Architecture 강의에서는 특정 CPU(S3C2440, STM32Fxx)에 대한 내용보다는 ARM Core의 이론적인 구조 자체에 대해서 많은 설명을 하였습니다. 다음 ARM Application 강의에서는 Samsung의 ARM9 CPU S3C2440 개발보드를 이용해 실제 실습을 통하여 ARM에 대해서 공부해 보도록 하겠습니다.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/2515/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[16호]2012 로보월드 참관기</title>
		<link>http://www.ntrexgo.com/archives/964</link>
		<comments>http://www.ntrexgo.com/archives/964#comments</comments>
		<pubDate>Thu, 10 Jan 2013 05:23:35 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[핫 뉴스]]></category>
		<category><![CDATA[16호]]></category>
		<category><![CDATA[로보월드]]></category>
		<category><![CDATA[매거진]]></category>
		<category><![CDATA[전시회]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=964</guid>
		<description><![CDATA[디바이스마트 매거진 16호 &#124; 지난 10월 25일(목)부터 28일(일)까지 4일간 일산 킨텍스전시장에서 2012 로보월드가 개최되었다.]]></description>
				<content:encoded><![CDATA[<p>지난 10월 25일(목)부터 28일(일)까지 4일간 일산 킨텍스전시장에서 2012 로보월드가 개최되었다.<br />
로보월드는 2007년부터 시작하여 5회째를 맞이하는 세계 최대 규모의 로봇 전문 전시회로써 올해에는 10개국 200개사, 500부스가 참가하고 30개국 약 10만명의 참관객이 방문했다. 주 전시품목으로는 제조업용 로봇, 전문/개인 서비스로봇, 부품 및 S/W등이 있다.</p>
<table style="width: 600px" border="0">
<tbody>
<tr>
<td width="300"> <a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201304.jpg" rel="lightbox[964]"><img class="alignnone size-medium wp-image-1275" alt="RobotWorld2013" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201304-300x199.jpg" width="300" height="199" /></a></td>
<td width="300"><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201303.jpg" rel="lightbox[964]"><img alt="" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201303-300x199.jpg" width="300" height="199" /></a></td>
</tr>
<tr>
<td width="300"><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201301.jpg" rel="lightbox[964]"><img alt="" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201301-300x199.jpg" width="300" height="199" /></a></td>
<td width="300"><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201310.jpg" rel="lightbox[964]"><img alt="" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201310-300x199.jpg" width="300" height="199" /></a></td>
</tr>
<tr>
<td colspan="2">▶ ㈜엔티렉스의 탱크형 로봇과 폭발물 제거 로봇</td>
</tr>
</tbody>
</table>
<table style="width: 600px" border="0">
<tbody>
<tr>
<td width="300"><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201302.jpg" rel="lightbox[964]"><img class="alignnone  wp-image-1255" alt="휴머노이드로봇" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201302-300x199.jpg" width="300" height="199" /></a></td>
<td width="300"><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld2013021.jpg" rel="lightbox[964]"><img class="alignnone size-medium wp-image-1294" alt="robotworld201302" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld2013021-300x199.jpg" width="300" height="199" /></a></td>
</tr>
<tr>
<td colspan="2">▶ 어린 아이들의 이목을 집중시켰던 휴머노이드 로봇</td>
</tr>
</tbody>
</table>
<table style="width: 600px" border="0">
<tbody>
<tr>
<td width="300"><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201308.jpg" rel="lightbox[964]"><img class="alignnone size-medium wp-image-1278" alt="robotworld201308" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201308-300x300.jpg" width="300" height="300" /></a></td>
<td width="300"><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201309.jpg" rel="lightbox[964]"><img class="alignnone size-medium wp-image-1279" alt="robotworld201309" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201309-300x223.jpg" width="300" height="223" /></a></td>
</tr>
<tr>
<td colspan="2">▶ 한울로보틱스의 탱크로봇(좌) / 로보링크의 두바퀴 자동차 세그웨이(우)</td>
</tr>
</tbody>
</table>
<table style="width: 600px" border="0">
<tbody>
<tr>
<td width="300"><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201306.jpg" rel="lightbox[964]"><img alt="" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201306-300x199.jpg" width="300" height="199" /></a></td>
<td width="300"><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201307.jpg" rel="lightbox[964]"><img alt="" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201307-300x199.jpg" width="300" height="199" /></a></td>
</tr>
<tr>
<td colspan="2">▶ 지능형 로봇서비스 산업 지원사업 설명회 모습과 지능형 탑승로봇으로 소개된 ㈜엔티렉스의 전기자동차</td>
</tr>
</tbody>
</table>
<table style="width: 600px" border="0">
<tbody>
<tr>
<td width="300"><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201312.jpg" rel="lightbox[964]"><img alt="" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201312-300x199.jpg" width="300" height="199" /></a></td>
<td width="300"><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201311.jpg" rel="lightbox[964]"><img alt="" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/robotworld201311-300x199.jpg" width="300" height="199" /></a></td>
</tr>
<tr>
<td colspan="2">▶ 초대형 로봇 뮤지컬 공연 &#8220;로봇랜드의 전설&#8221; 홍보관(좌) / 매회 참가하여 주목을 받는 현대중공업 로봇시스템(우)</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table style="width: 600px" border="0">
<tbody>
<tr>
<td>올해 전시회의 특징은 전문적인 로봇 개발 및 생산 업체의 참가가 줄었다는 점과, 현장 판매 위주의 업체들이 늘어났다는 점이다.<br />
예년에 비해 주목할 만한 부분은 전시장 내의 또 다른 전시장인 로보시티였다. 로보시티란 로봇을 이용할 수 있는 체험도시로서 로봇산업에 대한 인식과 문화를 조성하여 관람객이 로봇을 쉽게 접근하고 체험할 수 있게 만든 공간이다. 또한 휴머노이드 로봇대회 등 많은 연령층이 흥미롭게 볼 수 있는 이벤트가 많이 있었다.<br />
내년에도 전문적이면서 쉽고 재미있는 로봇 기술들을 만나 볼 수 있는 전시회가 되기를 바라며 후기를 마친다.</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/964/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[16호]100W급 DC 모터드라이버, NT-VNH20SV1 출시!</title>
		<link>http://www.ntrexgo.com/archives/1038</link>
		<comments>http://www.ntrexgo.com/archives/1038#comments</comments>
		<pubDate>Thu, 10 Jan 2013 02:03:15 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[프로덕트 뉴스]]></category>
		<category><![CDATA[16호]]></category>
		<category><![CDATA[매거진]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=1038</guid>
		<description><![CDATA[디바이스마트 매거진 16호 &#124; ㈜엔티렉스에서 100W급 DC모터를 제어하기 위한 모터드라이버를 출시했다.]]></description>
				<content:encoded><![CDATA[<p style="text-align: center"><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/product166.jpg" rel="lightbox[1038]"><img class="size-medium wp-image-1095 aligncenter" alt="NT-VNH20SV1" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/product166-300x225.jpg" width="300" height="225" /></a></p>
<p>㈜엔티렉스에서 100W급 DC모터를 제어하기 위한 모터드라이버를 출시했다.</p>
<p>ST사의 VNH2SP30이라는 H-Bridge 회로가 내장된 모터구동용 원칩을 이용하여 개발하였으며, 작은 사이즈임에도 불구하고 순간 전류 최대 30A까지 구동이 가능하다. 또한 19V 이상의 전압이 입력되었을 때 SHUT DOWN 기능을 내장하고 있다.<br />
단순 구동을 위한 모터드라이버로, 사용자 인터페이스가 아주 간단하며, EN핀의 신호에 따라서 드라이버 전체의 ON/OFF를 제어하고, 방향 신호(INA,INB)핀에 따라서 정역회전 및 정지가 가능하다.</p>
<p><span style="color: #0000ff"><strong>■ NT-VNH20SV1의 사양 ■</strong></span></p>
<ul>
<li>Input Voltage : +7V &#8211; +18V</li>
<li>Maximum Current Rating : 30A(순간최대)</li>
<li>maximum PWM Frequency : 20KHz</li>
<li>Overvoltage Shut down : 19V</li>
<li>Undervoltage Shut down : 5.5V</li>
</ul>
<div class="symple-toggle"><h3 class="symple-toggle-trigger">제품 설명 더보기</h3><div class="symple-toggle-container">
<p><a name="detail"></a><a name="detail"></a></p>
<table style="width: 100%" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<table style="width: 100%" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td align="center">
<table style="width: 550px" border="0" cellspacing="0" cellpadding="0" align="center">
<tbody>
<tr>
<td width="550" height="41">
<table style="width: 550px" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="550"><span style="color: #800000"><strong>NT-VNH20SV1의 소개</strong></span></td>
</tr>
<tr>
<td colspan="2" width="680" height="10"></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td width="680"><b>NT-VNH20SV1은 100W급의 DC모터를 제어하기 위한 모터드라이버 입니다.</b><br />
본 모터드라이버는 ST사의 VNH2SP30 이라는 H-Bridge 회로가 내장된 모터구동용 원칩을 이용하여 구성되었으며, 작은 사이즈임에도 불구하고 순간전류로 최대 30A까지 드라이빙이 가능하고, 19V이상의 전압이 입력시 SHUT DOWN 기능을 내장하고 있습니다.<br />
단순구동을 위한 모터드라이버이므로, 사용자 인터페이스는 아주 간단합니다. EN핀의 신호에 따라서 드라이버 전체의 ON/OFF를 제어하고, 방향신호(INA,INB)핀에 따라서, 정역회전 및 정지가 가능하며, 펄스입력핀(PWM)에 신호의 인가로 속도를 제어합니다.<br />
내부적으로 10A용량의 휴즈가 내장되어져 있습니다.제어상의 좀더 자세한 사항은 VNH2SP30-E의 데이터 시트를 참조하시면 됩니다.</td>
</tr>
<tr>
<td width="550" height="41"><span style="color: #800000"><strong>Specifications</strong></span></td>
</tr>
<tr>
<td colspan="2" width="550" height="10"></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td align="middle" width="550">
<table style="width: 550px" border="1" cellspacing="0" cellpadding="5">
<tbody>
<tr>
<td align="middle" bgcolor="#f7f7f7" width="81"><b>Pin out</b></td>
<td align="middle" bgcolor="#f7f7f7" width="107"><b>명칭</b></td>
<td align="middle" bgcolor="#f7f7f7" width="193"><b>기능</b></td>
<td align="middle" bgcolor="#f7f7f7" width="119"><b>IN/OUT</b></td>
</tr>
<tr>
<td align="middle">1</td>
<td align="middle">Battery+</td>
<td align="middle">Power</td>
<td align="middle">OUTPUT</td>
</tr>
<tr>
<td align="middle">2</td>
<td align="middle">Battery-</td>
<td align="middle">GND</td>
<td align="middle">COMMON</td>
</tr>
<tr>
<td align="middle">3</td>
<td align="middle">Vcc</td>
<td align="middle">+5V</td>
<td align="middle">INPUT</td>
</tr>
<tr>
<td align="middle">4</td>
<td align="middle">INA</td>
<td align="middle">Direction Pin</td>
<td align="middle">INPUT</td>
</tr>
<tr>
<td align="middle">5</td>
<td align="middle">EN</td>
<td align="middle">Enable</td>
<td align="middle">INPUT</td>
</tr>
<tr>
<td align="middle">6</td>
<td align="middle">PWM</td>
<td align="middle">Speed Control</td>
<td align="middle">INPUT</td>
</tr>
<tr>
<td align="middle">7</td>
<td align="middle">CS</td>
<td align="middle">Current Senseing</td>
<td align="middle">OUTPUT</td>
</tr>
<tr>
<td align="middle">8</td>
<td align="middle">INB</td>
<td align="middle">Direction Pin</td>
<td align="middle">INPUT</td>
</tr>
<tr>
<td align="middle">B+</td>
<td align="middle">Battery+</td>
<td align="middle">-</td>
<td rowspan="2" align="middle">INPUT</td>
</tr>
<tr>
<td align="middle">B-</td>
<td align="middle">Battery-</td>
<td align="middle">-</td>
</tr>
<tr>
<td align="middle">M+</td>
<td align="middle">Motor+</td>
<td align="middle">-</td>
<td align="middle">INPUT</td>
</tr>
<tr>
<td align="middle">M-</td>
<td align="middle">Motor-</td>
<td align="middle">-</td>
<td align="middle">OUTPUT</td>
</tr>
</tbody>
</table>
<table style="width: 550px" border="1" cellspacing="0" cellpadding="5">
<tbody>
<tr>
<td colspan="2" bgcolor="#f7f7f7"><b>Electrical data</b></td>
</tr>
<tr>
<td>Input Voltage</td>
<td>+7V &#8211; +18V</td>
</tr>
<tr>
<td>Maximum Current Rating</td>
<td>(순간전류) 30A</td>
</tr>
<tr>
<td>Maximum PWM Frequency</td>
<td>20KHz</td>
</tr>
<tr>
<td>Overvoltage Shut dowm</td>
<td>19V</td>
</tr>
<tr>
<td>Undervoltage Shut down</td>
<td>5.5V</td>
</tr>
<tr>
<td>Input Logic Level</td>
<td>+3.3V &#8211; +5V</td>
</tr>
<tr>
<td>Current Sense</td>
<td>0.13V / A</td>
</tr>
</tbody>
</table>
<table style="width: 500px" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<ol>
<li>배터리의 +측 전압이 출력됩니다.</li>
<li>배터리의 -측 전압이 출력되며, 다른 신호들과 공통 GND로 사용됩니다.</li>
<li>+5V의 전압이 모터드라이버 측에 입력 되어져야 합니다.</li>
<li>방향제어신호</li>
<li>모터드라이버의 전체 on/off</li>
<li>펄스신호를 입력하여 속도를 제어합니다.</li>
<li>전류변화에 따라 전압이 출력됩니다. 1A당 약 0.13V, 온도변화에 따른 드리프트 존재함.</li>
<li>방향제어신호</li>
</ol>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</td>
</tr>
<tr>
<td width="550" height="10"></td>
</tr>
<tr>
<td width="550" height="41">
<table style="width: 550px" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="20"></td>
<td width="550"><strong><span style="color: #800000">사용상 주의사항</span></strong></td>
</tr>
<tr>
<td colspan="2" width="550" height="10"></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td width="550">
<ol>
<li>정격 이상의 전압 입력을 인가하시면 안됩니다.</li>
<li>정격 이상의 모터를 연결 하시면 안됩니다.</li>
<li>배터리에 연결하시기전 극성을 확인하시기 바랍니다.</li>
<li>성능을 극대화 하시려면 통풍이 잘되도록 유지하시거나 추가적인 방열판을 부착 하시기 바랍니다.</li>
<li>케이스가 없는 제품이므로 정전기 및 이물질에 의한 합선에 주의 하셔야 합니다.</li>
<li>본 제품은 출하직전 모든 부분에 대한 전수검사가 실시됩니다.</li>
</ol>
<p>&nbsp;</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td align="center"><img alt="" src="http://www.devicemart.co.kr/skin/goods/detail/37871_1.jpg" width="455" height="1026" /></td>
</tr>
<tr>
<td align="center"><img alt="" src="http://www.devicemart.co.kr/skin/goods/detail/37871_2.jpg" width="540" height="405" /></td>
</tr>
<tr>
<td align="center"><img alt="" src="http://www.devicemart.co.kr/skin/goods/detail/37871_3.jpg" width="540" height="405" /></td>
</tr>
<tr>
<td align="center"><img alt="" src="http://www.devicemart.co.kr/skin/goods/detail/37871_4.jpg" width="540" height="405" /></td>
</tr>
<tr>
<td height="20"></td>
</tr>
</tbody>
</table>
</div></div>
<p>&nbsp;</p>
<p><a title="클릭하시면 NT-VNH20SV1 구입페이지로 연결됩니다." href="http://www.devicemart.co.kr/goods/view.php?seq=37871" target="_blank">제품 구입하러 가기</a></p>
<p>&nbsp;</p>
<p>TEL. 070-7019-8887<br />
www.ntrex.co.kr</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/1038/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[16호]ARM Corex-M3 코어가 내장된 4.3인치 칼라 디스플레이,SmartLCD 4.3 출시!</title>
		<link>http://www.ntrexgo.com/archives/1043</link>
		<comments>http://www.ntrexgo.com/archives/1043#comments</comments>
		<pubDate>Thu, 10 Jan 2013 01:56:21 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[프로덕트 뉴스]]></category>
		<category><![CDATA[16호]]></category>
		<category><![CDATA[디스플레이]]></category>
		<category><![CDATA[매거진]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=1043</guid>
		<description><![CDATA[디바이스마트 매거진 16호 &#124; 데브툴즈, SmartLCD 4.3 출시!]]></description>
				<content:encoded><![CDATA[<p style="text-align: center"><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/product168.jpg" rel="lightbox[1043]"><img class="size-medium wp-image-1097 aligncenter" alt="smartLCD" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/product168-300x225.jpg" width="300" height="225" /></a></p>
<p>데브툴즈에서 SmartLCD 4.3을 출시했다.</p>
<p>SmartLCD 4.3 모델은 ARM Corex-M3 코어 내장형 4.3인치 칼라 디스플레이로 4.3인치 컬러 TFTLCD(480x272Pixe, 65Kcolor, 4선 저항식 터치)와 STM32F103VET6 Flash 512K, RAM64K, 72MHz의 MCU를 내장하고 있다.</p>
<p>MCU를 STM32F407VGT6으로 교체하여 사용할 수 있도록 설계 되었으며 KEIL 예제 소스와 uCos+ucGUI, ucGUIBuilder4.0, 회로도, 치수도면 등이 제공된다.</p>
<p>이번에 SmartLCD 7.0 모델도 동시에 출시되었으며, 기판에 장착하여 여러가지 통신 및 MP3, 카메라 기능을 적용할 수 있는 확장 기판과 함께 아크릴 거치대, 12V SMPS가 포함되어 있는 완성품 버전도 출시됐다.</p>
<div class="symple-toggle"><h3 class="symple-toggle-trigger">제품 설명 더보기</h3><div class="symple-toggle-container">
<p><strong>제품설명</strong></p>
<p>&nbsp;</p>
<h4>ARM CORTEX-M3 코어 내장형 4.3인치 칼라 디스플레이</h4>
<ul>
<ul>
<li>4.3 inch true color TFT LCD, 480 * 272 pixel,65k color,4선 저항식 touch</li>
<li>MCU: STM32F103VET6 FLASH 512K , RAM64K , 72Mhz</li>
<li>외부기억장치: MicroSD</li>
<li>TOUCH IC: ADS7846E</li>
<li>2.0mm 10핀 JTAG 커넥터 내장 ( 2.54mm 20핀 변환기판 제공)</li>
<li>KEIL 예제소스제공(프로젝트파일) , <span style="color: #ff0000">uCos + ucGUI, ucGUIBuilder 4.0 유틸제공</span></li>
<li>PANEL장착형으로 제품에 응용가능(남는 포트는 외부로 확장-50핀 사용가능함)</li>
<li>회로도 , 치수도면제공</li>
<li><span style="color: #ff0000">STM32F407VGT6 로 칩을 교체하여 사용할 수 있는 기판설계</span></li>
</ul>
</ul>
<ul>
<ul>
<ul>※ NAND 메모리는 별도 구매품입니다.</ul>
</ul>
</ul>
<p>*<b>네이버 카페주소</b><br />
<a href="http://cafe.naver.com/devtools" target="_blank">http://cafe.naver.com/devtools</a><br />
에 소스업데이트 및 추가회로도가 있습니다.<br />
<img alt="" src="http://www.devicemart.co.kr/mart7/upload/fd_html_img/38100/38100s_img1.jpg" width="600" /><br />
</div></div>
<p><a title="Smart LCD 제품 안내" href="http://www.devicemart.co.kr/goods/view.php?seq=38100" target="_blank">제품 구입하러 가기</a></p>
<p>TEL. 051-751-1833 www.dev-tools.co.kr</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/1043/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[16호]ALTERA FPGA 개발키트 (AFPE-003) 출시!</title>
		<link>http://www.ntrexgo.com/archives/1046</link>
		<comments>http://www.ntrexgo.com/archives/1046#comments</comments>
		<pubDate>Thu, 10 Jan 2013 01:23:29 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[프로덕트 뉴스]]></category>
		<category><![CDATA[16호]]></category>
		<category><![CDATA[개발키트]]></category>
		<category><![CDATA[매거진]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=1046</guid>
		<description><![CDATA[디바이스마트 매거진 16호 &#124; 하이텍로직에서 출시한 ALTERA FPGA 개발키트 (AFPE-003)는 ALTERA사의 Cyclone Family 중 EP3C16Q240C8N을 실장한 FPGA 트레이닝 보드이다.]]></description>
				<content:encoded><![CDATA[<p style="text-align: center"><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/product164.jpg" rel="lightbox[1046]"><img class="size-medium wp-image-1093 aligncenter" alt="ALTERA FPGA 개발키트" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/product164-300x225.jpg" width="300" height="225" /></a></p>
<p>하이텍로직에서 출시한 ALTERA FPGA 개발키트 (AFPE-003)는 ALTERA사의 Cyclone Family 중 EP3C16Q240C8N을 실장한 FPGA 트레이닝 보드이다. C-MOS Image Sensor(OV7670)를 이용한 영상처리 및 Wiznet사의 W5300을 사용한 Ethernet 인터페이스를 코드레벨(VHDL)에서 구현하여 사용자에게 제공한다. 교육 예제 및 교재가 포함된 CD를 함께 제공하며, I/O(LED, Seven-Segment, DIP-Switch, Tactile Switch, USB to Serial), TFT-LCD(4.3&#8243; Wide), Ethernet, OV7670을 통해서 다양하게 학습할 수 있도록 개발된 FPGA 개발 키트이다.</p>
<div class="symple-toggle"><h3 class="symple-toggle-trigger">제품 설명 더보기</h3><div class="symple-toggle-container">
<p><a name="detail"></a></p>
<table style="width: 600px" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<table style="width: 600px" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td align="center">
<table style="width: 680px" border="0" cellspacing="0" cellpadding="0" align="center">
<tbody>
<tr>
<td width="680">
<table style="width: 680px" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="660"><span style="color: #0000ff"><strong>FEATURES</strong></span></td>
</tr>
<tr>
<td colspan="2" width="680" height="10"></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td width="680">
<table style="width: 650px" border="1" cellspacing="0" cellpadding="3">
<tbody>
<tr>
<td bgcolor="#f7f7f7"><strong>Model Name</strong></td>
<td>AFPE-003</td>
</tr>
<tr>
<td bgcolor="#f7f7f7"><strong>FPGA</strong></td>
<td>Cyclone-III Family, EP3C16Q240C8N</td>
</tr>
<tr>
<td bgcolor="#f7f7f7"><strong>Configuration Device</strong></td>
<td>EPCS16(ALTERA, 16Mbit)</td>
</tr>
<tr>
<td bgcolor="#f7f7f7"><strong>Power Input</strong></td>
<td>5V DC : Adapter</td>
</tr>
<tr>
<td bgcolor="#f7f7f7"><strong>Internal Power</strong></td>
<td>Three high-current voltage regulators(3.3V, 2.5V, 1.2V)</td>
</tr>
<tr>
<td bgcolor="#f7f7f7"><strong>Status LEDs</strong></td>
<td>Power, Done</td>
</tr>
<tr>
<td bgcolor="#f7f7f7"><strong>JTAG Connector</strong></td>
<td>10-pin header (2.54[mm] pitch)</td>
</tr>
<tr>
<td bgcolor="#f7f7f7"><strong>AS Connector</strong></td>
<td>10-pin header (2.54[mm] pitch)</td>
</tr>
<tr>
<td bgcolor="#f7f7f7"><strong>On-Board Clock</strong></td>
<td>24[MHz]</td>
</tr>
<tr>
<td bgcolor="#f7f7f7"><strong>10/100 Ethernet</strong></td>
<td>WizNet w5300</td>
</tr>
<tr>
<td bgcolor="#f7f7f7"><strong>Image Sensor Module</strong></td>
<td>OmniVision OV7670</td>
</tr>
<tr>
<td bgcolor="#f7f7f7"><strong>TFT-LCD</strong></td>
<td>LTE-430WQ(480 × 272, 4.3&#8243; Wide)</td>
</tr>
<tr>
<td bgcolor="#f7f7f7"><strong>SRAM</strong></td>
<td>512K × 16</td>
</tr>
<tr>
<td bgcolor="#f7f7f7"><strong>Design Tools</strong></td>
<td>Free Quartus software</td>
</tr>
<tr>
<td bgcolor="#f7f7f7"><strong>Simulation Tools</strong></td>
<td>Modelsim-Altera Stater Edition v6.6d</td>
</tr>
</tbody>
</table>
<ul>
<li>Naver Cafe에서 다양한 예제 및 자료제공
<ul>
<li><a href="http://cafe.naver.com/seogarae" target="_blank">http://cafe.naver.com/seogarae</a></li>
</ul>
</li>
</ul>
</td>
</tr>
<tr>
<td width="680">
<table style="width: 680px" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="660"><span style="color: #0000ff"><strong>AFPE-003 제품 구성</strong></span></td>
</tr>
<tr>
<td colspan="2" width="680" height="10"></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td width="680">
<p align="center"><img alt="" src="http://www.devicemart.co.kr/mart7/upload/fd_html_img/38081/img04.jpg" width="480" height="480" /></p>
<p align="center">
</td>
</tr>
<tr>
<td width="680">
<table style="width: 680px" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="660"><span style="color: #0000ff"><strong>AFPE-003 보드의 주요 명칭</strong></span></td>
</tr>
<tr>
<td colspan="2" width="680" height="10"></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td width="680">
<p align="center"><img alt="" src="http://www.devicemart.co.kr/mart7/upload/fd_html_img/38081/img05.jpg" width="472" height="282" /></p>
<ul>
<li>AFPE-003 PCB Size : 9600mil × 5100mil (243.8mm × 129.5mm)</li>
</ul>
<p align="center"><img alt="" src="http://www.devicemart.co.kr/mart7/upload/fd_html_img/38081/img06.jpg" width="454" height="307" /></p>
</td>
</tr>
<tr>
<td width="680">
<table style="width: 680px" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="660"><span style="color: #0000ff"><strong>XFPE-003 교육교재 주요항목</strong></span></td>
</tr>
<tr>
<td colspan="2" width="680" height="10"></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td width="680">
<p align="center"><img alt="" src="http://www.devicemart.co.kr/mart7/upload/fd_html_img/38081/img07.jpg" width="494" height="634" /></p>
<p align="center"><span style="color: #0000ff"><strong> </strong></span></p>
</td>
</tr>
<tr>
<td width="680">
<table style="width: 680px" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="660"><span style="color: #0000ff"><strong>다양한 Test Panel 제공</strong></span></td>
</tr>
<tr>
<td colspan="2" width="680" height="10"></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td width="680">Test Panel 사용법은 <a href="http://cafe.naver.com/seogarae" target="_blank">http://cafe.naver.com/seogarae</a> 참조</p>
<ul>
<li>TFT-LCD Test Panel</li>
</ul>
<p align="center"><img alt="" src="http://www.devicemart.co.kr/mart7/upload/fd_html_img/38081/img08.jpg" width="458" height="450" /></p>
<ul>
<li>USB to Serial Test Panel</li>
</ul>
<p align="center"><img alt="" src="http://www.devicemart.co.kr/mart7/upload/fd_html_img/38081/img09.jpg" width="434" height="545" /></p>
<ul>
<li>Ethernet Test Panel</li>
</ul>
<p><img class="aligncenter" alt="" src="http://www.devicemart.co.kr/mart7/upload/fd_html_img/38081/img10.jpg" width="540" height="413" /></p>
<ul>
<li>Loopback Test Panel</li>
</ul>
<p align="center"><img alt="" src="http://www.devicemart.co.kr/mart7/upload/fd_html_img/38081/img11.jpg" width="502" height="306" /></p>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div></div>
<p>&nbsp;</p>
<p><a href="http://www.devicemart.co.kr/goods/view.php?seq=38081" target="_blank">제품 구입하러 가기</a></p>
<p>&nbsp;</p>
<p>cafe.naver.com/seogarae</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/1046/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[14호] 안드로이드를 이용한 탱크 조종</title>
		<link>http://www.ntrexgo.com/archives/2049</link>
		<comments>http://www.ntrexgo.com/archives/2049#comments</comments>
		<pubDate>Sat, 25 Aug 2012 04:12:13 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[프로젝트]]></category>
		<category><![CDATA[16호]]></category>
		<category><![CDATA[diy]]></category>
		<category><![CDATA[Project To Build]]></category>
		<category><![CDATA[매거진]]></category>
		<category><![CDATA[안드로이드]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=2049</guid>
		<description><![CDATA[디바이스마트 매거진 14호 &#124; 안드로이드를 이용한 탱크 조종을 하고자 하였다. 통신 방식은 블루투스를 이용하고 탱크측 제어는 Attiny2313를 이용하였고, 단순 전후진만이 아닌 다른 동작들을 추가 하였다.]]></description>
				<content:encoded><![CDATA[<h3><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband03.jpg" rel="lightbox[2049]"><img class=" wp-image-2071 alignleft" alt="14ptband03" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband03-300x221.jpg" width="216" height="159" /></a>2012 DIY 프로젝트 작품 공모전 &#8211; 도전상</h3>
<h2><strong><span style="color: #008080">안드로이드를 이용한 </span></strong></h2>
<h2><strong><span style="color: #008080">탱크 조종</span></strong></h2>
<p style="padding-left: 420px">글 | 김종욱 bear1215@korea.com</p>
<p style="padding-left: 420px">
<p style="padding-left: 420px">
<p>&nbsp;</p>
<p><strong style="color: #008000">심사평</strong></p>
<p style="padding-left: 30px">근래 관심을 받는 안드로이드와 일반 주행 로봇을 결합한 작품이다. 무선조종기 대신 안드로이드 OS를 이용하여 해당 OS가 설치된 장비(폰, 태블릿 등)에서 로봇을 조종할 수 있도록 되어있다. 일반 사용자의 DIY 컨셉에 맞춰 본다면 쉽게 접근할 수 있는 내용이다. 단, 안드로이드 측 프로그램에 대한 구현방법에 대한 설명 등이 문서상 미흡한 것이 아쉬움으로 남는다.</p>
<p><span style="color: #008000"><strong>개발 동기 및 목적</strong></span></p>
<p style="padding-left: 30px">안드로이드를 이용한 탱크 조종을 하고자 하였다. 통신 방식은 블루투스를 이용하고 탱크측 제어는 Attiny2313를 이용하였고, 단순 전후진만이 아닌 다른 동작들을 추가 하였다. 1.전후진, 2.좌회전, 3.우회전, 4.좌후진, 5.우후진, 6.포탑 회전(좌우), 7.포신의 상하 이동, 8.포탄 발사(BB탄 발사), 9.전조등/후미등 켜기</p>
<p>&nbsp;</p>
<p><span style="color: #008000"><strong>단계별 과정</strong></span></p>
<p><strong><span style="color: #33cccc">1. 구조도(상세 블럭도 및 회로도 참조)</span></strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband.jpg" rel="lightbox[2049]"><img class="alignnone size-medium wp-image-2082" alt="구조도" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband-241x300.jpg" width="241" height="300" /></a><br />
<strong><span style="color: #33cccc">2. 전원</span></strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband01.jpg" rel="lightbox[2049]"><img class="alignnone size-medium wp-image-2083" alt="14ptband01" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband01-300x142.jpg" width="300" height="142" /></a></p>
<p>전원은 기존의 밧데리를 이용한다. (9.7V 1000mA)<br />
정전원 변환은 LM2575-5.0를 사용하였다. 전원은 9.7V를 모터 구동 전원으로 사용하고 제어부인 Attiny2313은 5.0V 전원을 사용한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband02.jpg" rel="lightbox[2049]"><img class="alignnone size-medium wp-image-2084" alt="14ptband02" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband02-300x135.jpg" width="300" height="135" /></a><br />
탱크부 구성<br />
기존의 RF 제어부를 제거하고 모터, 밧데리 등은 그대로 사용한다. 탱크의 구성은 아래의 표와 같다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband014.jpg" rel="lightbox[2049]"><img class="alignnone size-medium wp-image-2096" alt="14ptband014" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband014-300x125.jpg" width="300" height="125" /></a><br />
<strong><span style="color: #33cccc">3. 탱크 제어부 구성</span></strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband03.jpg" rel="lightbox[2049]"><img class="alignnone size-medium wp-image-2071" alt="14ptband03" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband03-300x221.jpg" width="300" height="221" /></a><br />
탱크 제어는 Attiny2313을 사용한다.<br />
가. MPU : Attiny2313<br />
나. 주모터 제어 : L293B(정역 회전용 2set)<br />
다. 포탑 모터 : LB1630(정역 회전용 1set)<br />
라. 포신 모터 : ULN2803(1/8)<br />
마. 포 발사 모터 : ULN2803(1/8)<br />
바. 전조등 : ULN2803(1/8)<br />
사. 후미등 : ULN2803(1/8)</p>
<p><strong><span style="color: #33cccc">4. 탱크 제어부 통신 모듈</span></strong><br />
탱크 제어부와 안드로이드 폰 연결은 bluetooth모듈을 사용하였다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband04.jpg" rel="lightbox[2049]"><img class="alignnone size-medium wp-image-2072" alt="14ptband04" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband04-300x161.jpg" width="300" height="161" /></a></p>
<p><a href="http://www.devicemart.co.kr/goods/view.php?seq=15592" target="_blank">my Bluetooth-EX 모듈 구입하러 가기</a></p>
<p><strong><span style="color: #33cccc">5. 안드로이드 프로그램</span></strong><br />
<span style="color: #666699"><strong>Program : android측</strong></span><br />
<span style="color: #666699"><strong> tankControl.java</strong></span></p>
<div class="symple-toggle"><h3 class="symple-toggle-trigger">tankControl.java 소스보기</h3><div class="symple-toggle-container">
<p>package kr.sunejune;</p>
<p>import android.R;<br />
import android.app.Activity;<br />
import android.bluetooth.BluetoothAdapter;<br />
import android.bluetooth.BluetoothDevice;<br />
import android.content.Intent;<br />
import android.os.Bundle;<br />
import android.os.Handler;<br />
import android.os.Message;<br />
import android.util.Log;<br />
import android.view.Gravity;<br />
import android.view.Menu;<br />
import android.view.MenuInflater;<br />
import android.view.MenuItem;<br />
import android.view.View;<br />
import android.view.ViewGroup;<br />
import android.widget.Button;<br />
import android.widget.TextView;<br />
import android.widget.Toast;<br />
import android.view.View.OnClickListener;</p>
<p>public class TankControl extends Activity implements OnClickListener {</p>
<p>private static final String TAG = &#8220;TankControl&#8221;;<br />
private static final boolean D = false;</p>
<p>// Message types sent from the BluetoothChartService Handler<br />
public static final int MESSAGE_STATE_CHANGE = 1;<br />
public static final int MESSAGE_READ = 2;<br />
public static final int MESSAGE_DEVICE_NAME = 4;<br />
public static final int MESSAGE_TOAST = 5;</p>
<p>// Key names received from the BluetoothChartService Handler<br />
public static final String DEVICE_NAME = &#8220;device_name&#8221;;<br />
public static final String TOAST = &#8220;toast&#8221;;</p>
<p>// Name of the connected device<br />
private String mConnectedDeviceName = null;</p>
<p>// Intent request codes<br />
private static final int REQUEST_CONNECT_DEVICE = 1;<br />
private static final int REQUEST_ENABLE_BT = 2;</p>
<p>// Local Bletooth adapetr<br />
private BluetoothAdapter mBluetoothAdapter = null;<br />
// Member object for the chat services<br />
private SvrServer mSvcServer = null;</p>
<p>private TextView mStatus;</p>
<p>finish();<br />
/*<br />
// Called when the activity is first created.<br />
static final int[] BUTTONS = {<br />
R.id.ball,<br />
R.id.turrent_left,<br />
R.id.turrent_stop,<br />
R.id.turrent_right,<br />
R.id.f_center,<br />
R.id.f_left,<br />
R.id.f_right,<br />
R.id.t_center,<br />
R.id.t_left,<br />
R.id.t_right,<br />
R.id.c_center,<br />
R.id.c_left,<br />
R.id.c_right,<br />
R.id.gun_up,<br />
R.id.gun_dn,<br />
R.id.gun_stop<br />
};<br />
*/<br />
int ball_f = 0;<br />
TextView _out1 = null;<br />
TextView _out2 = null;<br />
TextView _out3 = null;</p>
<p>@Override<br />
public void onCreate(Bundle savedInstanceState) {</p>
<p>// TODO Auto-generated method stub<br />
super.onCreate(savedInstanceState);<br />
setContentView(R.layout.tankcontrol);<br />
setOnClickListener((ViewGroup)findViewById(R.id.tblButtons));</p>
<p>mStatus = (TextView)findViewById(R.id.txtStatus);</p>
<p>mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();</p>
<p>if( mBluetoothAdapter == null){<br />
Toast.makeText(this, &#8220;Bluetooth is not available&#8221;, Toast.LENGTH_SHORT).show();<br />
finish();<br />
return;<br />
}</p>
<p>_out1 = (TextView)findViewById(R.id.text1);<br />
_out2 = (TextView)findViewById(R.id.text2);<br />
_out3 = (TextView)findViewById(R.id.text3);</p>
<p>_out1.setText(&#8220;Hello&#8221;);<br />
_out1.setBackgroundColor(0xFFFFFF00);<br />
_out1.setGravity(Gravity.CENTER);</p>
<p>_out2.setText(&#8220;멈춤&#8221;);<br />
_out2.setBackgroundColor(0xFFFF00FF);<br />
_out2.setGravity(Gravity.CENTER);</p>
<p>_out3.setText(&#8220;멈춤&#8221;);<br />
_out3.setBackgroundColor(0xFF00FFFF);<br />
_out3.setGravity(Gravity.CENTER);</p>
<p>}</p>
<p>@Override<br />
protected void onStart() {<br />
// TODO Auto-generated method stub<br />
super.onStart();<br />
/*<br />
if(D) Log.e(TAG,&#8221;++ ON START ++&#8221;);</p>
<p>if( !mBluetoothAdapter.isEnabled() ) {<br />
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);<br />
startActivityForResult(enableIntent, REQUEST_ENABLE_BT );<br />
}<br />
else {<br />
if(mSvcServer == null) {<br />
mSvcServer = new SvrServer(this, mHandler);<br />
}<br />
}<br />
*/<br />
}</p>
<p>@Override<br />
public boolean onCreateOptionsMenu(Menu menu) {<br />
MenuInflater inflater = getMenuInflater();<br />
inflater.inflate(R.menu.option_menu, menu);<br />
return true;<br />
}<br />
@Override<br />
public boolean onOptionsItemSelected(MenuItem item) {<br />
switch(item.getItemId()){<br />
case R.id.scan :<br />
/*<br />
Intent serverIntent = new Intent(this, DeviceListActivity.class);<br />
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);<br />
*/</p>
<p>Intent serverIntent = new Intent(this, DeviceListActivity.class);<br />
startActivityForResult(serverIntent , REQUEST_CONNECT_DEVICE);<br />
return true;<br />
}<br />
return false;<br />
}<br />
@Override<br />
protected void onActivityResult(int requestCode, int resultCode, Intent data) {<br />
if(D) Log.d(TAG,&#8221;onActivityResult&#8221;+resultCode);</p>
<p>switch(requestCode){<br />
case REQUEST_CONNECT_DEVICE :<br />
if(resultCode == Activity.RESULT_OK){<br />
String address = data.getExtras().getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);<br />
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);<br />
mSvcServer.connect(device);<br />
}<br />
break;<br />
case REQUEST_ENABLE_BT :<br />
if(resultCode == Activity.RESULT_OK){<br />
if(mSvcServer == null) {<br />
mSvcServer = new SvrServer(this, mHandler);<br />
}<br />
}<br />
else {<br />
Log.d(TAG,&#8221;BT not enable&#8221;);<br />
Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();<br />
finish();<br />
}<br />
break;<br />
}<br />
}</p>
<p>public void onInit(int status) {<br />
if(D) Log.d(TAG, &#8220;onInit&#8221;);<br />
}</p>
<p>private View[] getChildViews(ViewGroup group){<br />
int childCount = group.getChildCount();<br />
final View[] childViews = new View[childCount];<br />
for(int index = 0; index &lt; childCount; index++) {<br />
childViews[index] = group.getChildAt(index);<br />
}<br />
return childViews;<br />
}</p>
<p>private void setOnClickListener(ViewGroup group){<br />
View[] childViews = getChildViews(group);<br />
for(View view:childViews){<br />
if(view instanceof Button) {<br />
view.setOnClickListener(this);<br />
}<br />
else if(view instanceof ViewGroup) {<br />
setOnClickListener((ViewGroup) view);<br />
}<br />
}<br />
}</p>
<p>private int sendToQue(String data){<br />
if(mSvcServer.getState() != SvrServer.STATE_CONNECTED) {<br />
Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();<br />
return -1;<br />
}<br />
return mSvcServer.toQue(data);<br />
}</p>
<p>private final Handler mHandler = new Handler() {<br />
@Override<br />
public void handleMessage(Message msg) {<br />
switch (msg.what) {<br />
case MESSAGE_STATE_CHANGE:<br />
if (D)<br />
Log.i(TAG, &#8220;MESSAGE_STATE_CHANGE: &#8221; + msg.arg1);<br />
switch (msg.arg1) {<br />
case SvrServer.STATE_CONNECTED:<br />
mStatus.setText(R.string.status_connected_to);<br />
mStatus.append(mConnectedDeviceName);<br />
break;<br />
case SvrServer.STATE_CONNECTING:<br />
mStatus.setText(R.string.status_connecting);<br />
break;<br />
case SvrServer.STATE_LISTEN:<br />
case SvrServer.STATE_NONE:<br />
mStatus.setText(R.string.status_not_connected);<br />
break;<br />
}<br />
break;<br />
// TODO: remove MESSAGE_READ<br />
case MESSAGE_READ:<br />
byte[] readBuf = (byte[]) msg.obj;<br />
// construct a string from the valid bytes in the buffer<br />
String readMessage = new String(readBuf, 0, msg.arg1);<br />
// mConversationArrayAdapter.add(mConnectedDeviceName+&#8221;: &#8221; +<br />
// readMessage);<br />
break;<br />
case MESSAGE_DEVICE_NAME:<br />
// save the connected device&#8217;s name<br />
mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);<br />
Toast.makeText(getApplicationContext(),<br />
&#8220;Connected to &#8221; + mConnectedDeviceName,<br />
Toast.LENGTH_SHORT).show();<br />
break;<br />
case MESSAGE_TOAST:<br />
Toast.makeText(getApplicationContext(),<br />
msg.getData().getString(TOAST), Toast.LENGTH_SHORT)<br />
.show();<br />
break;<br />
}<br />
}<br />
};</p>
<p>public void gun_text()<br />
{<br />
Button b_up = (Button)findViewById(R.id.gun_up);<br />
Button b_dn = (Button)findViewById(R.id.gun_dn);<br />
Button b_st = (Button)findViewById(R.id.gun_stop);<br />
b_up.setText(&#8220;포신 UP&#8221;);<br />
b_dn.setText(&#8220;포신 DN&#8221;);<br />
b_st.setText(&#8220;포멈춤&#8221;);<br />
}</p>
<p>public void turrent_text()<br />
{<br />
Button b_up = (Button)findViewById(R.id.turrent_left);<br />
Button b_dn = (Button)findViewById(R.id.turrent_right);<br />
Button b_st = (Button)findViewById(R.id.turrent_stop);<br />
b_up.setText(&#8220;포탑_좌&#8221;);<br />
b_dn.setText(&#8220;포탑_우&#8221;);<br />
b_st.setText(&#8220;포탑멈춤&#8221;);<br />
}<br />
public void move_text()<br />
{<br />
Button b1_1 = (Button)findViewById(R.id.f_left);<br />
Button b1_2 = (Button)findViewById(R.id.f_center);<br />
Button b1_3 = (Button)findViewById(R.id.f_right);<br />
b1_1.setText(&#8220;전_좌&#8221;);<br />
b1_2.setText(&#8220;전_전&#8221;);<br />
b1_3.setText(&#8220;전_우&#8221;);<br />
Button b2_1 = (Button)findViewById(R.id.c_left);<br />
Button b2_2 = (Button)findViewById(R.id.c_center);<br />
Button b2_3 = (Button)findViewById(R.id.c_right);<br />
b2_1.setText(&#8220;좌_좌&#8221;);<br />
b2_2.setText(&#8220;멈춤&#8221;);<br />
b2_3.setText(&#8220;우_우&#8221;);<br />
Button b3_1 = (Button)findViewById(R.id.t_left);<br />
Button b3_2 = (Button)findViewById(R.id.t_center);<br />
Button b3_3 = (Button)findViewById(R.id.t_right);<br />
b3_1.setText(&#8220;후_좌&#8221;);<br />
b3_2.setText(&#8220;후_후&#8221;);<br />
b3_3.setText(&#8220;후_우&#8221;);<br />
}</p>
<p>@Override<br />
public void onClick(View v){<br />
if(v instanceof Button) {<br />
int btn_id = v.getId();<br />
Button btn = (Button)findViewById( btn_id );<br />
switch ( btn_id ) {<br />
case R.id.ball :<br />
if( ball_f == 0 ) {<br />
if(sendToQue(&#8220;A&#8221;)==0) {<br />
btn.setText(&#8220;발사중(A)&#8221;);<br />
_out1.setText(&#8220;포 발사&#8221;);<br />
ball_f = 1;<br />
}<br />
}<br />
else {<br />
sendToQue(&#8220;B&#8221;);<br />
btn.setText(&#8220;발사대기(B)&#8221;);<br />
_out1.setText(&#8220;Hello&#8221;);<br />
ball_f = 0;<br />
}<br />
break;<br />
case R.id.gun_up :<br />
if(sendToQue(&#8220;C&#8221;) == 0) {<br />
gun_text();<br />
btn.setText(&#8220;..ing(C)&#8221;);<br />
_out1.setText(&#8220;포신 UP&#8221;);<br />
}<br />
break;<br />
case R.id.gun_dn :<br />
if(sendToQue(&#8220;E&#8221;) == 0) {<br />
gun_text();<br />
btn.setText(&#8220;..ing(E)&#8221;);<br />
_out1.setText(&#8220;포신 DOWN&#8221;);<br />
}<br />
break;<br />
case R.id.gun_stop :<br />
if(sendToQue(&#8220;D&#8221;) == 0) {<br />
gun_text();<br />
btn.setText(&#8220;STOP(D)&#8221;);<br />
_out1.setText(&#8220;포신 STOP&#8221;);<br />
}<br />
break;<br />
case R.id.turrent_left :<br />
if(sendToQue(&#8220;F&#8221;) == 0) {<br />
turrent_text();<br />
btn.setText(&#8220;..ing(F)&#8221;);<br />
_out2.setText(&#8220;좌&#8221;);<br />
}<br />
break;<br />
case R.id.turrent_right :<br />
if(sendToQue(&#8220;H&#8221;) == 0) {<br />
turrent_text();<br />
btn.setText(&#8220;..ing(H)&#8221;);<br />
_out2.setText(&#8220;우&#8221;);<br />
}<br />
break;<br />
case R.id.turrent_stop :<br />
if(sendToQue(&#8220;G&#8221;) == 0) {<br />
turrent_text();<br />
btn.setText(&#8220;STOP(G)&#8221;);<br />
_out2.setText(&#8220;멈춤&#8221;);<br />
}<br />
break;<br />
case R.id.f_left :<br />
if(sendToQue(&#8220;I&#8221;) == 0) {<br />
move_text();<br />
btn.setText(&#8220;..ing(I)&#8221;);<br />
_out3.setText(&#8220;전_좌 &#8220;);<br />
}<br />
break;<br />
case R.id.f_center :<br />
if(sendToQue(&#8220;J&#8221;) == 0) {<br />
move_text();<br />
btn.setText(&#8220;..ing(J)&#8221;);<br />
_out3.setText(&#8220;전_전 &#8220;);<br />
}<br />
break;<br />
case R.id.f_right :<br />
if(sendToQue(&#8220;K&#8221;) == 0) {<br />
move_text();<br />
btn.setText(&#8220;..ing(K)&#8221;);<br />
_out3.setText(&#8220;전_우 &#8220;);<br />
}<br />
break;<br />
case R.id.c_left :<br />
if(sendToQue(&#8220;L&#8221;) == 0) {<br />
move_text();<br />
btn.setText(&#8220;..ing(L)&#8221;);<br />
_out3.setText(&#8220;좌_좌 &#8220;);<br />
}<br />
break;<br />
case R.id.c_center :<br />
if(sendToQue(&#8220;M&#8221;) == 0) {<br />
move_text();<br />
btn.setText(&#8220;STOP(M)&#8221;);<br />
_out3.setText(&#8220;멈춤&#8221;);<br />
}<br />
break;<br />
case R.id.c_right :<br />
if(sendToQue(&#8220;N&#8221;) == 0) {<br />
move_text();<br />
btn.setText(&#8220;..ing(N)&#8221;);<br />
_out3.setText(&#8220;우_우 &#8220;);<br />
}<br />
break;<br />
case R.id.t_left :<br />
if(sendToQue(&#8220;O&#8221;) == 0) {<br />
move_text();<br />
btn.setText(&#8220;..ing(O)&#8221;);<br />
_out3.setText(&#8220;후_좌 &#8220;);<br />
}<br />
break;<br />
case R.id.t_center :<br />
if(sendToQue(&#8220;P&#8221;) == 0) {<br />
move_text();<br />
btn.setText(&#8220;..ing(P)&#8221;);<br />
_out3.setText(&#8220;후_후&#8221;);<br />
}<br />
break;<br />
case R.id.t_right :<br />
if(sendToQue(&#8220;Q&#8221;) == 0) {<br />
move_text();<br />
btn.setText(&#8220;..ing(Q)&#8221;);<br />
_out3.setText(&#8220;후_우 &#8220;);<br />
}<br />
break;<br />
}<br />
}<br />
}</p>
<p>}<br />
</div></div>
<p><strong><span style="color: #666699">Program : android측</span></strong><br />
<strong><span style="color: #666699">SvrServer.java</span></strong></p>
<div class="symple-toggle"><h3 class="symple-toggle-trigger">SvrServer.java 소스보기</h3><div class="symple-toggle-container">
<p>package kr.sunejune;</p>
<p>import java.util.UUID;<br />
import java.io.IOException;<br />
import java.io.InputStream;<br />
import java.io.OutputStream;</p>
<p>import android.bluetooth.BluetoothAdapter;<br />
import android.bluetooth.BluetoothDevice;<br />
import android.bluetooth.BluetoothServerSocket;<br />
import android.bluetooth.BluetoothSocket;<br />
import android.content.Context;<br />
import android.os.Handler;<br />
import android.os.Bundle;<br />
import android.os.Message;<br />
import android.util.Log;</p>
<p>public class SvrServer {<br />
// Debug<br />
private static final String TAG = &#8220;SvrServer&#8221;;<br />
private static final boolean D = false;</p>
<p>// Name for the SDP record when creating server socket<br />
private static final String NAME =&#8221;TankCon&#8221;;</p>
<p>// Generic UUID for SPP<br />
private static final UUID MY_UUID = UUID.fromString(&#8220;00001101-0000-1000-8000-00805F9B34FB&#8221;);</p>
<p>private final BluetoothAdapter mAdapter;<br />
private final Handler mHandler;<br />
private AcceptThread mAccepThread;<br />
private ConnectThread mConnectThread;<br />
private ConnectedThread mConnectedThread;<br />
private int mState;</p>
<p>// Constants that indicate the current connection state<br />
public static final int STATE_NONE = 0;<br />
public static final int STATE_LISTEN = 1;<br />
public static final int STATE_CONNECTING = 2;<br />
public static final int STATE_CONNECTED = 3;</p>
<p>public SvrServer(Context context, Handler handler) {<br />
mAdapter = BluetoothAdapter.getDefaultAdapter();<br />
mState = STATE_NONE;<br />
mHandler = handler;<br />
}</p>
<p>private synchronized void setState(int state) {<br />
if( D ) Log.d(TAG, &#8220;setState()&#8221;+mState+&#8221;==&gt;&#8221;+state);<br />
mState = state;</p>
<p>mHandler.obtainMessage(TankControl.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();<br />
}</p>
<p>public synchronized int getState() {<br />
return mState;<br />
}</p>
<p>public synchronized void start() {<br />
if(D) Log.d(TAG, &#8220;start&#8221; );<br />
if(mConnectThread != null) { mConnectThread.cancel(); mConnectThread = null; }<br />
if(mConnectedThread != null) { mConnectedThread.cancel(); mConnectedThread = null; }<br />
if(mAccepThread == null) { mAccepThread = new AcceptThread(); mAccepThread.start(); }<br />
setState(STATE_LISTEN);<br />
}</p>
<p>public synchronized void connect(BluetoothDevice device){<br />
if(D) Log.d(TAG,&#8221;connect to:&#8221; + device);</p>
<p>if(mState == STATE_CONNECTING) {<br />
if(mConnectThread != null) { mConnectThread.cancel(); mConnectThread = null; }<br />
}</p>
<p>if(mConnectedThread != null) { mConnectedThread.cancel(); mConnectedThread = null; }</p>
<p>mConnectThread = new ConnectThread(device);<br />
mConnectThread.start();<br />
setState(STATE_CONNECTING);<br />
}</p>
<p>public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {<br />
if(D) Log.d(TAG, &#8220;connected&#8221;);</p>
<p>if(mConnectThread != null) { mConnectThread.cancel(); mConnectThread = null; }<br />
if(mConnectedThread != null) { mConnectedThread.cancel(); mConnectThread = null; }<br />
if(mAccepThread != null) { mAccepThread.cancel(); mAccepThread = null; }</p>
<p>mConnectedThread = new ConnectedThread(socket);<br />
mConnectedThread.start();</p>
<p>Message msg = mHandler.obtainMessage( TankControl.MESSAGE_DEVICE_NAME );<br />
Bundle bundle = new Bundle();<br />
bundle.putString( TankControl.DEVICE_NAME, device.getName() );<br />
msg.setData(bundle);<br />
mHandler.sendMessage(msg);</p>
<p>setState(STATE_CONNECTED);</p>
<p>}</p>
<p>public synchronized void stop() {<br />
if(D) Log.d(TAG,&#8221;stop&#8221;);<br />
if(mConnectThread != null) { mConnectThread.cancel(); mConnectThread = null; }<br />
if(mConnectedThread != null) { mConnectedThread.cancel(); mConnectedThread = null; }<br />
if(mAccepThread != null) { mAccepThread.cancel(); mAccepThread = null; }<br />
setState(STATE_NONE);<br />
}</p>
<p>public int toQue(String data) {<br />
ConnectedThread r; // temp<br />
synchronized(this) {<br />
if(mState != STATE_CONNECTED ) return -1;<br />
r = mConnectedThread;<br />
}<br />
return r.toQue(data);<br />
}</p>
<p>private void connectionFail() {<br />
if(D) Log.d(TAG,&#8221;connectionFail&#8221;);<br />
setState(STATE_LISTEN);</p>
<p>Message msg = mHandler.obtainMessage( TankControl.MESSAGE_TOAST );<br />
Bundle bundle = new Bundle();<br />
bundle.putString(TankControl.TOAST, &#8220;Unable to connect device&#8221;);<br />
msg.setData(bundle);<br />
mHandler.sendMessage(msg);<br />
}</p>
<p>private void connectionLost() {<br />
if(D) Log.d(TAG, &#8220;connectionLost&#8221;);<br />
setState(STATE_LISTEN);</p>
<p>Message msg = mHandler.obtainMessage(TankControl.MESSAGE_TOAST);<br />
Bundle bundle = new Bundle();<br />
bundle.putString(TankControl.TOAST, &#8220;Device connection was lost&#8221;);<br />
msg.setData(bundle);<br />
mHandler.sendMessage(msg);<br />
}<br />
private class AcceptThread extends Thread {<br />
private final BluetoothServerSocket mmServerSocket;</p>
<p>public AcceptThread() {<br />
BluetoothServerSocket tmp = null;</p>
<p>try {<br />
tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);<br />
} catch ( IOException e ) {<br />
Log.e(TAG, &#8220;listen() failed&#8221;, e);<br />
}<br />
mmServerSocket = tmp;<br />
}</p>
<p>@Override<br />
public void run() {<br />
if(D) Log.d(TAG, &#8220;BEGIN mAcceptThread&#8221;+this);<br />
setName(&#8220;AcceptThread&#8221;);<br />
BluetoothSocket socket = null;</p>
<p>while( mState != STATE_CONNECTED ) {<br />
try {<br />
socket = mmServerSocket.accept();<br />
} catch (IOException e) {<br />
Log.e(TAG, &#8220;accept() failed&#8221;, e);<br />
break;<br />
}</p>
<p>if(socket != null) {<br />
synchronized ( SvrServer.this ) {<br />
switch(mState) {<br />
case STATE_LISTEN :<br />
case STATE_CONNECTING :<br />
connected(socket, socket.getRemoteDevice());<br />
break;<br />
case STATE_NONE :<br />
case STATE_CONNECTED :<br />
try {<br />
socket.close();<br />
}catch (IOException e) {<br />
Log.e(TAG,&#8221;Could not close unwanted socket&#8221;, e);<br />
}<br />
break;<br />
}<br />
}<br />
}<br />
}<br />
if(D) Log.d(TAG,&#8221;END mAcceptThread&#8221;);<br />
}</p>
<p>public void cancel() {<br />
if(D) Log.d(TAG,&#8221;cancel&#8221;+this);<br />
try {<br />
mmServerSocket.close();<br />
}catch(IOException e) {<br />
Log.e(TAG,&#8221;close() of server failed&#8221;,e);<br />
}<br />
}<br />
}</p>
<p>private class ConnectThread extends Thread {<br />
private final BluetoothSocket mmSocket;<br />
private final BluetoothDevice mmDevice;</p>
<p>public ConnectThread(BluetoothDevice device) {<br />
mmDevice = device;<br />
BluetoothSocket tmp = null;</p>
<p>try {<br />
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);<br />
}catch(IOException e) {<br />
Log.e(TAG,&#8221;create() failed&#8221;, e);<br />
}<br />
mmSocket = tmp;<br />
}</p>
<p>@Override<br />
public void run() {<br />
Log.i(TAG,&#8221;BEGIN ConnectThrtead&#8221;);<br />
setName(&#8220;ConnectThread&#8221;);</p>
<p>mAdapter.cancelDiscovery();</p>
<p>try{<br />
mmSocket.connect();<br />
}catch(IOException e1) {<br />
connectionFail();<br />
try {<br />
mmSocket.close();<br />
}catch (IOException e2) {<br />
Log.e(TAG,&#8221;unable to close() socket during connection failure&#8221;, e2);<br />
}<br />
SvrServer.this.start();<br />
return;<br />
}</p>
<p>synchronized ( SvrServer.this ) {<br />
mConnectThread = null;<br />
}</p>
<p>connected(mmSocket, mmDevice );<br />
}</p>
<p>public void cancel() {<br />
try {<br />
mmSocket.close();<br />
}catch(IOException e) {<br />
Log.e(TAG,&#8221;close() of connect socket failed&#8221;, e);<br />
}<br />
}<br />
}</p>
<p>private class ConnectedThread extends Thread {<br />
private final BluetoothSocket mmSocket;<br />
private final InputStream mmInStream;<br />
private final OutputStream mmOutStream;</p>
<p>public ConnectedThread(BluetoothSocket socket) {<br />
Log.d(TAG, &#8220;create ConnectedThread&#8221;);<br />
mmSocket = socket;<br />
InputStream tmpIn = null;<br />
OutputStream tmpOut = null;</p>
<p>// Get the BluetoothSocket input and output streams<br />
try {<br />
tmpIn = socket.getInputStream();<br />
tmpOut = socket.getOutputStream();<br />
} catch (IOException e) {<br />
Log.e(TAG, &#8220;temp sockets not created&#8221;, e);<br />
}</p>
<p>mmInStream = tmpIn;<br />
mmOutStream = tmpOut;<br />
}</p>
<p>@Override<br />
public void run() {<br />
Log.i(TAG, &#8220;BEGIN mConnectedThread&#8221;);<br />
byte[] buffer = new byte[1024];<br />
int bytes;</p>
<p>// Keep listening to the InputStream while connected<br />
while (true) {<br />
try {<br />
// Read from the InputStream<br />
// TODO: add dogkick!!<br />
bytes = mmInStream.read(buffer);</p>
<p>// Send the obtained bytes to the UI Activity<br />
mHandler.obtainMessage(TankControl.MESSAGE_READ, bytes, -1, buffer).sendToTarget();<br />
} catch (IOException e) {<br />
Log.e(TAG, &#8220;disconnected&#8221;, e);<br />
connectionLost();<br />
break;<br />
}<br />
}<br />
}</p>
<p>public int toQue(String in_data) {<br />
int ret = 0;<br />
try {<br />
String data = in_data;<br />
/*<br />
if (0 &lt; left) data += &#8216;F&#8217;;<br />
else if (0 &gt; left) {data += &#8216;B&#8217;; left = -left;}<br />
else data +=&#8217;H';<br />
if (0 &lt; right) data += &#8216;F&#8217;;<br />
else if (0 &gt; right) {data += &#8216;B&#8217;; right = -right;}<br />
else data +=&#8217;H';</p>
<p>if (left != 0) data += (char)(left&amp;0xff);<br />
if (right != 0) data += (char)(right&amp;0xff);<br />
*/<br />
mmOutStream.write(data.getBytes());<br />
ret = 0;<br />
} catch (IOException e) {<br />
Log.e(TAG, &#8220;Exception during write&#8221;, e);<br />
ret = -1;<br />
}<br />
return ret;<br />
}</p>
<p>public void cancel() {<br />
try {<br />
mmSocket.close();<br />
} catch (IOException e) {<br />
Log.e(TAG, &#8220;close() of connect socket failed&#8221;, e);<br />
}<br />
}</p>
<p>}</p>
<p>}<br />
</div></div>
<p><span style="color: #666699"><strong>Program : android측</strong></span><br />
<span style="color: #666699"><strong>DeviceListActivity.java</strong></span></p>
<div class="symple-toggle"><h3 class="symple-toggle-trigger">DeviceListActivity.java 소스보기</h3><div class="symple-toggle-container">
<p>/*</p>
<p>* Copyright (C) 2009 The Android Open Source Project<br />
*<br />
* Licensed under the Apache License, Version 2.0 (the &#8220;License&#8221;);<br />
* you may not use this file except in compliance with the License.<br />
* You may obtain a copy of the License at<br />
*<br />
* http://www.apache.org/licenses/LICENSE-2.0<br />
*<br />
* Unless required by applicable law or agreed to in writing, software<br />
* distributed under the License is distributed on an &#8220;AS IS&#8221; BASIS,<br />
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<br />
* See the License for the specific language governing permissions and<br />
* limitations under the License.<br />
*/</p>
<p>package kr.sunejune;</p>
<p>import java.util.Set;</p>
<p>import android.app.Activity;<br />
import android.bluetooth.BluetoothAdapter;<br />
import android.bluetooth.BluetoothDevice;<br />
import android.content.BroadcastReceiver;<br />
import android.content.Context;<br />
import android.content.Intent;<br />
import android.content.IntentFilter;<br />
import android.os.Bundle;<br />
import android.util.Log;<br />
import android.view.View;<br />
import android.view.Window;<br />
import android.view.View.OnClickListener;<br />
import android.widget.AdapterView;<br />
import android.widget.ArrayAdapter;<br />
import android.widget.Button;<br />
import android.widget.ListView;<br />
import android.widget.TextView;<br />
import android.widget.AdapterView.OnItemClickListener;</p>
<p>/**<br />
* This Activity appears as a dialog. It lists any paired devices and<br />
* devices detected in the area after discovery. When a device is chosen<br />
* by the user, the MAC address of the device is sent back to the parent<br />
* Activity in the result Intent.<br />
*/<br />
public class DeviceListActivity extends Activity {<br />
// Debugging<br />
private static final String TAG = &#8220;DeviceListActivity&#8221;;<br />
private static final boolean D = false;</p>
<p>// Return Intent extra<br />
public static String EXTRA_DEVICE_ADDRESS = &#8220;device_address&#8221;;</p>
<p>// Member fields<br />
private BluetoothAdapter mBtAdapter;<br />
private ArrayAdapter&lt;String&gt; mPairedDevicesArrayAdapter;<br />
private ArrayAdapter&lt;String&gt; mNewDevicesArrayAdapter;</p>
<p>@Override<br />
protected void onCreate(Bundle savedInstanceState) {<br />
super.onCreate(savedInstanceState);</p>
<p>// Setup the window<br />
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);<br />
setContentView(R.layout.device_list);</p>
<p>// Set result CANCELED incase the user backs out<br />
setResult(Activity.RESULT_CANCELED);</p>
<p>// Initialize the button to perform device discovery<br />
Button scanButton = (Button) findViewById(R.id.button_scan);<br />
scanButton.setOnClickListener(new OnClickListener() {<br />
public void onClick(View v) {<br />
doDiscovery();<br />
v.setVisibility(View.GONE);<br />
}<br />
});</p>
<p>// Initialize array adapters. One for already paired devices and<br />
// one for newly discovered devices<br />
mPairedDevicesArrayAdapter = new ArrayAdapter&lt;String&gt;(this, R.layout.device_name);<br />
mNewDevicesArrayAdapter = new ArrayAdapter&lt;String&gt;(this, R.layout.device_name);</p>
<p>// Find and set up the ListView for paired devices<br />
ListView pairedListView = (ListView) findViewById(R.id.paired_devices);<br />
pairedListView.setAdapter(mPairedDevicesArrayAdapter);<br />
pairedListView.setOnItemClickListener(mDeviceClickListener);</p>
<p>// Find and set up the ListView for newly discovered devices<br />
ListView newDevicesListView = (ListView) findViewById(R.id.new_devices);<br />
newDevicesListView.setAdapter(mNewDevicesArrayAdapter);<br />
newDevicesListView.setOnItemClickListener(mDeviceClickListener);</p>
<p>// Register for broadcasts when a device is discovered<br />
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);<br />
this.registerReceiver(mReceiver, filter);</p>
<p>// Register for broadcasts when discovery has finished<br />
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);<br />
this.registerReceiver(mReceiver, filter);</p>
<p>// Get the local Bluetooth adapter<br />
mBtAdapter = BluetoothAdapter.getDefaultAdapter();</p>
<p>// Get a set of currently paired devices<br />
Set&lt;BluetoothDevice&gt; pairedDevices = mBtAdapter.getBondedDevices();</p>
<p>// If there are paired devices, add each one to the ArrayAdapter<br />
if (pairedDevices.size() &gt; 0) {<br />
findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);<br />
for (BluetoothDevice device : pairedDevices) {<br />
mPairedDevicesArrayAdapter.add(device.getName() + &#8220;\n&#8221; + device.getAddress());<br />
}<br />
} else {<br />
String noDevices = getResources().getText(R.string.none_paired).toString();<br />
mPairedDevicesArrayAdapter.add(noDevices);<br />
}<br />
}</p>
<p>@Override<br />
protected void onDestroy() {<br />
super.onDestroy();</p>
<p>// Make sure we&#8217;re not doing discovery anymore<br />
if (mBtAdapter != null) {<br />
mBtAdapter.cancelDiscovery();<br />
}</p>
<p>// Unregister broadcast listeners<br />
this.unregisterReceiver(mReceiver);<br />
}</p>
<p>/**<br />
* Start device discover with the BluetoothAdapter<br />
*/<br />
private void doDiscovery() {<br />
if (D) Log.d(TAG, &#8220;doDiscovery()&#8221;);</p>
<p>// Indicate scanning in the title<br />
setProgressBarIndeterminateVisibility(true);<br />
setTitle(R.string.scanning);</p>
<p>// Turn on sub-title for new devices<br />
findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);</p>
<p>// If we&#8217;re already discovering, stop it<br />
if (mBtAdapter.isDiscovering()) {<br />
mBtAdapter.cancelDiscovery();<br />
}</p>
<p>// Request discover from BluetoothAdapter<br />
mBtAdapter.startDiscovery();<br />
}</p>
<p>// The on-click listener for all devices in the ListViews<br />
private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {<br />
public void onItemClick(AdapterView&lt;?&gt; av, View v, int arg2, long arg3) {<br />
// Cancel discovery because it&#8217;s costly and we&#8217;re about to connect<br />
if (mBtAdapter.isDiscovering()) {<br />
mBtAdapter.cancelDiscovery();<br />
}</p>
<p>// Get the device MAC address, which is the last 17 chars in the View<br />
String info = ((TextView) v).getText().toString();<br />
String address = info.substring(info.length() &#8211; 17);</p>
<p>// Create the result Intent and include the MAC address<br />
Intent intent = new Intent();<br />
intent.putExtra(EXTRA_DEVICE_ADDRESS, address);</p>
<p>// Set result and finish this Activity<br />
setResult(Activity.RESULT_OK, intent);<br />
finish();<br />
}<br />
};</p>
<p>// The BroadcastReceiver that listens for discovered devices and<br />
// changes the title when discovery is finished<br />
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {<br />
@Override<br />
public void onReceive(Context context, Intent intent) {<br />
String action = intent.getAction();</p>
<p>// When discovery finds a device<br />
if (BluetoothDevice.ACTION_FOUND.equals(action)) {<br />
// Get the BluetoothDevice object from the Intent<br />
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);<br />
// If it&#8217;s already paired, skip it, because it&#8217;s been listed already<br />
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {<br />
mNewDevicesArrayAdapter.add(device.getName() + &#8220;\n&#8221; + device.getAddress());<br />
}<br />
// When discovery is finished, change the Activity title<br />
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {<br />
setProgressBarIndeterminateVisibility(false);<br />
setTitle(R.string.select_device);<br />
if (mNewDevicesArrayAdapter.getCount() == 0) {<br />
String noDevices = getResources().getText(R.string.none_found).toString();<br />
mNewDevicesArrayAdapter.add(noDevices);<br />
}<br />
}<br />
}<br />
};</p>
<p>}<br />
</div></div>
<p><strong><span style="color: #33cccc">6. AVR 프로그램</span></strong><br />
<strong><span style="color: #666699">Program : ATTINY2313측</span></strong></p>
<div class="symple-toggle"><h3 class="symple-toggle-trigger">Program : ATTINY2313측 소스보기</h3><div class="symple-toggle-container">
<p>/*</p>
<p><em id="__mceDel"> Project : USART TEST1<br />
tiny2313_uart1.c<br />
Date : 2008-05-23<br />
Company : AvrMall.com<br />
Chip type : ATtiny2313-10SI<br />
Clock : 12.000000 MHz<br />
Comment : ATTINY2313으로 UART송수신 테스트 프로그램<br />
Used with AVRSTUDIO V4.14 (WINAVR) .<br />
*/</em></p>
<p>#include &lt;avr/io.h&gt;</p>
<p>#define F_CPU 12000000UL // 16 MHz<br />
//#define F_CPU 14.7456E6<br />
//#include &lt;util/delay.h&gt;<br />
// Common Functions.<br />
void Delay_us(unsigned int time_us);<br />
void Delay_ms(unsigned int time_ms);</p>
<p>void USART_Init(void);<br />
void putchar_0(char data);<br />
void com_puts(char sbuf[]);<br />
void putchar_0(char data);<br />
int getchar_0(void);<br />
void cpu_setup(void);<br />
void Delay_us(unsigned int time_us)<br />
{<br />
unsigned int i;</p>
<p>for(i=0; i&lt;time_us; i++) // 4 cycle +<br />
{<br />
asm(&#8220;PUSH R0&#8243;); // 2 cycle +<br />
asm(&#8220;POP R0&#8243;); // 2 cycle +<br />
asm(&#8220;PUSH R0&#8243;); // 2 cycle +<br />
asm(&#8220;POP R0&#8243;); // 2 cycle + =12 cycle for 11.0592MHZ<br />
//asm(&#8220;PUSH R0&#8243;); // 2 cycle +<br />
//asm(&#8220;POP R0&#8243;); // 2 cycle = 16 cycle = 1us for 16MHz<br />
}<br />
}</p>
<p>void Delay_ms(unsigned int time_ms)<br />
{<br />
unsigned int i;</p>
<p>for(i=0; i&lt;time_ms;i++)<br />
Delay_us(1000);<br />
}<br />
void USART_Init(void)<br />
{<br />
// 9600Bps, 8Data, 1 Stop, No Parity<br />
UCSRA=0&#215;00;<br />
UCSRB=0&#215;18;<br />
UCSRC=0&#215;06;<br />
UBRRH=0&#215;00;<br />
UBRRL=0&#215;12;<br />
}<br />
// COM1 스트링 송신 //<br />
void com_puts(char sbuf[])<br />
{<br />
char ch;<br />
int i = 0;</p>
<p>ch = sbuf[i++]; // 전송할 데이터<br />
while(ch != 0){<br />
putchar_0(ch); // 1바이트 송신<br />
ch = sbuf[i++]; // 전송할 데이터<br />
}<br />
}</p>
<p>void putchar_0(char data)<br />
{<br />
/* Wait for empty transmit buffer */<br />
while (!((UCSRA) &amp; (1&lt;&lt;UDRE)));</p>
<p>/* Put data into buffer, sends the data */<br />
UDR = data;<br />
}</p>
<p>int getchar_0(void)<br />
{<br />
/* Wait for data to be received */<br />
while ( !(UCSRA &amp; (1&lt;&lt;RXC)) );</p>
<p>/* Get and return received data from buffer */<br />
return(UDR);<br />
}</p>
<p>void cpu_setup(void)<br />
{<br />
USART_Init();//USART 초기화<br />
DDRB = 0b01111111; // Port B IO mode : b7 (Input), b6-b0(Output)<br />
DDRD &amp;= 0b01111100; // Port B IO mode : d0-1 (UART), b6-b2(Output)<br />
}<br />
int main(void)<br />
{<br />
unsigned char cmd;<br />
unsigned char i_h=0;<br />
unsigned char i_t=0;<br />
unsigned char i_f=0;<br />
unsigned char i_u=0;</p>
<p>cpu_setup(); // cpu 초기화</p>
<p>com_puts(&#8220;\r\n&#8221;);<br />
com_puts(&#8220;- ATTINY2313 USART TEST -\r\n&#8221;);<br />
com_puts(&#8220;Press a or b \r\n&#8221;);</p>
<p>while(1)<br />
{<br />
cmd = getchar_0();//PC로부터 받은 값을 d에 저장한다.</p>
<p>switch (cmd) {<br />
case &#8216;i&#8217; :<br />
PORTB = 0b00000000;<br />
break;</p>
<p>// 전조등(h:4) / 후미등(t:5) , off(o)<br />
case &#8216;h&#8217; :<br />
case &#8216;R&#8217; :<br />
if(i_h == 1) {<br />
PORTB &amp;= 0b11001111;<br />
i_h=0;<br />
}<br />
else {<br />
PORTB |= 0b00010000;<br />
i_h=1;<br />
}<br />
break;<br />
case &#8216;t&#8217; :<br />
case &#8216;S&#8217; :<br />
if(i_t == 0) {<br />
PORTB |= 0b00100000;<br />
i_t=1;<br />
}<br />
else {<br />
PORTB &amp;= 0b11001111;<br />
i_t=0;<br />
}<br />
break;</p>
<p>case &#8216;o&#8217; :<br />
case &#8216;T&#8217; :<br />
PORTB &amp;= 0b11001111;<br />
break;<br />
// 포탄 발사(f:3:A) off(w:B)<br />
case &#8216;f&#8217; :<br />
case &#8216;A&#8217; :<br />
if(i_f == 0) {<br />
PORTB |= 0b00001000;<br />
i_f=1;<br />
}<br />
else {<br />
PORTB &amp;= 0b11110111;<br />
i_f=0;<br />
}<br />
break;<br />
case &#8216;B&#8217; :<br />
case &#8216;q&#8217; :<br />
PORTB &amp;= 0b11110111;<br />
break;<br />
// 포신 동작(u:2) off(c)<br />
case &#8216;u&#8217; :<br />
case &#8216;C&#8217; :<br />
PORTB |= 0b00000100;<br />
i_u=1;<br />
break;<br />
case &#8216;E&#8217; :<br />
PORTB &amp;= 0b11111011;<br />
i_u=0;<br />
break;<br />
case &#8216;c&#8217; :<br />
case &#8216;D&#8217; :<br />
PORTB &amp;= 0b11111011;<br />
break;</p>
<p>// 포탑 좌(l:0) 우(r:1) , off(m)<br />
case &#8216;l&#8217; :<br />
case &#8216;F&#8217; :<br />
PORTB &amp;= 0b11111100;<br />
PORTB |= 0b00000001;<br />
break;<br />
case &#8216;r&#8217; :<br />
case &#8216;H&#8217; :<br />
PORTB &amp;= 0b11111100;<br />
PORTB |= 0b00000010;<br />
break;<br />
case &#8216;m&#8217; :<br />
case &#8216;G&#8217; :<br />
PORTB &amp;= 0b11111100;<br />
break;</p>
<p>// 이동 전진(w:2-1,3-0 , 4-1,5-0) 후진(x:2-0,3-1 , 4-0,5-1)<br />
// 전좌(a:2-0,3-0 , 4-1,5-0) 전우(d:2-1,3-0 , 4-0,5-0) ,<br />
// 후좌(a:2-0,3-1 , 4-0,5-0) 후우(d:2-0,3-0 , 4-1,5-0) ,<br />
// off(s)<br />
case &#8216;O&#8217; : // 후좌<br />
PORTD &amp;= 0b10000011;<br />
PORTD |= 0b01001000;<br />
break;<br />
case &#8216;Q&#8217; : // 후우<br />
PORTD &amp;= 0b10000011;<br />
PORTD |= 0b01010000;<br />
break;<br />
case &#8216;w&#8217; :<br />
case &#8216;J&#8217; : // 전_전<br />
PORTD &amp;= 0b10000011;<br />
PORTD |= 0b01010100;<br />
break;<br />
case &#8216;x&#8217; :<br />
case &#8216;P&#8217; : // 후_후<br />
PORTD &amp;= 0b10000011;<br />
PORTD |= 0b01101000;<br />
break;<br />
case &#8216;a&#8217; :<br />
case &#8216;I&#8217; : // 전_좌<br />
PORTD &amp;= 0b10000011;<br />
PORTD |= 0b01010000;<br />
break;<br />
case &#8216;d&#8217; :<br />
case &#8216;K&#8217; : // 전우<br />
PORTD &amp;= 0b10000011;<br />
PORTD |= 0b01000100;<br />
break;<br />
case &#8216;s&#8217; :<br />
case &#8216;M&#8217; : // 멈춤<br />
PORTD &amp;= 0b10000011;<br />
break;<br />
default :<br />
;<br />
// putchar_0(&#8216;c&#8217;);<br />
}<br />
Delay_ms(100);<br />
}<br />
}<br />
</div></div>
<p><strong><span style="color: #33cccc">7. 관련 회로도</span></strong></p>
<p><span style="color: #339966">7.1 전체 Block</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband06.jpg" rel="lightbox[2049]"><img class="alignnone size-medium wp-image-2074" alt="14ptband06" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband06-300x249.jpg" width="300" height="249" /></a><br />
<span style="color: #339966">7.2 ATTINY2313 Board V1.2 회로도</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband07.jpg" rel="lightbox[2049]"><img class="alignnone size-medium wp-image-2075" alt="14ptband07" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband07-300x224.jpg" width="300" height="224" /></a><br />
<span style="color: #339966">7.3 L293B : 전후진용 주 모터 (좌우, 정, 역 회전 : 양방향)</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband08.jpg" rel="lightbox[2049]"><img class="alignnone size-medium wp-image-2076" alt="14ptband08" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband08-300x95.jpg" width="300" height="95" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband09.jpg" rel="lightbox[2049]"><img class="alignnone size-medium wp-image-2077" alt="14ptband09" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband09-300x241.jpg" width="300" height="241" /></a><br />
<span style="color: #339966"> 7.4 LB1630 : 포탑 (정. 역 회전 : 양방향)</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband010.jpg" rel="lightbox[2049]"><img class="alignnone size-full wp-image-2078" alt="14ptband010" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband010.jpg" width="297" height="132" /></a><br />
<span style="color: #339966"> 7.5 ULN2803 : 포신, 포발사, 전조등, 후미등 (정회전:단방향)</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband011.jpg" rel="lightbox[2049]"><img class="alignnone size-full wp-image-2079" alt="14ptband011" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband011.jpg" width="231" height="205" /></a><br />
<span style="color: #339966"> 7.6 bluetooth : myBluetooh-EX 모듈</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband012.jpg" rel="lightbox[2049]"><img class="alignnone size-medium wp-image-2080" alt="14ptband012" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband012-300x100.jpg" width="300" height="100" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband013.jpg" rel="lightbox[2049]"><img class="alignnone size-medium wp-image-2081" alt="14ptband013" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband013-300x148.jpg" width="300" height="148" /></a><br />
<strong><span style="color: #33cccc">8. 완성</span></strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband05.jpg" rel="lightbox[2049]"><img class="alignnone size-medium wp-image-2073" alt="14ptband05" src="http://www.ntrexgo.com/wp-content/uploads/2013/03/14ptband05-300x114.jpg" width="300" height="114" /></a></p>
<p><strong><span style="color: #008000">소요비용</span></strong></p>
<p>탱크 : 75,000원<br />
Attiny2313 보드 : 11,000원<br />
제어 보드 제작 : 약 20,000원(손실까지)<br />
블루투스 모듈 : 26,300원<br />
전체 : 132,300원</p>
<p><strong><span style="color: #008000">참고 웹사이트</span></strong></p>
<p><strong>참고 Site</strong></p>
<p><a title="탱크조립보러가기" href="http://web.suapapa.net:8080/wordpress/?p=471" target="_blank">탱크 조립</a></p>
<p><a title="아두이노 모터 컨트롤 보드 만들기" href="http://web.suapapa.net:8080/wordpress/?p=473" target="_blank" rel="bookmark">아두이노 모터 컨트롤 보드 만들기</a></p>
<p><a title="아두이노+블루투스+안드로이드" href="http://web.suapapa.net:8080/wordpress/?p=474" target="_blank" rel="bookmark">아두이노+블루투스+안드로이드</a></p>
<p><a href="http://cafe.naver.com/carroty.cafe?iframe_url=/ArticleRead.nhn%3Fclubid=10750951%26page=1%26menuid=0%26inCafeSearch=true%26searchBy=1%26query=%C5%CA%C5%A9%26includeAll=%26exclude=%26include=%26exact=%26searchdate=all%26media=0%26sortBy=date%26articleid=130057%26referrerAllArticles=true" target="_blank"><strong>완성후 게시물</strong></a></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/2049/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
