利用PROGISP实现ARDUINO IDE编写的程序的下载以及如何把AVR单片机做成ARDUINO

2019-07-13 23:48发布

首先讲讲题目的由来吧。我做的东西原本是利用ARDUINO MEGA2560及各种模块搭建起来的,程序自然也是用ARDUINO IDE写的。但这种东拼西凑的产品自然不够好,更主要的是,之前ARDUINO板的电源烧掉了,我看了下原理图,当电脑USB电源和12V电源都接上时,USB5V和12V转的5V并联了,以此来提供大电流,但是我上网查了下,两个相同电压的电源并联其实是很容易出问题的,电流的分配关系并没有想象的那么听话是均分的,而是和电源的内阻有关,很容易烧电源,于是想着自己参考着开源原理图设计了一块电路板,修改了电源方案并把所有元件都放在一块板上,并修改固件(即之前说的程序)后烧进单片机中。说到这里,有必要阐述一下AVR与ARDUINO的关系。 ARDUINO是以ATMEL公司的AVR单片机为主控芯片的开源硬件,同时它还有自己的开发环境ARDUINO IDE。那么ARDUINO板是怎么利用AVR单片机搭建起来的呢?比如ARDUINO MEGA2560就是以AT MEGA2560 为主控芯片搭建起来的。ARDUINO把AVR单片机的部分通用I/O口挑出来,给他重新赋予名字:如maga2560 中PD0对应ARDUINO板上的digital 21(PWM和COMMUNICATION 的I/O口也是DIGITAL口),PF0对应ADC0即板子上ANALOG IN的A0.每个版本都是事先把AVR单片机的各设置都设置好了之后才出售的。每个版本的相关信息可通过ARDUINO所在文件夹下hardwarearduino下的boards.txt查看,里面记载了各版本的熔丝位设置,串口波特率设置,bootloader文件所在位置等等。在ARDUINO IDE中选择版本时,就会把相关参数切换为这个文件里说明的参数。 部分ARDUINO I/O 与AVR I/O对应关系图 说完I/O口,再说说ARDUINO的下载方式。AVR单片机的下载方式有ISP,JTAG仿真,高压并行下载等。早期的ARUIDNO的下载用的还是CH340G,后来从某个版本开始就使用AT MEGA8以及16来实现USB转串口了。ARDUINO MEGA2560的手册的下载模块原理图如下:
下载模块原理图 由于这个原理我也不懂,所以就不多说了。重点是,ARDUINO并没有用传统的下载方式,那他这个下载方式是怎么实现的呢?答案就是BOOTLOADER。有一篇帖子对此作了很有趣的比喻,他说如果芯片是人,那么ISP下载相当于给人洗脑,而通过串行口下载则是让他看文字然后记到脑子里,详细见链接
isp与串口下载比较 BOOTLOADER就是正式程序之前的一段小程序,他在FLASH中有自己专门的存储区(忘记叫什么了),可以根据需要实现各种功能,一般被用作系统启动前的初始化工作。而ARDUINO就利用他实现了串行口下载。具体步骤见后面叙述。 ——————————分割线————————————– 下面说下我的开发过程。

一.利用PROGISP实现ARDUINO IDE编写的程序的下载

由于我的micro usb焊接不上去,又不想浪费其余部分已经焊好的板子,于是用PROGISP来下载ARDUINO IDE上写好的程序。
ARDUINO板子正常的下载是通过USB口,在编译器上一键下载的。而我们用PROGISP下载则需要编译好的16进制文件。导出ARDUINO IDE编译好的hex文件设置如下:
  1. 打开ARDUINO IDE,File->preferences,点那个C盘的路径,用记事本打开preferences.txt
    这里写图片描述
  2. 关闭ARDUINO IDE(非常重要!)
  3. 用记事本打开preferences.txt后,选择hex文件存放的路径,在最后行加入 build.path=D:arduinoMyHexDir。这个路径自己选择。关闭文件。
  4. 验证是否成功,如果没有成功,很可能是修改文件时ARDUINO没有关闭,此时重新打开文件,会发现那段语句并没有加入到文中。
  5. 成功后,目录里能找到编译好的HEX文件。
接下来就是AVR单片机的一些需要设置的地方了,谈下我的经历以及需要注意的东西:熔丝位。这是我第一次接触AVR单片机,很多地方都不懂,之前一直以为直接用CH340G就可以实现下载了,后来发现并不是这样。首先AVR的熔丝位就是一个很独特的东西,它决定了时钟选择,系统时钟分频,启动时从哪个地址开始执行程序,各种使能等等。AVR出厂时默认的是使用内部的RC振荡电路,我的板子上用的是外部的16M晶振,所以需要修改熔丝位来选择外部晶振作为时钟电路。而熔丝位是需要用ISP来下载的,所以第二版PCB我增加了ISP的下载口,并在网上买了两个usb isp下载器,无奈的是,把下载器插到电脑上后,电脑竟然没发现新硬件,在设备管理器里也没有找到。好在卖家负责,给我发了个免驱动的烧录软件,见下图。
这里写图片描述
这里写图片描述
下载链接:免驱动 progisp
这个软件对熔丝位的烧写有向导模式,非常方便,不用去查熔丝位各个位的意义,大大便利了熔丝位的设置。利用这个软件,我成功的实现了熔丝位的修改和程序的烧录(别忘了第一步永远是先选择芯片型号)。当然中间也有一些小插曲。比如说熔丝位中我选择了“系统时钟8分频”,导致实际时钟只有晶振值的八分之一,又如我明明没用BOOTLOADER,却选择了“将复位向量移至BOOT区起始地址”,导致单片机没有执行我的程序。其中主要的问题是单片机时钟选择的问题,这里需要重点强调一下:“RC振荡器”指的是利用电路和电容电路组成的时钟电路,“外部时钟”指的是一种有源晶振而不是我们平时所见的细长的无源晶振,“外部低频晶振”就是频率很低的无源晶振,“外部满幅晶振”我不懂,看有些地方写的它对应的几个熔丝位的值是外部RC振荡电路,总之不用他就对了,而“外部低功率晶振”则是我们常用的外接的无源晶振加起振电容组成的时钟电路,它对应的CKSEL3:0=1000~1111。现在,熔丝位的设置就完成了。
两种晶振 接下来看烧入程序,点“调入FLASH”,设置好其他的选项后,点“自动”就可完成所有操作。这里顺便说下FLASH和EEPROM的区别,FLASH容量很大,一般程序就装在里面。而EEPROM的容量较小,对MEGA2560,它只有4K的大小,多用于非易失性的数据存储器。至此,你已经成功的完成了用PROGISP下载ARDUINO IDE编好的程序到AVR里。
—————————————分割线————————————
现在说下我在开发的过程中遇到的一个很有趣的现象。当我全部设置好熔丝位后,我立即用示波器观察了下晶振的起振情况,得到的却是下面的结果:
这里写图片描述 电压大概是1V,有轻微的纹波。于是我判断晶振依然没有起振。后来又是重焊时钟电路,始终没有解决问题。最后我抱着试一试的态度写了个LED闪烁的程序,并把时钟改成内部RC振荡电路,测试了下输出,发现有输出,只不过频率不对,并且实际频率是理论频率的八分之一,我突然想到之前的“系统时钟8分频”,于是我把这个选项去掉了,果然,输出正常了。紧接着,我把时钟切换为外部晶振,又测了一下输出,输出正常!接着重新测了下晶振,波形依然是一条横线!得出结论:AVR与C51不同,晶振起振后并没有明显的正弦波波形。当设置为内部RC振荡电路时,晶振的引脚电平为0V;当设置为外部晶振时,晶振的一只引脚电压为1V,另一只电压为0.7V,没有正弦波形。

二.如何把AVR单片机做成ARDUINO板

上一种下载方法是AVR的下载方式,而这里提到的下载方法就是ARDUINO的下载方式。ARDUINO的下载其实利用的是AVR单片机的IAP下载方式。IAP是in application programming的缩写,常用来做系统升级。它的原理就是把整个芯片的flash分成两部分,一个叫app区,一个叫boot区。这两个区的大小可根据熔丝位来设置。这里把bootloader烧写进boot区,再让boot区的程序接收串口来的程序,实现程序的自更新即下载。 在你的串口电路好使(用CH340G搭建的串口电路见我的另一篇博客基于CH340G的一键下载)以及焊接等都没问题的情况下,把电脑和板子用AVR ISP连好,在ARDUINO里的TOOLS->Board上选择好板子型号后,再在programmer里选择AVR ISP,最后点Burn Bootloader。成功后,你就可以用ARDUINO正常的下载方式实现下载啦。 然而和前面的问题一样,我的电脑并不识别AVR ISP,所以这里仍然要使用bootloader的hex文件。找到arduino的安装目录,打开hardware/arduino/下的boards.txt,里面有关于各种型号板子的信息,这里我们只关注熔丝位和bootloader在哪。以Arduino Mega 2560为例,
mega2560.bootloader.low_fuses=0xFF
mega2560.bootloader.high_fuses=0xD8
mega2560.bootloader.extended_fuses=0xFD
mega2560.bootloader.path=stk500v2
mega2560.bootloader.file=stk500boot_v2_mega2560.hex

按照以上信息更改熔丝低位,高位和拓展位,再在stk500v2目录下找到stk500boot_v2_mega2560.hex文件,将其烧录到boot区即可。至于加密值,不管他吧,万一锁了就不好了。这样,一个能用ARDUINO IDE下载的板子就做好了。 这里详细说一下熔丝位是怎么设置的。虽然arduino都给我们固定好了,但我们也要把它弄懂。
这里写图片描述
这里写图片描述
以上就是按照arduino提供的熔丝位设置后的结果。
1.它把boot区的大小设置为了4096words,毕竟bootloader有20k+。
2.勾选了“将复位向量移至Boot区起止地址”,如果不这样做的话,每次单片机复位后程序将从头开始执行即IAP下载没有使能。勾选了后,复位后单片机将先执行boot区的程序,如果此时有下载需求,则下载程序,完成后正常执行app区的程序。
3.勾选了“无加密”。建议勾选,如果改为勾选下面两个,则不能再更改flash内容。
4.从其他人的博客上来看,在boot区程序执行并把新程序写入app区的过程中,读取app区的内容是绝对禁止的。所以这里应该勾选“不允许运行于Boot Loader区的LPM指令从应用区读取数据”。(LPM是读程序区指令,SPM是写程序区指令)但是他这里勾选的却是“SPM和LPM对应用区的访问没有限制”,对此我很不理解,希望有大神能指点。