<?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>诗意代码 - PoemCode</title>
	<atom:link href="http://www.poemcode.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.poemcode.net</link>
	<description>These codes, As beautiful as poetry!</description>
	<lastBuildDate>Mon, 14 May 2012 12:38:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>读CSAPP之PIPE原理和实现</title>
		<link>http://www.poemcode.net/2012/05/csapp-pipe/</link>
		<comments>http://www.poemcode.net/2012/05/csapp-pipe/#comments</comments>
		<pubDate>Mon, 14 May 2012 12:36:27 +0000</pubDate>
		<dc:creator>Xu Haojie</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[CSAPP]]></category>

		<guid isPermaLink="false">http://www.poemcode.net/?p=2772</guid>
		<description><![CDATA[<div class="wp-caption alignright" style="width: 80px"><img class="size-full wp-image-521" title="Computer System: A Programmer’s Perspective" src="http://www.poemcode.net/wp-content/uploads/2011/09/csapp.jpg" alt="Computer System: A Programmer’s Perspective" width="80" height="100" /></div> 

流水线化的目的就是每个时钟周期都发射一条指令，也就是说每个时钟周期都有一条新指令进入执行阶段，同时有一条旧指令退出执行流程。

流水线化会增加吞吐量（throughout），但同时也会增加一条指令从头到尾执行的全部时间，即延迟（latency），--延迟增加的原因是，多出来的流水线寄存器的时间开销。

流水线阶段之间的指令转移由时钟信号控制，并且时钟信号控制在每隔特定的时间间隔加载流水线寄存器。流水线寄存器采用时钟寄存器，其由时钟信号控制加载输入值，信号转播到流水线寄存器的输入，直到时钟上升时，才会改变寄存器的状态。用来保存程序计数器（PC）、条件代码（CC）和程序状态（Stat）等。]]></description>
			<content:encoded><![CDATA[<p><small>今年是离开校园的第六年，这六年来我一直在从事应用软件的设计、开发工作，大部分时间是在与高级编程语言、设计模式、业务逻辑打交道。它们大多流于表面，久而久之，与技术底层疏远了，诸如计算机组成原理、汇编语言、编译原理、数据结构以及算法慢慢得生疏，时至今日，向上碰到天花板，向下触到花岗岩。五年是一个契机，趁着下一个五年开始之际，我计划用三个月至半年时想间，重新学习这些知识，以期达到巩固基础，厚积薄发的目的。</p>
<p>本篇是我阅读《Computer System: A Programmer’s Perspective》一书的笔记，该书和与之搭配的《Professional Assembly Language》是我当下阅读计划的一部分。</small></p>
<p>我曾经不只三次翻阅第四章&#8211;处理器体系机构，然而至今未能完整读懂，其中的电子学和布尔代数小节，使我深深地为当年的逃课行为感到懊恼，&#8211;为此，我特意找了《数字电路简明教程》来补上这一课。下面这些文字，是我在半懂不懂的情况下，“断章取意”摘录的，只做自己的读书笔记。</p>
<h2>Pipelining 原理</h2>
<p>流水线化的目的就是每个时钟周期都发射一条指令，也就是说每个时钟周期都有一条新指令进入执行阶段，同时有一条旧指令退出执行流程。</p>
<p>流水线化会增加吞吐量（throughout），但同时也会增加一条指令从头到尾执行的全部时间，即延迟（latency），&#8211;延迟增加的原因是，多出来的流水线寄存器的时间开销。</p>
<p>流水线阶段之间的指令转移由时钟信号控制，并且时钟信号控制在每隔特定的时间间隔加载流水线寄存器。流水线寄存器采用时钟寄存器，其由时钟信号控制加载输入值，信号转播到流水线寄存器的输入，直到时钟上升时，才会改变寄存器的状态。用来保存程序计数器（PC）、条件代码（CC）和程序状态（Stat）等。</p>
<p>流水线的两个局限性表现为：</p>
<ol>
<li>如果流水线划分的阶段不一致，那么系统吞吐量将受到最慢阶段的速度所限制。</li>
<li>如果流水线划分阶段过多，则会增加寄存器的时间开销，收益反而会下降。</li>
</ol>
<p>相邻指令之间可能存在数据相关（data dependency）或者控制相关（control dependency），这时需要反馈路径来解决。</p>
<h2>Pipelining 实现</h2>
<p>将 SEQ 改造成 PIPE，需要完成两个修改：将 PC 的计算挪到取值阶段；在各个阶段之间加上流水线寄存器。PIPE 中没有硬件寄存器来存放程序计数器，而是根据从前一条指令保存下来的一些状态信息动态地计算 PC。这种对状态元素的改变称为重定时（retiming），其改变一个系统的状态表示，但并不改变它的逻辑行为，通常用来平衡一个系统中各个阶段之间的延迟。</p>
<p>流水线取出的指令如果是条件分支指令，或者是 ret，则需要等到几个时钟周期之后，才能确定选择分支，或者返回地址。分支预测就是猜测分支方向并根据猜测开始取值。</p>
<p>数据相关，下一条指令会用到这一条指令计算出的结果；控制相关，一条指令要确定下一条指令的位置，例如在执行跳转、调用或返回指令时。这些相关可能会导致流水线产生计算错误，称为冒险（hazard），可分为两类：数据冒险（data hazard）和控制冒险（control hazard）。<br />
暂停（stalling）是避免冒险的一种常用技术，暂停时，处理器会停止流水线中一条或多条指令，直到冒险条件不再满足，但它会允许其他指令继续通过流水线。每次要把一条指令阻塞在译码阶段，就在执行阶段插入一个“气泡”，其就像一个自动产生的 nop 指令，不改变寄存器、存储器、条件码或程序状态。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.poemcode.net/2012/05/csapp-pipe/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>读CSAPP之ISA、Circuit和SEQ</title>
		<link>http://www.poemcode.net/2012/04/csapp-isa-circuit-seq/</link>
		<comments>http://www.poemcode.net/2012/04/csapp-isa-circuit-seq/#comments</comments>
		<pubDate>Thu, 12 Apr 2012 14:29:28 +0000</pubDate>
		<dc:creator>Xu Haojie</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[CSAPP]]></category>

		<guid isPermaLink="false">http://www.poemcode.net/?p=2756</guid>
		<description><![CDATA[<div class="wp-caption alignright" style="width: 80px"><img class="size-full wp-image-521" title="Computer System: A Programmer’s Perspective" src="http://www.poemcode.net/wp-content/uploads/2011/09/csapp.jpg" alt="Computer System: A Programmer’s Perspective" width="80" height="100" /></div> 
我曾经不只三次翻阅第四章--处理器体系机构，然而至今未能完整读懂，其中的电子学和布尔代数小节，使我深深地为当年的逃课行为感到懊恼，--为此，我特意找了《数字电路简明教程》来补上这一课。下面这些文字，是我在半懂不懂的情况下，“断章取意”摘录的，只做自己的读书笔记。

<h2>ISA</h2>

指令集体系结构（Instrunction-Set Architecture, ISA）是指处理器所支持的指令和指令的字节级编码，其在编译器编写者和处理器设计者之间提供了一个概念抽象层。

每条指令由若干个字节组成，第一个字节包含了code部分（高四位）和function部分（低四位），不同指令的code部分可能相同，但code和function的二者组合则惟一标识一条指令，并根据其确定其他附加字节的长度和定义，处理器可以无二义性地执行目标代码程序。]]></description>
			<content:encoded><![CDATA[<p><small>今年是离开校园的第六年，这六年来我一直在从事应用软件的设计、开发工作，大部分时间是在与高级编程语言、设计模式、业务逻辑打交道。它们大多流于表面，久而久之，与技术底层疏远了，诸如计算机组成原理、汇编语言、编译原理、数据结构以及算法慢慢得生疏，时至今日，向上碰到天花板，向下触到花岗岩。五年是一个契机，趁着下一个五年开始之际，我计划用三个月至半年时想间，重新学习这些知识，以期达到巩固基础，厚积薄发的目的。</p>
<p>本篇是我阅读《Computer System: A Programmer’s Perspective》一书的笔记，该书和与之搭配的《Professional Assembly Language》是我当下阅读计划的一部分。</small></p>
<p>我曾经不止三次翻阅第四章&#8211;处理器体系机构，然而至今未能完整读懂，其中的电子学和布尔代数小节，使我深深地为当年的逃课行为感到懊恼，&#8211;为此，我特意找了《数字电路简明教程》来补上这一课。下面这些文字，是我在半懂不懂的情况下，“断章取意”摘录的，只做自己的读书笔记。</p>
<h2>ISA</h2>
<p>指令集体系结构（Instrunction-Set Architecture, ISA）是指处理器所支持的指令和指令的字节级编码，其在编译器编写者和处理器设计者之间提供了一个概念抽象层。</p>
<p>每条指令由若干个字节组成，第一个字节包含了code部分（高四位）和function部分（低四位），不同指令的code部分可能相同，但code和function的二者组合则惟一标识一条指令，并根据其确定其他附加字节的长度和定义，处理器可以无二义性地执行目标代码程序。</p>
<p>数字系统由三个主要部分组成，对位进行操作的函数的组合逻辑、存储位的存储器元素，以及控制存储器元素更新的时钟信号。</p>
<h2>Circuit</h2>
<p>逻辑门是数字电路的基本计算元素，包括了与门、或门、与非门、或非门和非门，其构成了组合逻辑电路和时序逻辑电路，前者没有存储能力，输出仅取决于当时的输入，后者具有存储能力，其输出不仅取决于当时的输入，也取决于以前的输入序列。</p>
<p>在组合逻辑电路（combinational circuits）中，两个或多个逻辑门的输出不能连接在一起，同时不能形成回路。在时序逻辑电路中，存储设备由同一个时钟控制，时钟是一个周期性信号，其决定了什么时候要把新值加载到设备中。</p>
<p>硬件寄存器用作电路不同部分中的组合逻辑之间的屏障，每当一个时钟到达了上升沿时，值才会从寄存器的输入传送到输出，在Y86中用来保存程序计数器（PC）、条件代码（CC）和程序状态（Stat）。</p>
<h2>SEQ</h2>
<p>处理一条指令会有很多的操作，这些操作可以被组织成一个阶段序列，虽然不同的指令对应的操作也不相同，但阶段序列则是统一的。</p>
<ol>
<li>取值（fetch），从存储器读取指令字节，地址为程序计数器（PC）的值。</li>
<li>译码（decode），从寄存器读取最多两个操作数。</li>
<li>执行（execute），算术/逻辑单元（ALU）执行指令指明的操作，或者增加或减少栈指针。</li>
<li>访存（memory），将数据写回存储器，或者从存储器读出数据。</li>
<li>写回（write back），将最多两个结果写到寄存器文件。</li>
<li>更新PC（PC update），将PC设置成下一条指令的地址。</li>
</ol>
<p>SEQ的实现包括组合逻辑、时钟寄存器（程序计数器和条件码寄存器）、随机访问存储器（寄存器文件、指令存储器和数据存储器），组合逻辑和指令寄存器可视作不需要时序控制，程序计数器、条件码寄存器、数据存储器和寄存器文件则需要对其时序进行控制。</p>
<p>处理器从来不需要为了完成一条指令的执行而去读由该指令更新了的状态。</p>
<p>用时钟控制状态元素的更新，以及值通过组合逻辑来传播，足够控制我们SEQ实现中每条指令执行的计算了。每次时钟由低变高时，处理器开始执行一条新指令。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.poemcode.net/2012/04/csapp-isa-circuit-seq/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>读CSAPP之Procedure、Stack Frame</title>
		<link>http://www.poemcode.net/2012/03/csapp-procedure-stack-fram/</link>
		<comments>http://www.poemcode.net/2012/03/csapp-procedure-stack-fram/#comments</comments>
		<pubDate>Wed, 28 Mar 2012 13:00:01 +0000</pubDate>
		<dc:creator>Xu Haojie</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[CSAPP]]></category>

		<guid isPermaLink="false">http://www.poemcode.net/?p=2748</guid>
		<description><![CDATA[<div class="wp-caption alignright" style="width: 80px"><img class="size-full wp-image-521" title="Computer System: A Programmer’s Perspective" src="http://www.poemcode.net/wp-content/uploads/2011/09/csapp.jpg" alt="Computer System: A Programmer’s Perspective" width="80" height="100" /></div> 
过程调用包括将数据（以参数和返回值的形式）和控制从代码的一部分传递到另一部分，同时，在进入时为过程的局部变量分配空间，并在退出时释放空间。

IA32只提供了对进入过程和退出过程的控制，而数据传递、变量的分配和释放则要通过操作程序栈来实现。x86-64则是通过寄存器而不是栈来传递数据，这样极大地减少了存储器读写操作的数量。]]></description>
			<content:encoded><![CDATA[<p><small>今年是离开校园的第六年，这六年来我一直在从事应用软件的设计、开发工作，大部分时间是在与高级编程语言、设计模式、业务逻辑打交道。它们大多流于表面，久而久之，与技术底层疏远了，诸如计算机组成原理、汇编语言、编译原理、数据结构以及算法慢慢得生疏，时至今日，向上碰到天花板，向下触到花岗岩。五年是一个契机，趁着下一个五年开始之际，我计划用三个月至半年时想间，重新学习这些知识，以期达到巩固基础，厚积薄发的目的。</p>
<p>本篇是我阅读《Computer System: A Programmer’s Perspective》一书的笔记，该书和与之搭配的《Professional Assembly Language》是我当下阅读计划的一部分。</small></p>
<h2>Procedure</h2>
<p>过程调用包括将数据（以参数和返回值的形式）和控制从代码的一部分传递到另一部分，同时，在进入时为过程的局部变量分配空间，并在退出时释放空间。</p>
<p>IA32只提供了对进入过程和退出过程的控制，而数据传递、变量的分配和释放则要通过操作程序栈来实现。x86-64则是通过寄存器而不是栈来传递数据，这样极大地减少了存储器读写操作的数量。</p>
<h2>Stack Frame</h2>
<p>栈（stack）在过程调用中起到了重要作用，包括了传递过程参数、存储返回信息、保存寄存器和本地存储。为单个过程分配的那部分栈成为栈帧（stack frame），其的最顶端是以两个指针界定，%ebp为帧指针，%esp为栈指针，程序执行时，大多数信息是相对于帧指针。</p>
<p>IA32中，栈向下增长，栈顶元素的地址是所有栈中元素地址最低的，栈指针%esp保存着栈顶元素的地址。</p>
<p>C对于数组引用是不进行任何边界检查，而且局部变量和状态信息（寄存器值和返回地址）都存放在栈中，一旦对越界的数组元素的写操作破坏了状态信息。则程序一旦重新加载寄存器或者执行ret指令，则会出现严重的错误。</p>
<p>栈随机化的思想是使栈的位置在程序每次运行时都有变化，程序开始时，在栈上分配一段0~n 字节之间的随机大小的空间。</p>
<p>地址空间布局随机化（Address-Sapce Layout Randomization），每次运行时，程序的不同部分，例如程序代码、库代码、栈、全局变量和堆数据，都会被加载到存储器的不同区域。</p>
<p>栈保护者的思想是在栈帧中任何局部缓冲区与栈状态之间存储一个特殊的“金丝雀”值，在回复寄存器状态和从函数返回之前，程序检查这个值是否被改变。</p>
<p>栈必须是既可读又可写，同时 x86 体系结构将读和执行访问权限合并成了一个1位的标志，因此栈上的字节也都是可执行的。x86-64 为内存保护引入了 NX （No-eXecute）位，将读和执行模式分开，由此栈就可以被标记为可读、可写，但不可执行。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.poemcode.net/2012/03/csapp-procedure-stack-fram/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>读CSAPP之RAM、Locality和Cache</title>
		<link>http://www.poemcode.net/2012/02/csapp-ram-locality-cache/</link>
		<comments>http://www.poemcode.net/2012/02/csapp-ram-locality-cache/#comments</comments>
		<pubDate>Thu, 02 Feb 2012 12:03:21 +0000</pubDate>
		<dc:creator>Xu Haojie</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[CSAPP]]></category>

		<guid isPermaLink="false">http://www.poemcode.net/?p=2731</guid>
		<description><![CDATA[<div class="wp-caption alignright" style="width: 80px"><img class="size-full wp-image-521" title="Computer System: A Programmer’s Perspective" src="http://www.poemcode.net/wp-content/uploads/2011/09/csapp.jpg" alt="Computer System: A Programmer’s Perspective" width="80" height="100" /></div> 
RAM（Random Access Memory）中文译作随机存取存储器，所谓“随机存取”，指的是当存储器中的消息被读取或写入时，所需要的时间与这段信息所在的位置无关。相对的，读取或写入顺序访问（Sequential Access）存储设备中的信息时，其所需要的时间与位置就会有关系[1]，比如磁盘存储器。

RAM 分为 SRAM 与 DRAM 两大类，二者区别在于前者对干扰（光、电）不敏感，用于高速缓存存储器，后者用于主存和显存，以及数码相机和摄像机中的传感器。]]></description>
			<content:encoded><![CDATA[<p><small>今年是离开校园的第六年，这六年来我一直在从事应用软件的设计、开发工作，大部分时间是在与高级编程语言、设计模式、业务逻辑打交道。它们大多流于表面，久而久之，与技术底层疏远了，诸如计算机组成原理、汇编语言、编译原理、数据结构以及算法慢慢得生疏，时至今日，向上碰到天花板，向下触到花岗岩。五年是一个契机，趁着下一个五年开始之际，我计划用三个月至半年时想间，重新学习这些知识，以期达到巩固基础，厚积薄发的目的。</p>
<p>本篇是我阅读《Computer System: A Programmer’s Perspective》一书的笔记，该书和与之搭配的《Professional Assembly Language》是我当下阅读计划的一部分。</small></p>
<h2>关于RAM</h2>
<p>RAM（Random Access Memory）中文译作随机存取存储器，所谓“随机存取”，指的是当存储器中的消息被读取或写入时，所需要的时间与这段信息所在的位置无关。相对的，读取或写入顺序访问（Sequential Access）存储设备中的信息时，其所需要的时间与位置就会有关系<a href="#ram_wiki"><sup>[1]</sup></a>，比如磁盘存储器。</p>
<p>RAM 分为 SRAM 与 DRAM 两大类，二者区别在于前者对干扰（光、电）不敏感，用于高速缓存存储器，后者用于主存和显存，以及数码相机和摄像机中的传感器。</p>
<p>DRAM 被分成 d 个超单元，每个超单元都是由 w 个 DRAM 单元组成。DRAM 每次传输 w 位信息。超单元被组织成一个 r 行 c 列的阵列，此时 r*c=d。之所以组织成阵列而不是线性数组，原因之一是降低芯片上地址引脚（pin）的数量，缺点是必须分两次发送地址，增加了访问时间。</p>
<h2>关于局部性</h2>
<p>局部性（locality）有两种：时间局部性（temporal locality）和空间局部性（spatial locality）。在一个具有良好时间局部性的程序中，被引用过一次的存储器位置很可能很快不远的将来再被多次引用。在一个具有良好空间局部性的程序中，如果一个存储器位置被引用了一次，那么程序很可能很快引用其附近的位置。</p>
<p>对于具有步长为k的引用模式的程序，步长越小，空间局部性越好。如果步长为1，则存储器层次结构中所有层次上的缓存都是将数据存储为连续的块。</p>
<p>对于取指令来说，循环具有很好的时间和空间局部性，循环体越小，循环迭代次数越多，局部性越好。重复引用同一个变量的程序有良好的时间局部性。</p>
<h2>关于高速缓存</h2>
<p>高速缓存存储器，作为CPU和主存之间的缓存区域，对应用程序性能的影响最大。其结构可以用元组（S，E，B，m）来描述，其大小 C 指的是所有块的大小的和，标记位和有效位不包含在内，因此，C=S*K*B。S=2s，即组数；E 是每个组的行数；B=2b 是块大小。</p>
<p>高速缓存的结构将 m 个地址位分成了 t 个标记位、s 个组索引位和 b 个块偏移位。组索引位告诉字存储在哪个组内；标记位告诉字存储在这个组的哪一行里，只有该行的标记位和地址中的标记位相匹配，并且有效位被设置，才能确定该行确实包含了该字；块偏移位则告诉在 B 个字节的数据块中的字偏移。</p>
<p>块是一个固定大小的信息包，在高速缓存和主存之间来回传送。行是高速缓存中存储块以及其他信息（例如标记位和有效位）的容器。组是一个或多个行的集合。直接映射高速缓存的的组只有一行。全相联高速缓存中组只有一个。</p>
<p>如果每一组里只有一行，即 E=1，那么这个高速缓存被称为直接映射高速缓存（direct-mapped cache）。如果每一组里有多个行，即 1&lt; E&lt;C/B，那么这个高速缓存被称为组相连高速缓存（set associative cache）。如果一个组包含了所有行，即 E=C/B，那么这个高速缓存被称为全相连高速缓存（fully associative cache）。</p>
<p>高速缓存确定一个请求是否被命中，然后抽取出被请求的字的过程，可分为三步：组选择、行匹配、字抽取。</p>
<p>最不常使用（Least-Frequently-Used，LFU）策略会替换在过去某个时间窗口内引用次数最少的那一行，最近最少使用（Least-Recently-Used，LRU）策略会替换最后一次访问时间最久远的一行。</p>
<p>全相联高速缓存只适合做小的高速缓存，例如虚拟存储器系统中的翻译备用缓冲器（TLB），它缓存页表项。</p>
<p>直写（write-through）就是立即将高速缓存块写回到接邻着的低一层中，简单，但是每次写都会引起总线流量。写回（write-back）就是尽可能地推迟存储器更新，只有当替换算法要驱逐更新过的块时，才将其写回到低一层中，其显著减少了总线流量，但增加了复杂性。</p>
<p>写分配（write-allocate）就是先加载低一层中的块到高速缓存中，然后更新这个高速缓存块。非写分配（non-write-allocate）就是避开高速缓存，直接写到低一层中。</p>
<hr style="margin-top:20px; margin-bottom:20px"/>
<ol>
<li><a href="http://zh.wikipedia.org/zh-cn/随机存取存储器" target="blank">维基百科上关于 RAM 的解释</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.poemcode.net/2012/02/csapp-ram-locality-cache/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WiFi-Robot Car 之舵机篇</title>
		<link>http://www.poemcode.net/2012/01/wifi-robot-car-servo/</link>
		<comments>http://www.poemcode.net/2012/01/wifi-robot-car-servo/#comments</comments>
		<pubDate>Sat, 21 Jan 2012 12:00:08 +0000</pubDate>
		<dc:creator>Xu Haojie</dc:creator>
				<category><![CDATA[Electronics]]></category>
		<category><![CDATA[WiFi-Robot]]></category>

		<guid isPermaLink="false">http://www.poemcode.net/?p=2685</guid>
		<description><![CDATA[舵机，有些人会叫它伺服器，这大概是台湾的术语，其可以根据在指令转动方向，停留在0-180度，在机器人等设备中经常用到。其有一个三线的接口，黑色（或棕色）的线是接地线，红线接+5V电压，黄线（或是白色或橙色）接控制信号端。这里有一篇来自果壳网的启蒙文章<a href="http://www.guokr.com/article/5292/" target="blank" title="DIYer修炼：舵机知识扫盲">《DIYer修炼：舵机知识扫盲》</a>，我也是通过这篇文章入门的。

在 WiFi-Robot Car 中，我使用了两个舵机来控制摄像头的上下、左右运动。如果打算做得更炫一点儿，WiFi-Robot Car 可以加入机械臂，通过舵机可以控制伸长、缩回等转动，甚至可以控制它抓取东西。--但眼下我没打算加入这个功能。]]></description>
			<content:encoded><![CDATA[<div id="attachment_2715" class="wp-caption alignleft" style="width: 210px"><img src="http://www.poemcode.net/wp-content/uploads/2012/01/servo_01.jpg" alt="全家福" title="全家福" width="200" height="300" class="size-full wp-image-2715" /><p class="wp-caption-text">全家福</p></div>
<p>舵机，有些人会叫它伺服器，这大概是台湾的术语，其可以根据在指令转动方向，停留在0-180度，在机器人等设备中经常用到。其有一个三线的接口，黑色（或棕色）的线是接地线，红线接+5V电压，黄线（或是白色或橙色）接控制信号端。这里有一篇来自果壳网的启蒙文章<a href="http://www.guokr.com/article/5292/" target="blank" title="DIYer修炼：舵机知识扫盲">《DIYer修炼：舵机知识扫盲》</a>，我也是通过这篇文章入门的。</p>
<p>在 WiFi-Robot Car 中，我使用了两个舵机来控制摄像头的上下、左右运动。如果打算做得更炫一点儿，WiFi-Robot Car 可以加入机械臂，通过舵机可以控制伸长、缩回等转动，甚至可以控制它抓取东西。&#8211;但眼下我没打算加入这个功能。</p>
<p>这次我选用的舵机是来自台湾辉盛的 MG995，其规格<a href="#mg995"><sup>1</sup></a>如下：</p>
<table border="1" cellspacing="0" cellpadding="0" style="margin:0px auto">
<tr>
<td>
Weight
</td>
<td>
55.0g
</td<br />
</tr>
<tr>
<td>
Dimension
</td>
<td>
40.7*19.7*42.9mm
</td>
</tr>
<tr>
<td>
Stall torque
</td>
<td>8.5kg/cm(4.8V),10kg/cm(6V)
</td>
</tr>
<tr>
<td>
Operating speed
</td>
<td>0.20sec/60degree(4.8v), 0.16sec/60degree(6v)
</td>
</tr>
<tr>
<td>Operating voltage
</td>
<td>4.8-7.2V
</td>
</tr>
<tr>
<td>Temperature range
</td>
<td>0℃_ 55℃
</td>
</tr>
<tr>
<td>Dead band width
</td>
<td>
5us
</td>
</tr>
</table>
<p>单单有舵机是无法支起摄像头的，在二者之间需要支架。在 WiFi-Robot Car 里，我选用一个支架套件，包括了两个多功能支架、一个U型支架和一个杯士轴承（我曾怀疑是杯式轴承，后查实确是杯士轴承）等。</p>
<p>以下我将组装舵机和支架，构成摄像头云台。&#8211;可不是单反相机的云台，那只是一个三脚架而已。</p>
<p>首先，安装第一个舵机和多功能支架。舵机要先固定在支架上，需要借助舵盘，常见的舵盘有圆盘型、星型、一字型、十字型，可参见全家福那张图片。</p>
<p>这里，我选用了圆盘型舵盘，这是因为我在安装过程中，其他类型的舵盘不好对准安装孔。</p>
<div id="attachment_2716" class="wp-caption aligncenter" style="width: 610px"><img src="http://www.poemcode.net/wp-content/uploads/2012/01/servo_1-300x200.jpg" alt="安装前" title="安装前" width="300" height="200" class="size-medium wp-image-2716" /><img src="http://www.poemcode.net/wp-content/uploads/2012/01/servo_2-300x200.jpg" alt="安装后" title="安装后" width="300" height="200" class="size-medium wp-image-2717" /><p class="wp-caption-text">第一步安装前（左）后（右）对比</p></div>
<p>然后，安装U型支架和杯士轴承。建议这个U型支架在购买时尽可能选择比较高的，我这里选用的U型支架高度不是很够，虽然不影响使用，但总觉得别扭。</p>
<p>杯士轴承是用来连接U型支架和上一步中的多功能支架，有了这个东西才能让两者足够“和谐”，减少摩擦。</p>
<div id="attachment_2718" class="wp-caption aligncenter" style="width: 610px"><img src="http://www.poemcode.net/wp-content/uploads/2012/01/servo_3-300x200.jpg" alt="安装前" title="安装前" width="300" height="200" class="size-medium wp-image-2718" /><img src="http://www.poemcode.net/wp-content/uploads/2012/01/servo_5-300x200.jpg" alt="安装后" title="安装后" width="300" height="200" class="size-medium wp-image-2720" /><p class="wp-caption-text">第二步安装前（左）后（右）对比</p></div>
<p>接着，安装第二个舵机。这个时候，需要观察舵机、U型支架、多功能支架之间的空间关系，注意到多功能支架的两条“手臂”正好卡住舵机，同时舵机也正对U型支架的另一端。</p>
<p>我这里的三者关系刚刚好，&#8211;毕竟这是有规格限制的，如果购买的配件不是很标准，那么安装起来就不会那么痛快了。我仔细目测了整体效果，觉得“刚刚好”要打个折扣，因为U型支架的水平方向不是很平。</p>
<div id="attachment_2721" class="wp-caption aligncenter" style="width: 610px"><img src="http://www.poemcode.net/wp-content/uploads/2012/01/servo_6-300x200.jpg" alt="安装前" title="安装前" width="300" height="200" class="size-medium wp-image-2721" /><img src="http://www.poemcode.net/wp-content/uploads/2012/01/servo_7-300x200.jpg" alt="安装后" title="安装后" width="300" height="200" class="size-medium wp-image-2722" /><p class="wp-caption-text">第三步效果</p></div>
<p>最后，安装第二个多功能支架。这个多功能支架是用来将整个结构能够牢牢固定在底座上，所谓的底座在这里就是车体了。</p>
<p>注意观察左侧图片下方的螺丝，也就是整个螺丝将云台固定起来。我将USB摄像头用胶带粘在了U型支架上，暂且将就用着，效果如右图所示。</p>
<div id="attachment_2723" class="wp-caption aligncenter" style="width: 610px"><img src="http://www.poemcode.net/wp-content/uploads/2012/01/servo_8-300x200.jpg" alt="云台完毕" title="云台完毕" width="300" height="200" class="size-medium wp-image-2723" /><img src="http://www.poemcode.net/wp-content/uploads/2012/01/servo_91-300x200.jpg" alt="整体效果" title="整体效果" width="300" height="200" class="size-medium wp-image-2725" /><p class="wp-caption-text">第四步效果</p></div>
<hr style="margin-top:20px; margin-bottom:20px"/>
<ol>
<li><a href="http://www.towerpro.com.tw/viewitem1.asp?sn=601&#038;area=53&#038;cat=187" target="blank">辉盛官方网站对MG995的介绍</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.poemcode.net/2012/01/wifi-robot-car-servo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

