CAT | DIY
终于要开始写第一个Arduino程序了,就跟之前学习所有语言一样,第一个程序自然是Hello World了。不过这次有点特殊,要让Arduino显示一个“Hello World”字符串恐怕有点难度,这是因为Arduino模块上没有提供任何可供显示字符的设备。而这对Arduino新手来讲,也就意味着程序的调试将是一个令人头疼的问题。
最简单的办法是在Arduino提供的数字端口(Digital I/O)上连接发光二极管,然后通过控制发光二极管的亮灭来表明程序的当前运行状态,这的的确确可以算得上是最原始的调试方法。
我的第一个Arduino程序正是要通过对数字I/O的13号管脚的控制,来实现与其相连的发光二极的亮灭。之所以要选择13号管脚步,是因为从原理图上可以看出该管脚与ATmega的引脚之间连接了一个1K的电阻,能够起到限流的作用,以保护二极管不被烧坏。
发光二极管是有正负极性的,因此必须连接正确才能够让其正常发光。刚买来的发光二极腿比较长的一端是正极,需要接在Arduino数字I/O的13号管脚上;腿比较短的一端是负极,需要接在GND管脚上。

运行Arduino的集成开发环境,选择File->New菜单创建一个新的Arduino工程

接着在Arduino集成开发环境的主窗口中输入相应的代码:
int ledPin = 13;
void setup()
{
pinMode(ledPin, OUTPUT);
}
void loop()
{
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);
}
不难看出,一个最简单的Arduino程序至少要实现两个函数:setup()和loop()。其中setup()这个函数主要用来完成相应的初始化工作,在上面的例子中是将数字I/O的13号管脚设置为数字输出。loop()这个函数则是Arduino程序的主函数,相当于C语言中的main()函数,一个Arduino程序要完成的主要功能都在该函数中实现,在上面的例子中是通过变换13号管脚的高低电平,并设置一秒的延时,从而使发光二极管能够间歇性地不断亮灭。
从原理上讲,用Arduino语言编写的程序最后会被翻译成相应的C代码,再用AVR-GCC编译后下载到ATmega单片机中运行。因此设计Arduino语言的目的就是简化单片机编程,虽然这样效率上会有一些损失,但却能够极大地促进单片机在更广泛领域内的使用,基本上算是沿袭了PC机上软件设计语言从汇编语言到C语言再到高级语言这一过程,因此很多技术和做法其实可以借鉴。
用Arduino语言编写的代码需要先验证(Verify),以保证语法的正确性,然后再编译生成相应的机器码。对Arduino代码的验证可以通过Sketch->Verify/Compile菜单命令完成,也可以通过工具栏上的按钮完成:

代码成功通过验证和编译之后,就可以将其下载到Arduino模块中了。由于昨天已经将bootloader成功地烧写到了ATmega中,因此下载Arduino应用的任务就可以完全交由bootloader来完成了。Arduino的bootloader与集成开发环境的交互是通过串口来完成的,因此需要用串口线将Arduino与PC机的串中连接起来。我的串口线是自制的,按照Arduino的原理图,只需要接2,3和5三根线,其中前两根用于数据的收发,最后一根是地线。
串口线连接好之后,在Arduino集成开发环境的Tools->Serial Port菜单下选择与PC相连的串口:

一开始我很奇怪为什么没有设置波特率和其它串行通信参数的地方,后来在Arduino的网站上才知道这些参数都保存在一个名为preferences.txt的配置文件中,该文件一般保存在类似于C:\Documents and Settings\Administrator\Application Data\Arduino这样的目录下。下面是我在该文件中找到的与串口通信相关的一些参数:
serial.stopbits=1
serial.databits=8
serial.download_rate=19200
serial.parity=N
不难看出,Arduino模块采用的是19200 8N1方式来进行串口通信的。确定了这些之后,按下Arduino模块的复位按钮,随后立即执行File->Upload to I/O Board菜单命令将编译好的程序下载到Arduino模块中。Arduino的bootloader被设计成如果在给定的时间(通常有7到8秒)内没有接收到任何来自集成开发环境的命令,就自动运行之前已经下载的程序,所以我们必须保证在正确的时间段内给Arduino模块发送程序下载的指令。除了通过菜单命令外,下载程序也可以通过快捷键Ctrl+U,或者直接点击工具栏上的相应按钮来完成:

将Arduino程序上传到Arduino模块中需要花一些时间,并且取决于工程的大小。当程序上传成功之后,可以在Arduino集成开发环境的console窗口中看到上传后的程序大小,以及该Arduino模块能够接受的最大程序的大小:

现在再次复位Arduino模块,会看到发光二极管立即闪了一下,表明bootloader正常工作了。接着再过一段时间,大约7到8秒,会看到发光二极管间歇性地不断亮灭,这就表明第一个Arduino程序已经成功地运行起来了,CONGRATULATIONS!

我在这期间遇到的唯一问题是刚开始的时候无法通过串口线下载程序,最初怀疑是串口通信的问题,后来慢慢排查发现Arduino模块能够从串口收数据,但却无法从串口发数据。仔细检查了硬件发现原来我在Arduino模块上接的是串口的公头,自然收发的两条线没有同PC机完全正常地连接上,后来换成一个母头就一切正常了。这一过程中的另一收区是仔细读了Arduino关于串口部分的原理图,原来这部分还是一个实用的TTL转232的电平转换电路,其中只用到了电阻、二极管和三极管,省去了一个MAX232芯片。
至此,DIY Arduino模块的工作算是暂告一段落,剩下的是如何对各个硬件功能进行详细的验证,这可以结合实际的项目来完成。我计划下一步做一些简单的Arduino工程,大部分可能都来源于Arduino网站或者是网上收集到的资料,以验证我的Arduino模块,同时也可以当作入门的教程供大家参考。
No tags
读了一些有关Arduino的介绍性的文章之后,才知道这么一个小东东居然在国外是大红大紫,虽然没有完全想清楚其中的原因,但似乎并不妨碍自己DIY它的决心。Arduino采用开放源代码的模式,其原理图和电路图都可以从其网站免费得到。在权衡比较了一番之后,我决定从其采用串口方式的版本开始,这一方面是因为原理相对简单,能够降低组装和调试的难度,另一方面则考虑到USB模拟的串口并不总是那么稳定。
决定开工之后,花了一上午的时间画好了原理图,基本凑和吧。可轮到电路图时可就不一样了,封装和走线对我这业务选手来讲的确不是件容易的事情。花了两个晚上的时间,最后还是决定放弃,因为Arduino官方提供的电路图在我看来确实比自己布的要漂亮多了,看来这一修养只能在随后的日子里慢慢积累了。
去做电路板时遇到一些问题,由于我问到的制造电路板的厂商基本上只认Protel,根本不知道还有Eagle CAD一说,甚至有人还将其与AutoCAD混为一谈,告诉我这个软件不是用来画电路图的。没有办法,只好回家一顿Google,将其生成Gerber文件后再将送过去。这一过程也算有点收获,除了知道何为Gerber文件以及如何在Eagle CAD中生成Gerber文件之外,还找到了一个用来查看Gerber文件的好工具:CAM350。
电路板从送去到拿到一般需要一周多的时间,这期间的主要任务当然是购买元器件了。一开始并没有注意到Arduino串口版本的元件列表,以为与NG版本一样也采用的是ATmega168,问了好些地方都没得卖,最好只好高价比香港快递过来,估计贵了不止一倍。最后在组装的时候才发现原来串口版本采用的仍旧是ATmega8,而这在村里还算是很好买到的,这一个郁闷啊!
元件都准备妥当之后,电路板也做出来了,虽然不是与Arduino官方一致的蓝色,但还是挺漂亮的;-)

将元件焊接到PCB板上又是一次对基本功的训练,好在这一版本的Arduino采用的都是分立元件,焊接上没有遇到太大的麻烦。期间再一次深刻体会到了工具的重要性,不时幻想自己手中那把最便宜的铬铁啥里也能更新换代一下,虽然他的寿命还不到短短的一个月。

焊接完成之后,万里长征估计还只完成了第一步,要让Arduino能够正常的运行起来,肯定还有相当多的调试和排错的工作要做,而这也正是DIY的乐趣所在;-)
No tags
