AVR单片机具有内部RC振荡器,对于内部振荡器的校正一直是一个比较难的问题,由于这个问题的困扰,导致很多正常的程序无法正常工作,特此整理该文档供客户参考,如果有需要英文的可以到ATMEL官方网站下载。
特点
l 可以使用 STK500, AVRISP, JTAGICE 或 JTAGICE mkII 校正
l 可以使用第三方编程器校正
l 调整 RC 频率到 +/-1% 精度
l 在任意电压和温度下调整 RC 振荡器
l 调整 RC 振荡器到指定频率
l 支持所有带有 RC 振荡器的 AVR 单片机
l 可以选择振荡器时钟频率
介绍
这篇应用笔记说明了快速和精确校正内部 RC 振荡器的方法。它提供了容易修改的固件源代码,可以用在任何带有内部可调 RC 振荡器的 AVR 单片机中。这个固件允许使用 AVR STK500, AVRISP 或 JTAGICE,但是也可以用在第三方系统中(如编程器)。
大部分 AVR 单片机提供了内部 RC 振荡器。这个 RC 振荡器的频率可以校正到 +/-1%。这个特点使其提供了更大的灵活性和节约了成本。
在 Atmel 的工厂中是在固定电压和温度下进行了校正(典型是 25°C和 5V),而内部 RC 振荡器的频率是受到温度和电压同时影响的,这使得用户在特定的应用环境时可能需要进行再次校正。再次校正可以得到更高的精度,匹配特定的电压或温度,甚至调整到一个完全不同的频率。
这篇应用笔记说明的校正方法使用的时间只比从签名中读取工厂校正字节并回写到设备中稍长。全部的编程时间几乎不受到校正的影响。
注意在某些系统中非常依赖于运行时间,这说明在应用中在整个温度范围需要一个精确的与电压无关的系统时钟。在这种情况下一个手表晶体可以提供可靠和低成本的解决方案。
在这篇文档的最后有快速开始指南。
操作理论 – 内部 RC 振荡器
在产品中内部 RC 振荡器在 5V 或 3.3V 下校正。工厂校正的精度在 +/-3 或 +/-10% (参考数据手册)。如果一个设计需要比工厂标准校正更高的精度,就需要再次校正 RC 振荡器,这样可以得到大约 +/-1%(对于工厂校正精度是+/-10%的器件是 +/-2%)的精度。
时钟选择
AVR 熔丝的设置控制了系统使用的时钟源。为了使用内部 RC 振荡器,需要选择正确的熔丝。数据手册中说明了可以使用的熔丝设置。
基本频率
下面小节给出了 AVR 单片机内部 RC 振荡器说明。
一些 AVR 单片机有一个 RC 振荡器,其它的有 4 种不同的 RC 振荡器可以选择,频率范围从 1MHz 到 9.6MHz。校正内部 RC 振荡器使用晶体校正寄存器:SCCAL(在 IO 头文件中定义了)。OSCCAL 寄存器是一个字节宽度,它可以对系统频率进行微调,校正 RC 振荡器就利用了这个微调。
当单片机被 Atmel 校正后,校正字节就存放到单片机的签名中。不同芯片的校正字节之间差异可能很大,因为 RC 振荡器与工艺有关,有一定离散性。如果芯片有多于一个振荡器,那每个振荡器都对应一个校正字节。
大多数单片机的缺省 RC 校正字节在复位时自动从签名中载入,并复制到 OSCCAL 寄存器中。例如,ATmega8 的默认时钟设置是内部 1MHz RC 振荡器;对应的 1MHz 校正字节在复位后自动载入。如果熔丝改变为 4MHz 振荡器,校正字节就需要手工载入 OSCCAL 寄存器了。编程工具可以从签名中读取 4MHz 校正字节并强制存放到 Flash 或 EEPROM 中,然后由用户程序在运行时读取出来再复制到 OSCCAL 寄存器中。
为了容易使用 OSCCAL 寄存器调整振荡器,一些单片机可以设置系统的预分频时钟。预分频寄存器(CLKPR) 可以用预定义的系数比例变化系统时钟。同样,这个预分频可以通过熔丝预先设置;编程 CKDIV8 熔丝就设置 CLKPR 系统时钟分频 8。这可以保证芯片在低于最大频率下操作,CLKPR 可以在运行时修改。
基本频率是定义为不分频。
RC振荡器总结
AVR 单片机在不同时期使用了不同的 RC 振荡器。一个关于 RC 振荡器的回顾参见表1。芯片列表按照振荡器类型排序,也差不多是按照发布时间排序的。表中只列出了可以调整振荡器的芯片。
表1.带有内部 RC 振荡器的芯片特点,按照版本分类
振荡器版本 器件 RC 振荡器频率 CKDIV PRSCK
1.1 ATtiny12 1.2 - -
1.2 ATtiny15 1.6 - -
2.0 ATmega163 1.0 - -
2.0 ATmega323 1.0 - -
3.0 ATmega8 1.0,2.0,4.0和8.0 - -
3.0 ATmega16 1.0,2.0,4.0和8.0 - -
3.0 ATmega32 1.0,2.0,4.0和8.0 - -
3.1 ATmega64 1.0,2.0,4.0和8.0 - XDIV(1)
3.1 ATmega128 1.0,2.0,4.0和8.0 - XDIV(1)
3.0 ATmega8515 1.0,2.0,4.0和8.0 - -
3.0 ATmega8535 1.0,2.0,4.0和8.0 - -
3.0 ATmega26 1.0,2.0,4.0和8.0 - -
4.0 ATmega162 8.0 是 是
4.0 ATmega169(2) 8.0 是 是
4.0 ATmega165 8.0 是 是
4.1 ATmega13 4.8和9.6 是 是
4.2 ATmega2313 4.0和8.0 是 是
5.0 ATmega48
ATmega88
ATmega168 8.0 是 是
5.0 ATmega25
ATmega45
ATmega85 8.0 是 是
5.0 ATmega325
ATmega3250
ATmega645
ATmega6450 8.0 是 是
5.0 ATmega329
ATmega3290
ATmega649
ATmega6490 8.0 是 是
5.0 AT90CAN128 8.0 是 是
5.0 AT90PWM2
AT90PWM3 8.0 是 是
注意:
1. 这个器件的预分频寄存器叫做 XDIV。
2. ATmega169 修订 F 使用 5.0 版本的振荡器。
版本1.X
这个版本是 AVR 单片机最早的可以校正的内部 RC 振荡器,它提供了 1.2MHz 到 1.6MHz 的频率。校正值存放在签名中,但是不能自动载入,必须在运行时手工加载到 OSCCAL 寄存器。这个版本的振荡器的频率高度依赖于工作电压和温度。
版本2.X
这个版本的振荡器提供了 1MHz 频率。与1.x版本相比,显著的减少了对电压和温度的依赖性。
版本3.X
这个版本和35.5k工艺一起引入。
扩展振荡器提供多个频率,4种不同的 RC 振荡器,频率分别是 1, 2, 4 以及 8MHz。这个版本自动载入 1MHz 的校正值。因为有4个不同 RC 振荡器,所以在签名中保存了 4 个校正值。如果使用了不是缺省的 1MHz 频率,OSCCAL 寄存器需要运行时手工加载校正值。
版本4.X
版本4.0中只保留了 8MHz 的振荡器。稍晚一些的 4.x 版本中提供了两种频率:4MHz 和 8MHz(ATtiny2313),4.8MHz 和 9.6MHz(ATtiny13)。OSCCAL 寄存器修改为只有 7 位用于调整选择的频率,最高位没有使用。可以自动载入校正值和预分频时钟。
版本4.X
版本5.0中只有8MHz时钟,OSCCAL中所有的8位都可以用于调整频率,可以自动载入校正值和预分频时钟。OSCCAL寄存器分为两个部分,OSCCAL的最高位选择频率范围,后7位用于调整指定的频率。
振荡器特性
内部 RC 振荡器的频率依赖于温度和工作电压。图1显示了ATmega169 (版本 A 到 E)的 8MHz RC 振荡器的频率。如图所示,频率随着温度而增加,随着电压的增加而稍微降低,这个特性随芯片不同而变化。对于某种具体型号的芯片参考数据手册。
图1.晶体频率和变化与温度和电压关系(ATmega169)
(MHz)
Vcc(V)
所有带有可调整振荡器的芯片都有 OSCCAL 寄存器。增加 OSCCAL 将得到一个称为“伪单调”(pseudo-monotone)增加的频率。把它称为“伪单调”的原因是因为在某些情况下改变 OSCCAL 寄存器的参数将不会增加或减少频率,但是再次改变就会增加频率了。换句话说,OSCCAL 寄存器加上 1 可能不增加频率,但是加上 2 一般都会使频率增加。这一特点对于搜索最佳校正值很重要。一个伪单调的例子可以从图2看出,它是 ATmega169 的 8MHz RC 振荡器的例子。注意到 OSCCAL 寄存器只使用了 7 位(8 位在 ATmega169 修订版本 F 及以后版本中),这样 OSCCAL 的最大值是 128。
图2. ATmega169 校正 RC 振荡器频率
(MHz)
晶体参数
对于所有可以调整的振荡器,不推荐调整频率超过指定基本频率的 10%,因为内部定时是依赖于 RC 振荡器的。
知道了 RC 振荡器的基本特性,就可以在 10% 的范围内,在任何工作电压和环境温度下,将给定的频率校正到 +/-1% 的精度。
进行校正
这一节分为协议和固件程序两部分。协议是为了适应任何支持校正的编程工具,如 AVR 的开发工具STK500, AVRISP, JTAGICE 和 JTAGICE mkII,这些工具校正的用法在后面说明。
STK500, AVRISP, JTAGICE 和 JTAGICE mkII 目前只支持命令行版本的校正,由 AVR Studio 4.11 SP1 (及以后版本)支持。最新版本的 AVR Studio 可以在 http://www.atmel.com/avr/ 下载。
校正协议
校正协议是简单快速的,以保证可以用于产品中。编程使用的管脚是 ISP 接口或 JTAG 接口(如果有),使其可以用于最终产品中(或PCB)。
两个管脚用于进行校正: ISP 中的 MOSI 和 MISO,或 JTAG 中的 TDI 和 TDO。这里为了简单只说明 MOSI 和 MISO,TDI 和 TDO 的用法是一样的。
基本概念就是编程器产生校正时钟(C-clock),单片机使用它作为参考来校正自己的内部 RC 振荡器。当单片机完成校正后通过 MISO 发送 “OK”信号给编程器。编程器允许 MISO 信号线上拉,而单片机允许 MOSI 信号线上拉,这是为了保证噪声不影响校正。
编程器使用 1024 C-cycles (C-clock 周期)作为溢出时间,校正程序在这个时间内完成
校正程序按一下步骤运行:
1. 编程器写入校正固件程序到单片机中,允许 MISO 上拉,并释放 reset 信号线。校正时钟发送到 MOSI 信号线。手表晶体(32.768kHz)的频率是合适的。
2. 单片机允许 MOSI 内部上拉,并开始监听 MOSI 上的校正时钟信号。
3. 当单片机检测到用于二进制搜索的校正时钟达到 1% 精度,如果不是需要的参数值,那么就把邻近值作为结果,并进行验证
4. 校正值存放到 EEPROM 中(在校正失败时,忽略这个步骤)。
5. 当成功完成校正后,翻转 MISO 信号 4 次。在 MOSI 时钟下降沿时执行 MISO 翻转 5 到 10 个 CPU 周期(C-clock)。在校正失败时,不进行这一步。
6. 如果单片机没有 EESAVE 熔丝,编程器必须取回 EEPROM 中的校正值以便恢复,因为稍后固件程序将被从 Flash 中擦除。如果有 EESAVE 熔丝,就设置这一位,这样在擦除 Flash 时就不会擦除 EEPROM 了。
必须在运行时从 EEPROM 复制校正参数到 OSCCAL 寄存器,为此需要在最终的固件程序中执行它。
校正固件程序
校正代码是用汇编写的,对于 AVR Studio 4.11 已经安装了带有校正包的汇编。
校正固件程序是按照方便修改为任何型号的单片机(表1中)来组织的。同样,校正的接口也可以被修改。如果使用 AVR 的开发工具,所有需要进行的修改都在文件 “RC_Calibration.asm”中。
文件包括下面内容:
1. 指定芯片文件(选择和你的系统对应的),如 “m16.asm”是 Atmega16 的。芯片指定文件包括下面内容:
a. AVR Studio 的寄存器和位定义。
b. 定义的内存映射文件,指定代码的位置和存放在 EEPROM 的校正数据的位置。
c. OSCCAL 访问的宏,控制怎样对 OSCCAL 寄存器进行访问。访问 OSCCAL 寄存器的方法与 IO 文件和 OSCCAL 寄存器的位置有关。
d. 振荡器版本文件。这个文件定义了二进制搜索的初始化步骤,因为一些 OSCCAL 寄存器是 7 位,另外的是 8 位的。
e. 返回堆栈初始化宏文件。一些芯片有硬件堆栈,另外的使用软件堆栈,需要进行初始化。
f. 端口访问宏文件,定义了怎样访问与校正相关的端口的相关寄存器。需要这个文件是因为一些寄存器在 IO 文件的高端部分,而其它的在低端部分。
g. 重定义位和寄存器名。
请注意使用 ATmega169 修订版F 的芯片时需要修改芯片的特殊文件,在“m169.asm”文件中振荡器版本要设置成 5。
2. 校正接口文件。这个文件指定使用 ISP 或 JTAG 端口,以及使用的管脚名。校正时钟频率也在这里指定。
3. 包含使用宏定义的文件 - “macros.inc”。
4. 公共的校正代码文件 “main.asm”。
校正代码的结构是按照易于修改而设计的,可以更简单的适应目标系统的单片机和接口。此外,广泛使用了宏定义保证了代码可以只要最小的改动。最后,芯片和校正接口的设计使得只需很小的改动就可以支持新的器件。
二进制搜索算法
这个搜索是基于二进制搜索的, a divide-and-conquer method:
1. OSCCAL 寄存器载入初始值,就是 OSCCAL 最大值的一半。OSCCAL 的初始值在初始化步骤中定义了。
2. 系统时钟频率和外部参考进行比较,校正时钟:
a. 如果频率精度在 1% 之内,跳到第5步。
b. 如果系统时钟太快,就减少 OSCCAL 的值;如果时钟太慢,就增加。跳到第3步。
3. 步进值修改为以前的一半
a. 如果步进值达到0,二进制搜索失败,跳到第4步。
b. 如果步进值大于0,在当前的 OSCCAL 上加或减去步进值,重复第2步。
4. 测试与 OSCCAL 最邻近的 4 个点,这是为了补偿振荡器频率的伪单调性。
a. 如果测试后 OSCCAL 的参数满足精度要求,跳转到第5步。
b. 如果没有一个点满足要求,MISO 保持低电平表示校正失败。
5. 存储校正值到 EEPROM。
6. MISO 翻转4次表示校正频率成功。
决定振荡器频率的方法
在校正时钟 (C-clock) 和内部 RC 振荡器之间的比较使用了 8位定时器/计数器0 (TC0),使用8位定时器是因为它在所有的带有可调 RC 振荡器的单片机中都有。计时40个 C-clock 周期cycles 然后比较定时器计数, C-frequency 在接口文件中指定。决定频率的方法在流程图中说明了。
图3. 决定振荡器频率方法的流程图
为了覆盖到振荡器频率的整个范围,从 1MHz 到 9.6MHz,通过检查 TC0 溢出标志(OVF) 来扩展定时器,得到了一个16位定时器。OVF 标志每半个周期(Cclock)检查一次,可以充分保证检查到所有的 TC0 OVF 标志。因为使用 16位定时器的关系,最差的情况是在 9.6MHz 时,OSCCAL 寄存器载入 0xFF。在这个情况下,振荡器能 100% 高于指定频率,定时器计数到 23,541,在16位计数范围中。
从另外一个方面看,最低的振荡器频率也必须被考虑。最低可以得到的频率是写入 0x00 到 OSCCAL 寄存器时,此时频率可能低于指定频率的 50%。因为 TC0 OVF 标志位每半个周期检查一次,只有不超过7个CPU周期来处理 OVF 标志位以及检测 C-clock 沿 –在指定的 1MHz 频率下。当 OVF 标志位没有设置时会遇到这个时间约束,而设置标志位需要 8 个周期,这样当检测时间时将引起一个小错误,不过不影响最后的结果:振荡器被判断为太慢。
这些极端一般不会遇到,但是需要考虑到它们。
修正时间错误
因为不能使用中断来检测 C-clock 的沿,只能使用轮询法。这样的结果是检测可能会有 2 个CPU 周期的延时,使校正可能失败。为了补偿这个时间误差,收缩门限 2 个 ticks (2 个CPU周期)。
所有参数和门限的计算由单片机完成,使用了 32 位精度(在AVRASM中)或 64 位精度(在 AVRASM2中)。
校正固件程序不能用于校正时钟源,参考这篇文档 “校正时钟精度”的小节。
使用STK500,AVRISP,JTAGICE或JTAGICE mkII进行校正
校正固件的源码和批处理文件是作为怎样使用 STK500, AVRISP, JTAGICE 或 JTAGICE mkII 进行校正的例子来提供的。固件几乎不需要就可以用于其它校正系统上。
编译校正固件
校正固件的主程序是 RC_Calibration.asm。这个文件需要在AVR Studio中添加到一个汇编工程里。在这个文件中指定了单片机型号和使用的校正接口:STK500, AVRISP, JTAGICE 或 JTAGICE mkII。甚至还可以指定校正的精度。
一旦修改这些选项,编译工程产生一个二进制文件 “rc_calib.hex”,就是使用这个文件进行校正。
注意正确设置熔丝很重要:如果选择了 1MHz RC 振荡器,就不能校正为单片机 8MHz。
使用命令行工具
STK500, AVRISP, JTAGICE 和 JTAGICE mkII 目前只支持以命令行方式调用的工具 (AVR Studio 4.11 SP1 及以后版本)。提供这种支持的软件包可以在http://www.atmel.com/avr/中查找到。
软件包中包括了校正需要的新固件程序。当第一次连接到AVR Studio时固件自动进行更新,或者按照AVR Studio帮助文件中的说明进行手工更新。
单独提供了3个批处理文件,这些文件展示了怎样使用命令行工具编程校正代码到用户系统,执行校正和用最终的固件再编程。批处理文对 ATmega16 通过 STK500 或 ISP, JTAGICE 和 JTAGICE mkII 分别进行校正。请研究这些批处理文件和 AVR Studio 帮助来了解 STK500/ISP, JTAGICE 和 JTAGICE mkII 命令行工具的用法。表2 包括了新命令列表。
表2. stk500.exe 和 jtagice.exe 新选项
命令 说明
-Z[addr] 从EEPROM读取校正字节,addr是读取的地址。读取操作在芯片擦除命令前执行,使用 “-S#”将在芯片擦除后重新写入参数到flash或EEPROM中。
-Y 按次序执行校正,这个命令不考虑其它所有操作。如果没有获得响应信号,返回错误级别1。
支持新型号
为了支持新型号的器件,所需要的就是复制一个类似的设备文件(最好引脚兼容),并修改新型号的特点。下面步骤用ATmega8535为例显示了这一过程:
1. 复制引脚和功能兼容的设备文件。
ATmega8535 和 ATmega16 引脚兼容,但是 ATmega8535 没有 JTAG 接口。复制文件 “m16.asm”并改名为 “m8535.asm”。
2. 修改寄存器和位定义文件,以适合新的型号。
对于 ATmega8535 定义寄存器和位变量的文件是 “m8535.inc”。
3. 修改引脚输出描述文件以适合新器件。
因为 ATmega8535 没有 JTAG 接口,修改引脚输出文件为 “s8535_family_pinout.inc”。
4. 修改新型号器件对应的振荡器版本文件。
5. 在 RC_Calibration 文件中添加新器件到设备列表。
对程序进行编译验证是否正确。如果错误,一般都是因为修改了寄存器或位变量名、端口、引脚或者定时器引起的。
固件的性能
代码有如下特点:整个校正运行相当快速,其性能依赖于校正固件的大小和完成校正的时间。校正固件有 183 到 240 个字节,与用户系统和使用的接口有关。固件编程需要的时间非常短。
校正程序完成时间少于 1024 个校正周期,最短时间与二进制搜索搜索速度和写EEPPROM时间有关。目前,使用 STK500.exe 或 JTAGICE.exe,校正时间少于 32ms。
校正时钟精度
校正的精度高度依赖于外部校正时钟。由 AVR 工具产生的校正时钟的频率可能发生变化,所以要测量出使用的准确频率并输入到接口源文件中。因为振荡器与工作电压和温度都有关,校正频率要在相同的条件下进行测量。
快速开始指南
参考下面的步骤:
1. 下载并解压 AVR053 的源代码(可以放在任何位置,这里写为 \AVR053\)。
2. 从http://www.atmel.com/avr/下载并安装 AVR Stdio 4.11 SP1。
3. 打开 AVR Studio,创建新工程”rc_calib”,并添加源文件 RC_Calibration.asm 到工程中。
4. 在RC_Calibration.asm中选择用户系统的单片机(添加或删除设备行前面的分号)。
5. 选择接口,和选择单片机一样。
6. 使用频率计测量出校正时钟的频率。这个信号在STK500/AVRISP 的MOSI 引脚,或者 JTAG ICE的TDI引脚。在接口文件的行 ”.EQU CALIB_CLOCK_FREQ = XXXX” 中修改频率。
7. 指定用户系统期望的频率和精度。注意精度太高会可能校正失败,参考数据手册查看可能达到的精度。
8. 编译工程产生 hex 二进制文件。
9. 如果使用 STK500/AVRISP 进行校正:
a. 在文本编辑器中打开批处理文件 ”\AVR053\AVR Asm\Batch file\ISP_rc_calib.bat” (使用命令行 STK500.exe -h 查看相关参数的信息)。
b. 编辑文件,对应使用的单片机型号。修改 -datmega16 参数为 -d[用户型号]。
c. 修改熔丝设置,确定熔丝设置是校正需要的:选择 8MHz 内部 RC 如果需要校正单片机到 8MHz。熔丝设置通过参数 -E(扩展熔丝)和 -f(高/低熔丝)设置。确认熔丝设置中看门狗定时器总是关闭。
d. 如果 AVR Studio 的安装路径和批处理文件的不同(标准英文 Windows 版本),请修改 stk500.exe 的路径。
e. 保存文件。
10. 如果使用 JTAGICE 校正:请注意复位必须可用。
a. 打开文件 ”\AVR053\AVR Asm\Batch file\JTAGICE_rc_calib.bat”(使用命令行方式jtagice.exe -h 查看详细参数)。
b. 编辑文件,修改单片机型号,修改 -datmega16 参数为 -d[用户型号]。
c. 修改熔丝设置。确定熔丝设置是正确的:如果校正单片机到 8MHz 就选择 8MHz 内部 RC 振荡器。熔丝设置通过参数 -E(扩展熔丝)和 -f(高/低熔丝)设置。确认熔丝设置中看门狗定时器总是关闭。
d. 如果 AVR Studio 的安装路径不同于批处理文件(标准英文 Windows 版本),请修改jtagice.exe 的路径。
e. 保存文件。
11. 如果使用 JTAGICE mkII 进行校正:请注意复位可用
a. 打开文件 ”\AVR053\AVR Asm\Batch file\JTAGICE_mkII_rc_calib.bat”(使用命令行方式 jtagiceii.exe -h 查看详细参数设置)。
b. 编辑文件,修改单片机型号,修改 -datmega16 参数为 -d[用户型号]。
c. 修改熔丝设置。确定熔丝设置是正确的:如果校正单片机到 8MHz 就选择 8MHz 内部 RC 振荡器。熔丝设置通过参数 -E(扩展熔丝)和 -f(高/低熔丝)设置。确认熔丝设置中看门狗定时器总是关闭。
d. 如果 AVR Studio 的安装路径不同于批处理文件(标准英文 Windows 版本),请修改jtagiceii.exe 的路径。
e. 保存文件。
12. 连接 STK500, AVRISP, JTAGICE 或 JTAGICE mkII 到用户板,并给它们上电。检查串口线与计算机连接好。
13. 打开 windows 的 DOS 方式,切换到目录 ”\AVR053\AVR Asm\Batch file\”。执行批处理文件(ISP_rc_calib.bat, JTAGICE_rc_calib.bat 或 JTAGICE_mkII_rc_calib.bat)。
14. 等待校正完成。
批处理文件也可以修改为在校正后编程自定义的固件代替 test.hex。要清楚新的校正值要在运行时由固件载入 OSCCAL 寄存器。
评论
查看更多