专注电子技术学习与研究
当前位置:单片机教程网 >> Arduino >> 浏览文章

扩展NDS掌机连接Arduino (1)--Arduino端最小系统实现

作者:c_gao   来源:转的   点击数:  更新时间:2014年06月25日   【字体:
前几天写了这篇方案:扩展NDS掌机连接Arduino方案设计。昨天在此基础上实现了第一步,即Arduino端最小系统实现。此第一步主要内容概括为不使用任何外部电子元件,实现仅Atmega328独立运行的最小系统,包括支持3.3V运行电压下工作的bootloader,以及一个简单的sketch (blink)的运行。该最小系统目前在面包板上实现和运行,图1为实现效果。


图1. 最小Arduino系统blink程序效果。左侧面包板为最小系统,右侧无CPU的UNO仅为左侧提供3.3V工作电压。

下面记录一下实现过程。

首先我手上的资源如下:
(1)两块Arduino UNO板子
(2)面包板一块
(3)杜邦线若干

第一步,制做Arduino ISP。是在IDE里设置好正确的串口和板子类型(Arduino UNO),选择File->Examples->ArduinoISP。编译上传该Sketch至其中一块UNO板上。上传成功后,这块Arduino板子便成为了ISP (In-System Programmer),即烧写器或编程器。


图2. 用一块Arduino给另一块烧写Bootloader。

第二步,烧写bootloader。按图2所示连接好两块UNO板的线。图中上方的UNO为含需要被上传bootloader的CPU板子,下方为第一步完成的作为ISP的Arduino UNO。然后按之前方案所述,在Sketchbook location路径(该路径可在菜单Preferences对话框内查看)下创建hardware文件夹,并在该文件夹中创建breadboard文件夹,然后在这个breadboard文件夹中创建boards.txt文件,内容如下:

##############################################################

atmega328bb.name=ATmega328 on a breadboard (8 MHz internal clock)

atmega328bb.upload.protocol=stk500
atmega328bb.upload.maximum_size=30720
atmega328bb.upload.speed=57600

atmega328bb.bootloader.low_fuses=0xE2
atmega328bb.bootloader.high_fuses=0xDA
atmega328bb.bootloader.extended_fuses=0x05
atmega328bb.bootloader.path=arduino:atmega
atmega328bb.bootloader.file=ATmegaBOOT_168_atmega328_pro_8MHz.hex
atmega328bb.bootloader.unlock_bits=0x3F
atmega328bb.bootloader.lock_bits=0x0F

atmega328bb.build.mcu=atmega328p
atmega328bb.build.f_cpu=8000000L
atmega328bb.build.core=arduino:arduino
atmega328bb.build.variant=arduino:standard

然后,关闭Arduino IDE后重新打开IDE,此时在菜单Tools->Board里会出现一块新的板子,即:ATmega328 on a breadboard (8 MHz internal clock)。选择这块板子。并在菜单Tools->Programmer里选择Arduino as ISP。然后点击菜单Tools->Burn Bootloader,IDE开始给另一块板子的CPU烧写Bootloader。烧写成功后,被
烧的板子上的CPU就拥有了仅使用CPU内部8MHz晶振作为时钟源的最小系统。

这里不得不提一件非常重要的插曲,估计绝大多数用户可能都会遇到的很难解决的问题。以下是我最初尝试的第二步:将其中一块的CPU取下后按之前方案中图3连接好线后,怎么也刷不上bootloader,总是提示这样的错误:
 "avrdude: Yikes!  Invalid device signature." or "avrdude: Expected signature for ATMEGA328P is 1E 95 0F" 或
 "stk500_getsync(): not in sync: resp=0x00"
开始毫无头绪,查了非常多的资料和论坛发现,很多老外都遇到这个问题,而且几乎每个贴子都没有解决,其中有一个贴子很多网友回复,非常之长,提了N种可能的解决方法,包括添加10uF的电容在Reset和Gnd之间,以及添加10K电阻在Vcc和Reset之间,还有说UNO不带FTDI芯片无法解决,可惜提问者也都没有最终解决。而我除了第三种FTDI外,前两种尝试了N遍也都无果。其中10uF的电容我还是从同学的废旧录音机上拆下的。

还好我在第二天查到了另一种引发该问题的原因,即因为我使用的是CPU是从原UNO板上取下的Atmega328,该CPU已烧有带16MHz外部晶振运行的bootloader,因此无法取下后在没有添加晶振和附加滤波电容的条件下重新烧录bootloader或运行。是这篇文章给了我回答和解决方法:Breaduino,文章里有一段原话:
So why couldn't I burn the bootloader using the Minimal Circuit?
All my ATMega came preloaded with the regular Arduino Bootloader for use with the Arduino Board. That way they are configured to work with an external 16 MHz crystal.
So, because of that, the ATMega that I was trying to burn a bootloader into wasn't working. It needed the external crystal as configured for me to be able to burn a different boot loader.
既然需要外部晶振,那么原来的没取CPU时的UNO板子不就带吗?于是按这个思路最后实现了正确的第二步。而之前方案中采用的是刚出厂未被使用过的CPU,这种刚出厂未使用的CPU在出厂时默认被设置为使用内部晶振,因此可以不用外部晶振就能工作。这个理由应该可以从Atmel官方的DataSheet中查得到(我没查),不过我在这篇文章:Fuse bits aren’t that scary中查到了这样两句话:
1. Most MCUs are shipped with the internal RC oscillator set as default clock source.
2. ATmega48 is shipped with internal 8MHz RC oscillator set as an active clock source and CKDIV8 fuse set. 

因此第二步的成功和失败经验得出如下结论:
(1)如果是给已含有带外部晶振的CPU烧只用片内晶振的bootloader时,需要添加外部晶振。
(2)如果是给出厂未使用过的CPU烧只用片内晶振的bootloader时,不需要添加外部晶振。

第三步,上传Sketch。首先,将原作为Arduino ISP的板子上的CPU取下放到一边(暂时用不上了),并按图3所示连接好连线。


图3. 上传Sketch时的连线。
此时,取下原CPU,再连好线后,任意选择一个Sketch即可编译上传。我为了演示方便,选择了最常用的Blink,然后对照图4,将Arduino 13号数字引脚对应的Atmega328的第19号脚(PB5)和Gnd间串连个电阻(220~330欧左右)和LED,便能看到一秒停一秒亮的运行效果了。


图4. Atmega 168/328 和Arduino引脚的对照图。

至此,面包板上的东西就是个真正的最小系统了,无任何外电子元件。

注意:第二步和第三步里,操作的对象都是需要制做的最小系统的CPU,所以菜单Tools->Board里保持选择ATmega328 on a breadboard (8 MHz internal clock)不变。

第四步,使用3.3V给最小系统供电。 这部分工作可能复杂,也可能很简单,这和CPU类型,以及烧录bootloader时boards.txt里写的low fuse, high fuse, extend fuse有关。特别是extend fuse里可以设置brown-out电压,按Atmel官方的资料, 虽然Atmega 168/328运行电压为1.8V~5.5V,但实际情况可能会因为运行电压低于一定值时CPU就无法工作。这就是为什么要设置extend fuse bit里brown-out电压的原因,具体这里不给出说明了,可以google之。

因为我采用上述boards.txt里的fuse bit设置后,将无CPU的Arduino UNO板3.3V口作为供电电源后,本方案一切运行正常。所以第四步,对于我来说只是改变供电电压便何。

敬请期待后续工作...

相关文章