yaboPP电子
项目

了解关于ATmega328P保险丝位和如何使用它们与外部晶体振荡器

2017年8月3日,通过查尔斯·r·汉普顿

该项目介绍了ATmega328P保险丝位,并展示了如何设置它们使用外部16 MHz晶体振荡器。

该项目介绍了ATmega328P保险丝位,并展示了如何设置它们使用外部16 MHz晶体振荡器。

文章概述

熔断器位,也称为熔断器或组态位,是微控制器中用来控制某些在程序代码执行过程中通常不会改变的操作的设置。本文将解释这些操作在ATmega328P中是什么,以及如何设置它们。用于选择时钟源的保险丝位将被更深入地处理,包括如何和为什么使用16mhz外部晶体振荡器。

ATmega328P编程电路

下图显示了一个简单的ATmega328P编程电路。包括原理图、完整的零件清单和结构细节一篇文章.为了继续这个项目,您将需要如下所示的ATmega328P编程电路。

ATmega328P熔丝位

三个保险丝字节

在ATmega328P中总共有19个熔断器位,它们被分成三个不同的熔断器字节。三个保险丝位包含在“扩展保险丝字节”中,八个包含在“保险丝高字节”中,另外八个包含在“保险丝低字节”中。

的2016年11月版本的表31-5ATmega328 / P数据表下面是转载。如你所见,整个扩展的保险丝字节处理电力不足检测水平。限电检测是许多微控制器的一个特点,当电源电压降至一定水平以下时,可以进行复位。在ATmega328P的情况下,可以选择三种不同的电压(名义上1.8V、2.7V或4.3V)中的一种作为最小允许供电电压。

也许从表中需要注意的最重要的事情是,编程一个保险丝位包括将它设置为低,即0(零),这可能与您所期望的相反。例如,请注意,当每一位被设置为逻辑高值(即1(1))时,它是未编程的。这种有点不寻常的方法适用于ATmega328P中所有fuse字节中的所有位。

数据表31-6如下所示。位2-0用于设置ATmega328P的启动大小;启动大小是指为安装功能类似于Arduino开发板的bootloader的“boot Loader”预留的内存大小。Fuse高字节中剩余位的用途由表项合理地阐明。的要避免两位数除非你非常确定你正在做的是第7位,RSTDISBL(外部复位禁用)位和第5位,SPIEN(串行外设接口启用)位。使其中任何一个失效通常是“砖”的Atmel碳纳米管的原因;“别管他们”是个好建议。

ATmega328/P Datasheet中包含所有19个保险丝位的目的和设置程序的详细信息;设置保险丝低字节将包括在这篇文章。然而,编程所有保险丝位的一般过程是相似的。

Fuse低字节选项

这个Fuse低字节为ATmega328P选择时钟源,并控制时钟操作的一些细节。数据表31-7如下所示。

不要忘记,编程一个保险丝位包括设置低,即,0(零)。例如,请注意,第7位用于启用/禁用时钟除以8;要使时钟速率被8分割,第7位将被设置为0(低),要使时钟速率被8分割,第7位将被设置为1(高)。

  • 第7位控制是否启用时钟速率除以8的特性,第6位决定是否在微控制器的PORTB0上存在时钟输出。
  • 位5和位4控制微控制器的启动时间,这是为了防止芯片试图在供电电压有时间达到可接受的最低水平之前启动。
  • 3到0位用于选择时钟源,表13-1给出了可用的时钟源选择。

Fuse低字节默认值

哇!诚然,为了设置Fuse Low Byte的8位,需要考虑很多数据,但这都是必要的,没有“回旋的空间”。(冒着看起来过于挑剔的风险,作者认为数据表可以写得更清楚一点,以传达这个相当复杂的过程的细节。)

幸运的是,数据表中有很多信息都写得很清楚;当ATmega328P从工厂发货时,它的默认值是明确无误的。回顾表31-7。

  • 时钟除以8通过将第7位设置为0启用。
  • 时钟输出PORTB0因第6位设置为1而禁用。
  • 选择时钟源设置为内部校准RC振荡器,由位3,2,1和0被设置为0010。(见表13-1,下表13-11)

  • 启动时间部分依赖于所选择的振荡器类型,并由第5位和第4位设置。在内部校准RC振荡器的情况下,该信息来自表13-12。第5位和第4位(SUT1和SUT0熔断器)的编程是指定为每三种功率条件。默认是缓慢上升的功率,结果在断电或省电后的启动时间为6个时钟周期,加上额外的14个时钟周期和复位后的65毫秒启动时间。见下表31- 12。

您现在应该了解Fuse低字节被预编程为01100010(在十六进制记数法中,是0x62),以及这对微控制器的操作意味着什么。如果其中有不清楚的地方,不要惊讶;这是一个复杂的问题。你的时间可能会花在重读ATmega328P数据表第13和31节的适用部分。

现在,做一些改变

如果你熟悉Arduino家族的微控制器平台,特别是Arduino UNO,你可能还记得它使用了一个ATmega328PµC。也许你还记得UNO有一个外部振荡器电路,由一个16MHz晶体和两个小陶瓷电容器(通常每个约22pF)组成。你也许还记得,联合国办事处的工作速度是16兆赫。

但是ATmega328P呢?你能确定吗?默认的从工厂发货时的操作速度?

你知道ATmega328P的默认时钟是一个内部RC振荡器,但你记得它的速度吗?答案在表31-7的注释2:8MHz。并且因为Fuse Low Byte的第7位的默认值是0,时钟率除以8是启用的。因此,ATmega328P的默认运行速度是…等待它…1MHz。

但是假设您的项目要求ATmega328P的时钟速度为16MHz;你知道怎么做到吗?和往常一样,这涉及到硬件和软件。

硬件:增加一个水晶振荡器

为了以16MHz的频率运行ATmega328P,您需要在本文开头所示的电路中添加一个外部晶体振荡器。只需要三个新部件:16MHz晶体(Jameco # 325139)及两个22pF陶瓷电容器(Jameco # 81533).所得到的原理图就在下面,面包板电路的照片就在原理图的下面。

软件:更改保险丝低字节设置

一旦添加了16MHz晶体振荡器电路并检查了配线,下一个目标是确定低功率晶体振荡器所需的保险丝位的变化。扩展保险丝字节和保险丝高字节不受振荡器变化的影响;只有保险丝低字节需要改变。

警告!不要将时钟源改为外部晶体,除非你真的安装了晶体。如果你这样做了,就没有ATmega328P的时钟,因此就没有办法重新编程。

考虑Fuse低字节逐位。

  • 第7位控制除以8的操作,并且0的默认设置启用了这个功能,这是您不想要的。所以,第7位需要从0变成1。
  • 第6位控制到PORTB0的时钟输出,这一点您并不关心。所以,第6位可以左置为1。
  • 位3-0控制振荡器的选择,和0010的默认设置是使用校准的内部RC振荡器,这不是你想要的。你想要低功率晶体振荡器,根据表13-1,比特3-0应该设置为1111,1110,1101,1100,1011,1010,1001,或1000,但哪一个?继续读下去。

如表13-3所示,对于8.0 ~ 16.0 MHz的操作,3-1位(CKSEL[3:1])应该设置为111。但是CKSEL[0]呢?继续读下去。

比特5和比特4控制启动时间,默认设置为10的启动延迟从下电和省电6个时钟周期,加上额外的启动延迟14个时钟周期加上从复位65毫秒。从常规表,在低功率晶体振荡器的安全起见,你想要16000个时钟周期的最大延迟可能从省电,省电,所以SUT[1]应该设置为1,再加上一个额外的启动延迟14从重置时钟周期+ 65毫秒,所以SUT[0]应该设置为1。另外,CKSEL[0]应该设置为1。

因此,第7位是1,第6位是1,第5位是1,第4位是1,第3-0位是1111。因此,新的Fuse低字节应该是11111111,在十六进制符号中,是0xFF。唷!你终于到了!

Avrdude

Avrdude是一个命令行驱动的实用程序,我们将对它进行更深入的解释这篇文章.它是唯一的软件工具,需要程序更改保险丝字节在ATmega328P和一长串其他Atmel微控制器。下面的屏幕剪辑来自avrdude与连接到ATmega328P的AVR Pocket Programmer的实际会话,如本文前面的原理图和无焊料面包板组件所示。行号已被添加到屏幕片段中,以便更容易引用编程会话的特定部分。

第1-3行是avrdude在程序启动后立即生成的。

第5行显示活动目录被更改为avrdude安装的位置。在本例中,创建和使用的目录也称为“avrdude”。您应该切换到您计算机上安装avrdude的目录。

第7行是一个命令,告诉avrdude正在使用什么程序员以及附加了什么Atmel微控制器。在这种情况下,AVR Pocket Programmer使用USBTiny驱动程序,使用的微控制器是ATmega328P。

第9-17行是avrdude的回复。第13行以十六进制表示ATmega328P签名:0x1e950f。第15行介绍了目前在ATmega328P中的保险丝位编程,也是十六进制表示法;在这种情况下,fuse字节是按工厂默认值编程的。扩展的保险丝字节是0xFF,保险丝高字节是0xD9,保险丝低字节是0x62。

第20行是一个命令,告诉avrdude正在使用什么程序员和什么Atmel微控制器是附加的,并将Fuse低字节更改为0xFF。

第22-45行是avrdude的回复。每一行显示完成的步骤,第43行显示ATmega328P中的新保险丝位编程。扩展的保险丝字节是0xFF,保险丝高字节是0xD9,保险丝低字节是0xFF。

第48行是一个命令,告诉avrdude正在使用什么程序员,附加了什么Atmel微控制器,并将Fuse低字节更改为0x62。(只有当您想要更改回原始配置时,才需要将Fuse低字节设置为0x62,因为0x62是默认值。)

第50-73行是avrdude的回复。每一行显示完成的步骤,第43行显示ATmega328P中的新保险丝位编程。扩展的保险丝字节是0xFF,保险丝高字节是0xD9,保险丝低字节是0x62。现在,保险丝字节再次按工厂默认值编程。

“燃烧”导火索低字节

一旦一切就绪(硬件和软件),实际上重新编程fuse字节是相当虎头蛇尾的;它发生得如此之快,如果你不仔细观察,你可能会错过它。因此,提供一些关于所做改变的证据是值得的。这是很容易做到的,通过使用相同的LED闪烁软件在Atmel Studio 7中编写ATmega328P & ATtiny45的面包板和编程.如果它仍然在你的ATmega328P中编程,你就领先了;如果没有,请使用下面的按钮下载并安装。

New_Blink.zip

New Blink.c黄色LED亮半秒灭半秒,每分钟60次。检查以确保它仍然在您的面包板组件中这样做。

正如您(希望)回忆的那样,ATmega328P使用其校准的内部振荡器,而不依赖于您刚刚添加的16MHz晶体振荡器。此时,由于熔断器低字节设置,晶体被忽略。(记住,保险丝低字节仍然设置为其出厂默认值0x62,这指定了内部振荡器的使用。)幸运的是,晶体和它的两个22pF电容的存在并没有阻止内部振荡器的使用。要对16MHz晶体振荡器进行更改,执行以下两个步骤。

  • 首先,启动avrdude,然后按照上面屏幕片段的第4-17行所描述的过程进行操作。结果应该确认保险丝低字节仍然设置为0x62,这指定了使用校准的内部振荡器。
  • 其次,遵循第20-45行中描述的过程。结果应该确认保险丝低字节现在更改为0xFF,这指定了晶体振荡器的使用。

手表的LED发黄;你注意到闪速变了吗?这是为什么。

fuse低字节值0x62不仅调用了内部8MHz振荡器的使用,它还指定启用了除以8特性。因此,振荡器的有效速率是1MHz,这一事实反映在下面描述的New Blink.c代码的第3行。(这是重要的第3行并不控制ATmega328P的运行速度,而是告诉编译器微控制器的运行速度应该以1MHz的速度运行,以便代码以正确的速度执行。)

因为您已经将保险丝低字节从0x62更改为0xFF,您已经将正在使用的振荡器更改为16MHz晶体。此外,您已经禁用了除以8功能。这两个变化的净效果是ATmega328P时钟现在运行在16MHz,但是New Blink.c中的第3行仍然告诉编译器微控制器运行在1MHz。因此,flash的速度是正常速度的16倍。要做什么吗?

启动Atmel Studio 7,当然要更改第3行。而不是#定义F_CPU1000000UL,使第3行读取#defineF_CPU16000000UL,它告诉编译器时钟现在运行在16MHz。然后,重新构建项目,并将修改后的代码下载到AT328P。几乎立刻,LED将恢复闪烁半秒和半秒,每分钟60次,这正是你想要的。

一个更简单的方法吗?

你可能会问:“难道没有更简单的方法吗?”答案是:“有。”有一些在线应用程序将决定保险丝字节设置,以反映所选的功能,其中最流行的是EngBedded的AVR保险丝计算器.然而,网站有消失的方式,知道如何自己做总是好的;这样,除了“做什么”之外,你还能理解“如何做”和“为什么做”。

接下来是什么?

本系列的下一篇文章将更详细地讨论Atmel Studio 7的操作,并提供一种更便宜的方法来获得真正的Atmel ICE程序员。它马上就要来了AllAboutCircuits.com

你自己试试这个项目吧!BOM。

4评论
  • R
    ROTiree 2018年3月15日

    Arduino网站上有篇文章…

    https://www.arduino.cc/en/Tutorial/ArduinoToBreadboard

    ...这似乎意味着你不需要通过所有这些来让你的ATmega328P正确运行,独立的,在16MHz的外部晶体/帽。还是我错过了什么?

    喜欢的。 回复
    • 查尔斯·r·汉普顿 2018年3月15日
      你在Arduino网站上看到的文章描述了在ATmega328P上安装一个引导加载程序,它可以有效地将ATmega328P变成一个Arduino,引导加载程序可以使用外部晶体。我的文章不涉及Arduino引导加载程序的安装,因此我所描述的步骤是使用外部晶体所必需的。谢谢你的问题。
      喜欢的。 回复
  • 查尔斯·r·汉普顿 2018年3月15日

    你在Arduino网站上看到的文章描述了在ATmega328P上安装一个引导加载程序,它可以有效地将ATmega328P变成一个Arduino,引导加载程序可以使用外部晶体。我的文章不涉及Arduino引导加载程序的安装,因此我所描述的步骤是使用外部晶体所必需的。谢谢你的问题。

    喜欢的。 回复