当前位置:首页 >> 机械/仪表 >>

avr单片机


AVR 单片机特点
每种 MCU 都有自身的优点与缺点,与其它 8-bit MCU 相比,AVR 8-bit MCU 最大的特点是: ● 哈佛结构,具备 1MIPS / MHz 的高速运行处理能力; ● 超功能精简指令集(RISC),具有 32 个通用工作寄存器,克服了如 8051 MCU 采用单一 ACC 进行处理造成的瓶颈现象; ● 快速的存取寄存器组、单周期指令系

统,大大优化了目标代码的大小、执行效率,部分型号 FLASH 非常大,特别适用于使用高级语言进行开发; ● 作输出时与 PIC 的 HI/LOW 相同,可输出 40mA(单一输出),作输入时可设置为三态高阻抗 输入或带上拉电阻输入,具备 10mA-20mA 灌电流的能力; ● 片内集成多种频率的 RC 振荡器、上电自动复位、看门狗、启动延时等功能,外围电路更加简 单,系统更加稳定可靠; ● 大部分 AVR 片上资源丰富: E2PROM, 带 PWM, RTC, SPI, UART, TWI, ISP, Analog Comparator, AD, WDT 等; ● 大部分 AVR 除了有 ISP 功能外,还有 IAP 功能,方便升级或销毁应用程序。 ● 性价比高。

开发 AVR 单片机,需要哪些编译器、调试器?
软件名称 类型 简介
ATMEL AVR Studio 集成开发环境(IDE),可使用 AVR Studio IDE、汇编编 汇编语言进行开发(使用其它语言需第三方软件协 译器 助),集软硬件仿真、调试、下载编程于一体。ATMEL 官方及市面上通用的 AVR 开发工具都支持 AVRStudio。 GCC 是 Linux 的唯一开发语言。 的编译器优化 GCC 程度可以说是目前世界上民用软件中做的最好的,另 GCCAVR (WinAVR) C 编译器 外,它有一个非常大优点是,免费!在国外,使用它 的人几乎是最多的。但,相对而言,它的缺点是,使 用操作较为麻烦。 C 编译器 ICC AVR (集烧写程 序功能) C 编译器 序功能) ATman AVR C 编译器 市面上(大陆)的教科书使用它作为例程的较多, 集成代码生成向导,虽然它的各方面性能均不是特别 但,它有 Demo 版本,在 45 天内是完全版。 与 KeilC51 的代码风格最为相似,集成较多常用 块,不是免费软件,Demo 版为限 2KB 版。 支持多个模块调试 (AVRStudio 不支持多个模块调试) www.atmanecl.com 。 IAR 实际上在国外比较多人使用,但它的价格较 IAR AVR C 编译器 为昂贵,所以,中国大陆内,使用它的开发人员较少, 只有习惯用 IAR 的工程师才会去使用它。 www.iar.com www.imagecraft.com 突出, 但使用较为方便。 虽然 ICCAVR 软件不是免费的, sourceforge.net www.atmel.com

官方网址

CodeVision AVR (集烧写程 外围器件的操作函数,集成代码生成向导,有软件模 www.hpinfotech.ro

AVR 的仿真方式

一般来说,AVR 有三种仿真方式: (1)JTAG 仿真方式,适用于具备 JTAG 仿真接口的 AVR。如:Atmega16/32, Atmega64/128 等。 JTAG 是 IEEE 的标准规范, 通过这个标准,可对具有 JTAG 接口的芯片的硬 件电路进行边界扫描和故障检测。部分 AVR 型号带 JTAG 仿真调试接口,可使用 JTAG 仿真方式。 (2)debugWIRE 仿真方式,适用于具备 debugWIRE 仿真接口的 AVR。如: Attiny13/24/2313,Atmega48/88/168 等。 debugWIRE 是用以降低成本和调试引脚的开销,ATMEL 在 AVR 器件上使用的 新的调试接口:debugWIRE,与 JTAG 相比其主要区别在于仅使用一根信号线 (RESET),即可完成调试信息的交互,达到控制程序流向,执行指令以及编程 熔丝位的功能。它的总的连接图如下:

这里的 RESET 信号被用于传递调试信息。 (3)采用仿真头替代 AVR MCU 仿真方式,适用于不带仿真接口的 AVR。如 Attiny26,Atmega8,Atmega8515 等

AVR 单片机基本硬件电路设计包括:AVR 复位电路和下载电路的设计,另外 AVR 晶振电路可以不加。
● AVR 复位电路的设计

与传统的 51 单片机相比,AVR 单片机内置复位电路,并且在熔丝位里,可 以控制复位时间,所以,AVR 单片机可以不设外部上电复位电路,依然可以正常 复位,稳定工作。 若是系统需要设置按键复位电路,那么注意,AVR 单片机是低电平复位,如 下图,设计按键复位电路:

● AVR 下载电路的设计

一般来说,AVR 的编程方式有: (1)串行编程,ISP 编程 (2)高压/并行编程 (3)JTAG 编程 (4)IAP 编程 一般情况,系统板都需要设计下载线路,对 AVR 进行编程。目前的 AVR 芯片基本上都具备 ISP 接口, 可通过 ISP 接口进行编程。所以,最常见的是,在系统板上留 ISP 接口。 那么什么是 ISP 呢? ISP 是 In System Program 的缩写,意思是在系统编程,亦即是在线编程。它一共使用了两条电源线: VCC、GND,三条信号线:SCK、MOSI、MISO,以及复位线:RESET。由于仅仅使用了几条数据线,所以我们 亦常将其称为串行编程。 值得注意的是:大部分 AVR 的 ISP 数据端口亦为 SCK、MOSI、MISO 引脚(如 tiny13/24/2313, mega48/88/168/8,mega16/32/162 等),如下: [调试器] [目标 MCU] VCC -------- VCC GND -------- GND RESET -------- RESET SCK -------- SCK MOSI -------- MOSI MISO -------- MISO

● AVR 晶振电路的设计 与传统的 51 单片机相比,AVR 单片机内置 RC 振荡电路。出厂时,未进行时钟源设置的 AVR,其时钟源 使用的是内部 RC 振荡,一般情况使用的是 1M 频率。 通过对熔丝位的设置,可以设置 MCU 的内部 RC 振荡频率。例如:4M、8M 等。 不过,内置 RC 振荡,在一致性方面存在差异,它因生产的批次有所差异,亦与温度等因素有较大的相 关性。所以,在一些对时钟要求较高的场合,如:精确定时,RS232 通信等,这些场合,建议使用外部的 晶振线路。

AVR 教程(1):AVR 单片机介绍

作者:微雪电子 文章来源:www.waveshare.net 点击数:

478 更新时间:2008-4-1 23:58:21

AVR,它来源于:1997 年,由 ATMEL 公司挪威设计中心的 A 先生与 V 先生利用 ATMEL 公司的 Flash 新 技术,共同研发出 RISC 精简指令集的高速 8 位单片机,简称 AVR。

AVR 单片机特点
每种 MCU 都有自身的优点与缺点,与其它 8-bit MCU 相比,AVR 8-bit MCU 最大的特点是: ● 哈佛结构,具备 1MIPS / MHz 的高速运行处理能力; ● 超功能精简指令集(RISC),具有 32 个通用工作寄存器,克服了如 8051 MCU 采用单一 ACC 进行处理造成的瓶颈现象; ● 快速的存取寄存器组、单周期指令系统,大大优化了目标代码的大小、执行效率,部分型号 FLASH 非常大,特别适用于使用高级语言进行开发; ● 作输出时与 PIC 的 HI/LOW 相同,可输出 40mA(单一输出),作输入时可设置为三态高阻抗 输入或带上拉电阻输入,具备 10mA-20mA 灌电流的能力; ● 片内集成多种频率的 RC 振荡器、上电自动复位、看门狗、启动延时等功能,外围电路更加简 单,系统更加稳定可靠; ● 大部分 AVR 片上资源丰富:带 E2PROM,PWM,RTC,SPI,UART,TWI,ISP,AD,Analog Comp arator,WDT 等;

● 大部分 AVR 除了有 ISP 功能外,还有 IAP 功能,方便升级或销毁应用程序。 ● 性价比高。

开发 AVR 单片机,需要哪些编译器、调试器?
软件名称 类型 简介
ATMEL AVR Studio 集成开发环境(IDE),可使用 AVR Studio IDE、汇编编 汇编语言进行开发(使用其它语言需第三方软件协 译器 助),集软硬件仿真、调试、下载编程于一体。ATMEL 官方及市面上通用的 AVR 开发工具都支持 AVRStudio。 GCC 是 Linux 的唯一开发语言。 的编译器优化 GCC 程度可以说是目前世界上民用软件中做的最好的,另 GCCAVR (WinAVR) C 编译器 外,它有一个非常大优点是,免费!在国外,使用它 的人几乎是最多的。但,相对而言,它的缺点是,使 用操作较为麻烦。 C 编译器 ICC AVR (集烧写程 序功能) C 编译器 序功能) ATman AVR C 编译器 市面上(大陆)的教科书使用它作为例程的较多, 集成代码生成向导,虽然它的各方面性能均不是特别 www.imagecraft.com 突出, 但使用较为方便。 虽然 ICCAVR 软件不是免费的, 但,它有 Demo 版本,在 45 天内是完全版。 与 KeilC51 的代码风格最为相似,集成较多常用 块,不是免费软件,Demo 版为限 2KB 版。 支持多个模块调试 (AVRStudio 不支持多个模块调试) www.atmanecl.com 。 IAR 实际上在国外比较多人使用,但它的价格较 IAR AVR C 编译器 为昂贵,所以,中国大陆内,使用它的开发人员较少, 只有习惯用 IAR 的工程师才会去使用它。 www.iar.com sourceforge.net www.atmel.com

官方网址

CodeVision AVR (集烧写程 外围器件的操作函数,集成代码生成向导,有软件模 www.hpinfotech.ro

AVR 的仿真方式
一般来说,AVR 有三种仿真方式: (1)JTAG 仿真方式,适用于具备 JTAG 仿真接口的 AVR。如:Atmega16/32,At mega64/128 等。 JTAG 是 IEEE 的标准规范, 通过这个标准,可对具有 JTAG 接口的芯片的硬 件电路进行边界扫描和故障检测。部分 AVR 型号带 JTAG 仿真调试接口,可使用 JTAG 仿真方式。 (2)debugWIRE 仿真方式,适用于具备 debugWIRE 仿真接口的 AVR。如:Attin y13/24/2313,Atmega48/88/168 等。 debugWIRE 是用以降低成本和调试引脚的开销,ATMEL 在 AVR 器件上使用的 新的调试接口:debugWIRE,与 JTAG 相比其主要区别在于仅使用一根信号线(R

ESET),即可完成调试信息的交互,达到控制程序流向,执行指令以及编程熔丝 位的功能。它的总的连接图如下:

这里的 RESET 信号被用于传递调试信息。 (3)采用仿真头替代 AVR MCU 仿真方式,适用于不带仿真接口的 AVR。如 Atti ny26,Atmega8,Atmega8515 等。

AVR 的烧写方式
一般来说,AVR 的编程方式有: (1)串行编程(即 ISP 编程) ISP 是 In System Program 的缩写,意思是在系统编程。目前的 AVR 芯片基 本上都具备 ISP 接口,可通过 ISP 接口进行编程。它一共使用了两条电源线:V CC、GND,三条信号线:SCK、MOSI、MISO,以及复位线:RESET。由于仅仅使用 了几条数据线,所以我们亦常将其称为串行编程。值得注意的是,虽然下载器端 使用的信号线名为 SCK、MOSI、MISO,但 AVR MCU 的信号端不一定是名为 SCK、M OSI、MISO。 AVR 的串行编程方式有很多种,如: (1)STK200/STK300:并口下载器多采用该烧写方式,最早期的一种烧写方 式,支持型号少,烧写速度低,不支持 AVR Studio。 (2)STK500:ATMEL 最推荐的编程方式,由于采用 ATMEL 官方的 STK500 固 件, 使得它可烧写全系列 AVR 若对固件进行升级亦可支持未来的 AVR 型号) ( , 烧写速度非常快,支持 AVR Studio。 (3)AVRISP(准 STK500):由于采用 ATMEL 官方的 STK500 固件,使得它可 烧写大部分 AVR(若对固件进行升级亦可支持未来的 AVR 型号),烧写速度 非常快,支持 AVR Studio。

(4)AVRISPmkII:由于采用 ATMEL 官方的 AVRISPmkII 固件,使得它可烧写 大部分 AVR(若对固件进行升级亦可支持未来的 AVR 型号),烧写速度非常 快,支持 AVR Studio。 (5)当然还有其它的 ISP 方式,但已经那些均不是最为常见的串行编程方 式,在此不在作一一介绍。 (2)高压/并行编程 AVR 的高压编程/并行编程,实际上是更早出现的编程方法,它功能强大, 但需要: 1)连接较多的引脚(故称“并行编程”) 2)使用 12V 电压(故称“高压编程”) 联合起来一般叫高压/并行编程。实际上,有些编程是高压/串行编程, 如 Attiny13。(Attiny13 端口非常少)高压/并行编程(理论上)能修 复任何熔丝位,例如: 1)Attiny13/24/2313、Atmega8/48/88/168 等 AVR 的 RESET 端口与 IO 端口是共用的,由于这类 AVR 的引脚一般较少,(如 Attiny13 仅有 6 个 IO 口),经常出现 IO 不够用的情况,需要将 RESET 端口设置为 IO 端口使用,然而,一旦将 RESET 设置为 IO,便无法再进行 ISP 编程了, 更无法使用 ISP 恢复 RESET 功能,因为 ISP 编程需要 RESET 功能。然而, 这种情况下,使用高压/并行编程,可以恢复 RESET 功能,(注意:RES ET 端口与 IO 端口是共用的 AVR,具备 debugWIRE 功能,“dW”熔丝位必 须为启动状态)因为高压/并行编程不需要 RESET 功能。 2)当设置错了熔丝位导致芯片锁死,这种情况下,使用高压/并行编程, 可恢复熔丝位。 (3)JTAG 编程 JTAG 烧写方式仅适用于带 JTAG 接口的 AVR,另外,JTAG 对比 ISP 烧写方式 主要有个缺点:必须占用 JTAG 对应的 IO 端口。例如,ATMEGA16 必须占用 PC2PC5 这几个端口。然而,有时候,缺点也是优点,因为对于 IO 够用的 AVR 来说, 在产品开发过程,可以用 JTAG 接口来仿真调试,产品量产后,产品板预留的 JT AG 接口还可以用来烧写程序。

(4)IAP 编程 AVR MCU 的 ISP 功能和 debugWIRE 功能是互斥的,也就是说,使能了 AVR MC U 的 debugWIRE 功能后 ISP 功能就无法使用,使能了 ISP 功能后 debugWIRE 功 能就无法使用。 那么,怎样确定 AVR 的 RESET 引脚 为 ISP 功能使用还是 debugWIRE 功能使 用呢? 在具备 debugWIRE 的 AVR 器件中,有一个可编程的熔丝位 DWEN,如果该熔 丝被编程(且 lockbits 未被编程),则 debugWIRE 功能被启用,AVR 的 RESET 引脚将被作为 debugWIRE 功能使用,可与调试器进行 debugWIRE 仿真通信(此 时,ISP 功能被禁用)。AVR 芯片出厂时,DWEN 熔丝位是未编程的,也即是说 I SP 功能是使能的,debugWIRE 被禁用。使用 ISP 功能时,通过调试器对 debug WIRE 熔丝进行编程使能,可启用 debugWIRE 功能;使用 debugWIRE 功能时,对 通过调试器对 debugWIRE 熔丝禁止,可使能 ISP 功能。

编程语言建议使用 C 而不是汇编开发 AVR
首先说说 C 的优点。
1、直观,可读性强:这点很重要。对于一个产品,周期是很长的,即使出第一

台产品之后,还有很长的维护时间。这中间维护人员可能经常变动,如果可读性 强, 将给维护工作省下很大的成本。 即使是在开发, 可读性强的程序也便于查错。

2、模块化可以做的很好:这点也是很重要的。模块化做得好,当然程序得重用

性就高。对于公司来说,这一点是关系到公司长远发展的。程序可以重用,说明 下一次开发的投入就可以减少,时间也可以加快,多好的事呀。 还有很多有点,当然也就是高级语言相对于汇编语言的优点,这里就不一 一列举了。 再来看看汇编的优点:应该来说,汇编语言操作硬件直观,对于硬件非常 熟悉的人来说,直接操作很方便。另外可能就是很多人说的效率要高了。 针对以上两点我来说说,首先“汇编语言操作硬件直观”,这是在代码编写 阶段,对于整个产品周期来说,应该是要避免使用汇编语言的,这个在 C 语言的

优点中已经说明。 对于第二点, 效率问题, 目前 C 语言的编译器优化也做的很好, 对于一个汇编不是很熟练的来说,C 编出来的程序应该不会效率比汇编低。当然 这样就对开发人员的要求降低了很多,人员的限制也就没有那么严格。另外是否 真的是效率问题呢。 我觉得应该是一个整体效率和局部效率的均衡问题。需要提 高的是整体的效率。一个好的软件架构,远远比一个好的函数效率要高的多。因 此主要的精力应该放在软件的架构上。另外现在 CPU 的速度不停的往上提,CPU 越 来越快,这点应该也可以弥补程序的效率吧。 当然,我的意思不是不学习汇编。汇编对于熟悉硬件有很大的好处,应此 汇编语言在学习初期一定是要学习的。 在基本的硬件熟悉之后, 就可以转向 C 了。

AVR 教程(2):AVR 单片机基本硬件设计

作者:微雪电子 文章来源:www.waveshare.net 点击数:

315 更新时间:2008-4-1 23:57:33

AVR 单片机基本硬件电路设计包括:AVR 复位电路和下载电路的设计, 另外 AVR 晶振电路可以不加。
● AVR 复位电路的设计

与传统的 51 单片机相比,AVR 单片机内置复位电路,并且在熔丝位里,可 以控制复位时间,所以,AVR 单片机可以不设外部上电复位电路,依然可以正 常复位,稳定工作。 若是系统需要设置按键复位电路,那么注意,AVR 单片机是低电平复位, 如下图,设计按键复位电路:

● AVR 下载电路的设计 一般来说,AVR 的编程方式有: (1)串行编程,ISP 编程 (2)高压/并行编程 (3)JTAG 编程 (4)IAP 编程 一般情况,系统板都需要设计下载线路,对 AVR 进行编程。目前的 AVR 芯片基本上都具备 ISP 接口, 可通过 ISP 接口进行编程。所以,最常见的是,在系统板上留 ISP 接口。 那么什么是 ISP 呢? ISP 是 In System Program 的缩写,意思是在系统编程,亦即是在线编程。它一共使用了两条电源 线:VCC、GND,三条信号线:SCK、MOSI、MISO,以及复位线:RESET。由于仅仅使用了几条数据线,所 以我们亦常将其称为串行编程。 值得注意的是:大部分 AVR 的 ISP 数据端口亦为 SCK、MOSI、MISO 引脚(如 tiny13/24/2313,meg a48/88/168/8,mega16/32/162 等),如下: [调试器] [目标 MCU] VCC -------- VCC GND -------- GND RESET -------- RESET SCK -------- SCK MOSI -------- MOSI MISO -------- MISO

● AVR 晶振电路的设计 与传统的 51 单片机相比,AVR 单片机内置 RC 振荡电路。出厂时,未进行时钟源设置的 AVR,其时钟 源使用的是内部 RC 振荡,一般情况使用的是 1M 频率。 通过对熔丝位的设置,可以设置 MCU 的内部 RC 振荡频率。例如:4M、8M 等。 不过,内置 RC 振荡,在一致性方面存在差异,它因生产的批次有所差异,亦与温度等因素有较大的 相关性。所以,在一些对时钟要求较高的场合,如:精确定时,RS232 通信等,这些场合,建议使用外 部的晶振线路。

AVR 教程(3):ICCAVR 快速使用

作者:微雪电子 文章来源:www.waveshare.net 点击数:

267 更新时间:2008-4-1 23:56:44

ICCAVR 快速使用
1、在 ICCAVR 中建立工程、C 文件 A、从“Project”菜单中选择“New”命令,如下图:

B、选择文件路径,并输入工程文件的名称,如“ATmega16_Led_Test”,如下图:

C、点击“NewFile”控件,建立新文件,如下图:

D、将文件另存为“.C”文件,如下图:

E、输入“.C”文件的名称,如“ATmega16_Led_Test.C”,如下图:

F、点击“Files”->“Add File(s)”,如下图:

G、找到您的“.C”文件,将它添加到您的“Project”下面,如下图:

2、在 ICCAVR 编写自己的 C 代码,并进行编译 A、在您“.C”文件中输入您的代码,如下图:

B、点击“Project Options”控件,如下图:

C、打开第三个面板“Target”,选择您的 AVR 器件型号,如下图:

D、打开第二个面板“Compiler”,选择与您实际相符的选型,一般进行如下设置,如下图:

E、配置完成后,您就可以编译您的 ICCAVR 工程了,点击“Builder Project”控件,如下图:

AVR 教程(4):AVRStudio 仿真调试快速入门

作者:微雪电子 文章来源:www.waveshare.net 点击数:

211 更新时间:2008-4-1 23:55:11

AVRStudio 仿真调试快速入门
● AVRStudio 的安装 到 ATMEL 官方网站: http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2725 下载安装。 ● AVRStudio 之建立、打开相关调试文件 --使用汇编语言,软件仿真 若使用汇编语言进行源代码的编写,由于 AVRSTUDIO 自带 ASM 编译器,可以直接建立、打开。

接着,进行代码编写,之后按

进行编译。

--使用 ICCAVR,软件仿真 若使用 C 进行编写,由于 AVRSTUDIO 不带 C 编译器,所以需要打开相应的调试文件。

打开*.COF(使用 ICCAVR 编译器编写源代码)或*.D90 文件(使用 IAR 编译器编写源代码)。这类文 件与您需要调试的*.C 文件所处同一文件夹。下面以 ICCAVR 为例,进行介绍。

接着,保存*.aps 文件,改文件将记录目标芯片、文件路径等信息。

在打开项目文件的时候,如下图:选择“AVR Simulator”,右边选择实际使用的器件型号,之后点击 “Finish”即可进行软件仿真。

选择完成后,即可进行仿真调试了。

--使用 JTAGICE 仿真器,硬件仿真 与软件仿真不同的是:在打开项目文件的时候,如下图:选择“JTAG ICE”,其它的步骤与软件仿真 一致,见上。

--使用 JTAG ICE mkII 仿真器,硬件仿真 与软件仿真不同的是:在打开项目文件的时候,如下图:选择“JTAG ICE”,其它的步骤与软件仿真 一致,见上。

● AVRStudio 之调试程序 下面简单介绍使用 AVRStudio 进行仿真调试 调试控制栏 调试控制栏可以控制程序的执行状态,所有的调试控制都可以由菜单,快捷键和调试工具栏实现。 注意!如果在目标文件中含有有效的源码级信息,所有的调试操作将一直继续执行,直到到达第一条用户 源代码语句.如果没有遇到用户源代码语句,程序将继续执行。如果要停止程序的运行,必须在发出停止命 令前转换到反汇编模式。

1.开始调试(Start Debugging) 此命令将启动调试模式,并使所有的调试控制命令处于有效。通常在调试模式下不能编辑程序。此命令将 连接调试平台,装载目标文件并执行复位操作。 2.停止调试(Stop Debugging) 此命令将停止调试过程,并断开与调试平台的连接,进入编辑模式. 3.复位(Reset)(SHIFT+F5) 此命令可以让目标程序复位。当程序正在运行时,执行此命令的话程序将停止运行。如果用户是在源级模 式中,程序会在复位完成后,继续运行直到第一条用户的源代码语句处。复位命令执行后,所有窗口中的

信息都将更新。 4.运行(Run)(F5) 调试菜单中的运行命令将启动(重启动)程序。程序将一直运行直到被用户停止或遇到一个断点。只有当程 序处于停止运行状态时才能执行此命令。 5.暂停(Break)(CTRL-F5) 调试菜单中的暂停命令将停止程序运行。当程序停止时,所有窗口中的信息都将更新。只有当程序处在运 行状态时才能执行此命令。 6.单步执行(Single step, Trace Into)(F11) 调试菜单中的跟踪命令将控制程序只执行一条指令。当 AVR Studio 是在源代码级模式时,可执行一条源 代码语句。 当在反汇编级模式时,可执行一条反汇编指令。 当指令执行完成后, 所有窗口中的信息都将更新。

7.逐过程(Step Over)(F10) 调试菜单中的逐过程命令只执行一条指令。如果此条指令包含一个函数调用/子程序调用,该函数/子程序 也会同时执行。如果在逐过程命令中遇到用户设置的断点,程序运行将被挂起。在逐过程命令执行完毕后, 所有窗口中的信息才会被更新。 8.跳出(Step Out)(SHIFT+F11) 调试菜单中的跳出命令会使程序一直运行,直到当前函数结束。如果遇到用户设置的断点,程序运行将被 挂起。当程序处在最外层(如主函数)时,此时执行跳出命令,程序将继续运行,直到遇到一个断点或被 用户停止。在该命令执行完成后,所有窗口中的信息都将更新。 a.运行到光标处(Run To Cursor)(F7) 调试菜单中的运行到光标处命令,将使程序运行到源代码窗口中光标指示的语句处停止。此时如果遇到用 户的断点,程序的运行将不会被挂起。如果程序运行永远达不到光标指示处的语句,程序将一直继续运行, 直到被用户停止。当此命令结束后,所有窗口中的信息都将更新。由于此命令是与光标位置有关,所以只 有当源代码窗口激活时才有效。 b.自动运行(Auto Step) 调试菜单中的的自动运行命令将重复执行跟踪指令。当 AVR Studio 处在源代码级模式时,每次执行一条 源指令,处在反汇编级模式时,每次执行一条汇编指令,随后所有窗口中的信息都将更新,接者自动执行 下一条语句或指令。使用自动运行命令时,程序的运行将一直持续的单步运行,直到遇到一个用户设置的 断点或被用户停止。 c.设置清除断点 d.清除所有断点 e.快速观察窗口

AVR 教程(5):使用 AVRStudio 设置 AVR 熔丝位及烧写 程序

作者:微雪电子 文章来源:www.waveshare.net 点击数:

190 更新时间:2008-4-1 23:53:17

使用 AVRStudio 设置 AVR 熔丝位及烧写程序
AVR Studio 是 ATMEL 指定用于开发 AVR MCU 的官方软件,其编程功能最为强大。下 面介绍使用 AVRStudio 烧写程序及熔丝快速入门。
● 使用 AVRISP 方式烧写程序及配置熔丝位 对软硬件进行初始配置,并正确设备连接,就可使用 AVRISP 进行联机了。

打开 AVRStudio, 点击主窗口中的图标

前面标有 Con 的那个图标。 出现如下图画面:

在左边,选择“STK500 or AVRISP”,在右边,选择“Auto”(或具体的 COM 口),点击“Connect”进行 联机。

正常联机后,将弹出如下窗口: (1)程序编程面板:

● Device 里面选择好对应的芯片类型,后面的 Erase Device 可以擦 除芯片。 ● Programming mode 编程模式: 注意这里必须是 ISP mod, 表示用 的 ISP 编程模式;Erase Device Before 选项:编程前先擦除芯片,建 议选上,如果不选芯片内部残留的程序可能会对新的程序造成干扰。V erity Device After Program:下载完毕后校验程序内容,建议选上。 ● Flash 下载区: Input HEX File, 找到要写的 hex 文件格式为*.hex、 *.e90。Program,编程点此按钮,将会把 Input HEX File 对应文件下 载到芯片中去,如果路径有错误或者文件格式不正确会有提示报警。V erify 校验命令,用于检测芯片内程序是否和文件中的一致。Read 读命 令,此命令可以读出未加密芯片内的程序,自动弹出一个对话框提示保

存。 ● EEPROM 下载区,和 Flash 下载区类似,格式为.hex、.e90 和.ee p,此功能用于下载比较多的需要存在 EEPROM 中的内容时使用。Pr ogram、 Verify、 Read 于 Flash 下载区有对应 EEPROM 的同样的功能, 不在赘述。 ● 状态指示区,这里显示目前的操作状态。 (2)熔丝位设置面板:

● 配置熔丝位有一定的危险性,可能锁死芯片,在不知道具体在做什 么操作之前,请不要急于动手。 ● 熔丝位状态显示框,显示芯片的各个熔丝位的详细状况,AVR 的熔

丝位打勾表示 0,表示启用该选项;取消表示 1,表示不启用该选项, 需要注意。 ● Auto Verity 选项选中时,程序会自己进行校验,建议选中。Smart Warning 选项选中时,在对一些特殊的具有一定危险性的熔丝位进行 编程时会弹出警告信息,建议选中。 ● Program、Verify 和 Read 分别对应编程、校验和读取,正确的配置 熔丝的方法是先读取,先后修改需要修改的地方,再编程写回。在 Aut o Verity 选项选中时无需再点 Verify 按钮进行校验。 ● 为了安全起见,在 ISP 模式下,SPEEN 熔丝是不允许编程的。 ● 芯片锁死的主要原因是设错熔丝位,主要有两种情况: (1)JTAGEN 和 SPIEN 两个熔丝位都为 1(不打勾),不能再进行编 程,此时只能用高压并行编程或者有源晶振恢复。 (2)将熔丝位选择了外部晶振或外部 RC 振荡,而没有接外部晶振或 外部 RC 振荡,或者外接的振荡频率不匹配,导致芯片不能工作,这种 情况,需要外挂相应晶体才能再次操作芯片,用户应尽量记起当时设错 熔丝的情况,比如错误设置成了外部 3-8M 晶振,那么外挂一个 3-8M 晶振即可进行相应操作。 当然还有其它方面的原因导致芯片锁死,在此处不再一一赘述。 下面以 ATmega16 为例,对其熔丝位进行简单描述:

(3)锁定位设置面板:

● 通过编程锁定位,允许用户对 AVR 芯片内数据进行加密,不同的锁 定位对应不同的加密保护程度,加密位共有三位,每位的数越大加密程 度越高,否则越低。 ● 被加密后的芯片依然可以读出熔丝位和加密位的情况,一旦试图对 加密位进行修改,芯片内的程序将会被修改或擦除,不能再使用。 ● 加密位可以通过编程界面的芯片擦除功能擦除到初始状态,使得芯 片可以重复使用。 ● 锁定位编程界面有与熔丝位编程界面相同的选项和操作按钮,功能 类似,不再赘述。 ● 锁定位编程应该在熔丝位编程之后进行,通常编程锁定位是生产过 程中写芯片环节的最后一步。

下面以 ATmega16 为例,对其所定位进行简单描述:

(4)高级设置面板:

● Signature Bytes,芯片型号标识位,点右边的 Read 读按钮可以读 出芯片内的 ID。 如果在编程面板里面选的芯片型号与读出的芯片型号对 应,下面会提示 Signature matches selected device,如果不匹配会 出现 WARNING: Signature does not match selected device! ● Oscillator Calibration byte,内部 RC 振荡校准。这里选择不同的 频率,点 Read Cal. Byte ,可以读出对应的频率下的校准值,然后将 这个值复制到 Write 区,选择将校准值写到 Flash 还是 EEPROM,点 击 Write to Memory 写按钮, 即可完成对应频率下的内部 RC 振荡校准。 ● 写入到 flash 区域的校准字芯片启动时自动读取并校准 RC 振荡, 如 果写到 EEPROM 中,需要程序中进行处理。 ● Communication Settings 串行通讯设定。

(5)对目标板控制面板:

● Voltages 通过本面板可以查看目标板的电压和写参考电压, 参考电 压需要实际测得,再写入,可以帮助仿真器准确读取目标板电压值以供 参考。本功能在 ISP 编程模式下不可用,需要在 JTAG 模式下使用。 ● Oscillator and ISP Clock 读写速率设定,这里可以读写仿真器内 ISP 编程的速率,ISP 模式下 STK500 选项为灰色。注意速率一定要小 于芯片时钟频率的 1/4,否则无法正确下载。 ● Revision 版本号及升级,这里显示当前 hex 文件的版本号,如果 A VR studio 内的软件版本高于仿真器的版本,右边的 Upgrade 会可用, 如果匹配则该按钮为灰色。

● 当 Upgrade 按钮为可用状态时,可以点击它进入自动升级,在此之 前请确认仿真器是否支持自动升级,以免造成麻烦。 (5)自动烧写面板:

● 自动烧写面板在生产的时候非常管用,程序会记录上次进行批处理 的各个选项,一旦设置好之后,可以连续进行烧写。 ● 请慎用本功能,在不知情的情况下使用本功能,锁死芯片的几率将 大大增加。 ● 自动处理:擦除芯片、检测芯片 ID 号、写 flash、写 EEPROM、写 熔丝位、写锁定位以及他们对应的校验,一次完成,状态栏会显示正在 进行的操作。

● 所有的操作需要在前面对应的面板设置好,比如选择好下载的 HEX 及 EEPROM 文件,选好熔丝位,选好锁定位,写好内部 RC 校正位等。 请一定确保各个选项正确,特别是熔丝需要格外小心,可以先在每个面 板里面进行操作确认没有问题再进行批处理操作。 ● 在进行批处理之前,请先在高级选项里面设置好通讯速率,确保速 率小于晶振的四分之一,否则会出错。 ● 可以选中右边的 Log to file 选项从而记录操作日志。 ● 使用 JTAG 方式烧写程序及熔丝位 对软硬件进行初始配置,并正确设备连接,就可使用 JTAG 进行联 机了。 打开 AVRStudio,点击主窗口中的图标 n 的那个图标。出现如下图画面: 前面标有 Co

在左边,选择“JTAG ICE”,在右边,选择“Auto”(或具体的 COM 口), 点击“Connect”进行联机。

下面步骤基本与上面 AVRISP 方式相同。

AVR 教程(6):ATmega16 简介(一)

作者:微雪电子 文章来源:www.waveshare.net 点击数:

150 更新时间:2008-4-1 23:52:28

ATmega16 是基于增强的 AVR RISC 结构的低功耗 8 位 CMOS 微控制器。 由于其先进的指令集以及单时钟周期指令执行时间,ATmega16 的数据吞吐率 高达 1 MIPS/MHz,从而可以缓减系统在功耗和处理速度之间的矛盾。 ATmega16 AVR 内核具有丰富的指令集和 32 个通用工作寄存器。所有的寄 存器都直接与算逻单元(ALU) 相连接,使得一条指令可以在一个时钟周期内同 时访问两个独立的寄存器。这种结构大大提高了代码效率,并且具有比普通的 CISC 微控制器最高至 10 倍的数据吞吐率。 ATmega16 有如下特点:16K 字节的系统内可编程 Flash(具有同时读写的能 力,即 RWW),512 字节 EEPROM,1K 字节 SRAM,32 个通用 I/O 口线,32 个 通用工作寄存器,用于边界扫描的 JTAG 接口,支持片内调试与编程,三个具 有比较模式的灵活的定时器/ 计数器(T/C),片内/外中断,可编程串行 USART, 有起始条件检测器的通用串行接口, 路 10 位具有可选差分输入级可编程增益 8 (TQFP 封装) 的 ADC ,具有片内振荡器的可编程看门狗定时器,一个 SPI 串 行端口,以及六个可以通过软件进行选择的省电模式。 工作于空闲模式时 CPU 停止工作,而 USART、两线接口、A/D 转换器、SR

AM、T/C、SPI 端口以及中断系统继续工作;掉电模式时晶体振荡器停止振荡, 所有功能除了中断和硬件复位之外都停止工作;在省电模式下,异步定时器继 续运行,允许用户保持一个时间基准,而其余功能模块处于休眠状态; ADC 噪声抑制模式时终止 CPU 和除了异步定时器与 ADC 以外所有 I/O 模块的工作, 以降低 ADC 转换时的开关噪声; Standby 模式下只有晶体或谐振振荡器运行, 其余功能模块处于休眠状态,使得器件只消耗极少的电流,同时具有快速启动 能力;扩展 Standby 模式下则允许振荡器和异步定时器继续工作。 本芯片是以 Atmel 高密度非易失性存储器技术生产的。片内 ISP Flash 允许程序存储器通过 ISP 串行接口,或者通用编程器进行编程,也可以通过运 行于 AVR 内核之中的引导程序进行编程。 引导程序可以使用任意接口将应用程 序下载到应用 Flash 存储区(ApplicationFlash Memory)。在更新应用 Flash 存储区时引导 Flash 区(Boot Flash Memory)的程序继续运行,实现了 RWW 操 作。 通过将 8 位 RISC CPU 与系统内可编程的 Flash 集成在一个芯片内, A Tmega16 成为一个功能强大的单片机,为许多嵌入式控制应用提供了灵活而低 成本的解决方案。ATmega16 具有一整套的编程与系统开发工具,包括:C 语 言 编译器、宏汇编、 程序调试器/ 软件仿真器、仿真器及评估板。 ATmega16 产品特性 ? 高性能、低功耗的 8 位 AVR 微处理器 ? 先进的 RISC 结构 – 131 条指令 – 大多数指令执行时间为单个时钟周期 – 32 个 8 位通用工作寄存器 – 全静态工作 – 工作于 16MHz 时性能高达 16MIPS – 只需两个时钟周期的硬件乘法器 ? 非易失性程序和数据存储器 – 16K 字节的系统内可编程 Flash,擦写寿命: 10,000 次 – 具有独立锁定位的可选 Boot 代码区,通过片上 Boot 程序实现系统内编程, 真正的同时读写操作

– 512 字节的 EEPROM,擦写寿命: 100,000 次 – 1K 字节的片内 SRAM – 可以对锁定位进行编程以实现用户程序的加密 ? JTAG 接口( 与 IEEE 1149.1 标准兼容) – 符合 JTAG 标准的边界扫描功能 – 支持扩展的片内调试功能 – 通过 JTAG 接口实现对 Flash、EEPROM、熔丝位和锁定位的编程 ? 外设特点 – 两个具有独立预分频器和比较器功能的 8 位定时器/计数器 – 一个具有预分频器、比较功能和捕捉功能的 16 位定时器/计数器 – 具有独立振荡器的实时计数器 RTC – 四通道 PWM – 8 路 10 位 ADC,8 个单端通道,2 个具有可编程增益(1x, 10x, 或 200x) 的差分通道 – 面向字节的两线接口 – 两个可编程的串行 USART – 可工作于主机/ 从机模式的 SPI 串行接口 – 具有独立片内振荡器的可编程看门狗定时器 – 片内模拟比较器 ? 特殊的处理器特点 – 上电复位以及可编程的掉电检测 – 片内经过标定的 RC 振荡器 – 片内/片外中断源 – 6 种睡眠模式: 空闲模式、ADC 噪声抑制模式、省电模式、掉电模式、Sta ndby 模式以及扩展的 Standby 模式 ? I/O 和封装 – 32 个可编程的 I/O 口 – 40 引脚 PDIP 封装, 44 引脚 TQFP 封装, 与 44 引脚 MLF 封装 ? 工作电压:

– ATmega16L:2.7 - 5.5V – ATmega16:4.5 - 5.5V ? 速度等级 – 0- 8MHz ATmega16L – 0-16MHz ATmega16 ? ATmega16L 在 1MHz, 3V, 25°C 时的功耗 – 正常模式: 1.1 mA – 空闲模式: 0.35 mA – 掉电模式: < 1 μ A

ATmega16 引脚功能
引脚名称
VCC GND

引脚功能说明
电源正 电源地 端口 A 做为 A/D 转换器的模拟输入端。端口 A 为 8 位双向 I/O 口,具有可编程的

端口 A(PA7..PA0)

内部上拉电阻。其输出缓冲器具有对称的驱动特性,可以输出和吸收大电流。作为 输入使用时,若内部上拉电阻使能,端口被外部电路拉低时将输出电流。在复位过 程中,即使系统时钟还未起振,端口 A 处于高阻状态。 端口 B 为 8 位双向 I/O 口, 具有可编程的内部上拉电阻。 其输出缓冲器具有对称的 驱动特性,可以输出和吸收大电流。作为输入使用时,若内部上拉电阻使能,端口

端口 B(PB7..PB0) 被外部电路拉低时将输出电流。在复位过程中,即使系统时钟还未起振,端口 B 处 于高阻状态。 端口 B 也可以用做其他不同的特殊功能,请参见 P56。 端口 C 为 8 位双向 I/O 口, 具有可编程的内部上拉电阻。 其输出缓冲器具有对称的 端口 C(PC7..PC0) 驱动特性,可以输出和吸收大电流。作为输入使用时,若内部上拉电阻使能,端口 被外部电路拉低时将输出电流。在复位过程中,即使系统时钟还未起振,端口 C 处 于高阻状态。如果 JTAG 接口使能,即使复位出现引脚 PC5(TDI)、 PC3(TMS)与 PC2(TCK)的上拉电阻被激活。 端口 C 也可以用做其他不同的特殊功能, 请参见 P59。 端口 D 为 8 位双向 I/O 口, 具有可编程的内部上拉电阻。 其输出缓冲器具有对称的 端口 D(PD7..PD0) 驱动特性,可以输出和吸收大电流。作为输入使用时,若内部上拉电阻使能,则端 口被外部电路拉低时将输出电流。 在复位过程中, 即使系统时钟还未起振, 端口 D 处 于高阻状态。端口 D 也可以用做其他不同的特殊功能,请参见 P61。 复位输入引脚。持续时间超过最小门限时间的低电平将引起系统复位。门限时间见 RESET XTAL1 XTAL2 P36Table 15。持续时间小于门限间的脉冲不能保证可靠复位。 反向振荡放大器与片内时钟操作电路的输入端。 反向振荡放大器的输出端。

AVCC 是端口 A 与 A/D 转换器的电源。不使用 ADC 时,该引脚应直接与 VCC 连接。使 AVCC AREF 用 ADC 时应通过一个低通滤波器与 VCC 连接。 A/D 的模拟基准输入引脚。

ATmega16 内核介绍
本节从总体上讨论 ATMEGA16 AVR 内核的结构。CPU 的主要任务是保证程序的正确执行。因此它必须能 够访问存储器、执行运算、控制外设以及处理中断。

结构综述 Figure 3. AVR 结构的方框图 为了获得最高的性能以及并行性, AVR 采用了 Harvard 结构,具有独立的数 据和程序总线。程序存储器里的指令通过一级流水线运行。CPU 在执行一条指 令的同时读取下一条指令( 在本文称为预取)。这个概念实现了指令的单时钟 周期运行。程序存储器是可以在线编程的 FLASH。

快速访问寄存器文件包括 32 个 8 位通用工作寄存器,访问时间为一个时钟周 期。从而实现了单时钟周期的 ALU 操作。在典型的 ALU 操作中,两个位于寄 存器文件中的操作数同时被访问, 然后执行运算, 结果再被送回到寄存器文件。 整个过程仅需一个时钟周期。

寄存器文件里有 6 个寄存器可以用作 3 个 16 位的间接寻址寄存器指针以寻址 数据空间,实现高效的地址运算。其中一个指针还可以作为程序存储器查询表 的地址指针。这些附加的功能寄存器即为 16 位的 X、Y、Z 寄存器。

ALU 支持寄存器之间以及寄存器和常数之间的算术和逻辑运算。ALU 也可以执 行单寄存器操作。运算完成之后状态寄存器的内容得到更新以反映操作结果。

程序流程通过有/ 无条件的跳转指令和调用指令来控制,从而直接寻址整个地 址空间。大多数指令长度为 16 位,亦即每个程序存储器地址都包含一条 16 位或 32 位的指令。

程序存储器空间分为两个区:引导程序区(Boot 区) 和应用程序区。这两个区 都有专门的锁定位以实现读和读/ 写保护。 用于写应用程序区的 SPM 指令必须 位于引导程序区。

在中断和调用子程序时返回地址的程序计数器(PC) 保存于堆栈之中。堆栈位 于通用数据 SRAM,因此其深度仅受限于 SRAM 的大小。在复位例程里用户首先 要初始化堆栈指针 SP。这个指针位于 I/O 空间,可以进行读写访问。数据 SR AM 可以通过 5 种不同的寻址模 式进行访问。

AVR 存储器空间为线性的平面结构。

AVR 有一个灵活的中断模块。控制寄存器位于 I/O 空间。状态寄存器里有全局

中断使能位。每个中断在中断向量表里都有独立的中断向量。各个中断的优先 级与其在中断向量表的位置有关,中断向量地址越低,优先级越高。

I/O 存储器空间包含 64 个可以直接寻址的地址, 作为 CPU 外设的控制寄存器、 SPI,以及其他 I/O 功能。映射到数据空间即为寄存器文件之后的地址 0x20 0x5F。

AVR 教程(7):ATmega16 简介(二)

作者:微雪电子 文章来源:www.waveshare.net 点击数:

113 更新时间:2008-4-1 23:51:33

ATmega16 ALU
ALU- 算术逻辑单元 AVR ALU 与 32 个通用工作寄存器直接相连。 寄 存器与寄存器之间、寄存器与立即数之间的 ALU 运算只需要一个时钟周期。ALU 操作分为 3 类:算术、逻辑和位操作。此外还提供了支持无/ 有符号数和分数 乘法的乘法器。具体请参见指令集。

ATmega16 状态寄存器
状态寄存器包含了最近执行的算术指令的结果信息。 这些信息可以用来改变 程序流程以实现条件操作。如指令集所述,所有 ALU 运算都将影响状态寄存器 的内容。这样,在许多情况下就不需要专门的比较指令了,从而使系统运行更快 速,代码效率更高。 在进入中断服务程序时状态寄存器不会自动保存, 中断返回时也不会自动恢 复。这些工作需要软件来处理。

AVR 中断寄存器 SREG 定义如下: ?Bit 7 – I: 全局中断使能 I 置位时使能全局中断。单独的中断使能由其他独立的控制寄存器控制。如果 I 清零,则不 论单独中断标志置位与否,都不会产生中断。任意一个中断发生后 I 清零,而 执行 RETI 指令后 I 恢复置位以使能中断。I 也可以通过 SEI 和 CLI 指令来置位和清零。 ?Bit 6 – T: 位拷贝存储 位拷贝指令 BLD 和 BST 利用 T 作为目的或源地址。BST 把寄存器的某一位拷贝 到 T,而 BLD 把 T 拷贝到寄存器的某一位。 ?Bit 5 – H: 半进位标志 半进位标志 H 表示算术操作发生了半进位。此标志对于 BCD 运算非常有用。详 见指令集 的说明。 ?Bit 4 – S: 符号位, S = N ⊕ V S 为负数标志 N 与 2 的补码溢出标志 V 的异或。详见指令集的说明。 ?Bit 3 – V: 2 的补码溢出标志 支持 2 的补码运算。详见指令集的说明。 ?Bit 2 – N: 负数标志 表明算术或逻辑操作结果为负。详见指令集的说明。 ?Bit 1 – Z: 零标志 表明算术或逻辑操作结果为零。详见指令集的说明。 ?Bit 0 – C: 进位标志 表明算术或逻辑操作发生了进位。详见指令集的说明。

ATmega16 通用寄存器
文件寄存器文件针对 AVR 增强型 RISC 指令集做了优化。为了获得需要的性能和 灵活性,寄存器文件支持以下的输入/ 输出方案: ?输出一个 8 位操作数,输入一个 8 位结果 ?输出两个 8 位位操作数,输入一个 8 位结果 ?输出两个 8 位位操作数,输入一个 16 位结果 ?输出一个 16 位位操作数,输入一个 16 位结果 Figure 4 为 CPU 32 个通用工作寄存器的结构。

Figure 4. AVR CPU 通用工作寄存器 大多数操作寄存器文件的指令都可以直接访问所有的寄存器, 而且多数这样的指 令的执行时间为单个时钟周期。 如 Figure 4 所示,每个寄存器都有一个数据内存地址,将他们直接映射到用户 数据空间的头 32 个地址。 虽然寄存器文件的物理实现不是 SRAM,这种内存组织

方式在访问寄存器方面具有极大的灵活性,因为 X、Y、Z 寄存器可以设置为指 向任意寄存器的指针。

寄存器 R26..R31 除了用作通用寄存器外,还可以作为数据间接寻址用的地址指 针。这三个间接寻址寄存器示于 Figure 5。 Figure 5. X、Y、Z 寄存器 在不同的寻址模式中, 这些地址寄存器可以实现固定偏移量,自动加一和自动减 一功能。 具体细节请参见指令集。

ATmega16 堆栈指针
堆栈指针主要用来保存临时数据、局部变量和中断/ 子程序的返回地址。堆 栈指针总是指向堆栈的顶部。要注意 AVR 的堆栈是向下生长的,即新数据推入 堆栈时,堆栈指针的数值将减小。如果在调用或中断后读程序计数器,未用位(1 5:13) 应屏蔽。

堆栈指针指向数据 SRAM 堆栈区。在此聚集了子程序堆栈和中断堆栈。 调用子程序和使能中断之前必须定义堆栈空间,且堆栈指针必须指向高于 0x60 的地址空间。 使用 PUSH 指令将数据推入堆栈时指针减一; 而子程序或中断返回 地址推入堆栈时指针将减二。 使用 POP 指令将数据弹出堆栈时, 堆栈指针加一; 而用 RET 或 RETI 指令从子程序或中断返回时堆栈指针加二。

AVR 的堆栈指针由 I/O 空间中的两个 8 位寄存器实现。实际使用的位数与 具体器件有关。请注意某些 AVR 器件的数据区太小,用 SPL 就足够了。此时 将不给出 SPH 寄存器。

AVR 教程(8):ATmega16 简介(三)

作者:微雪电子 文章来源:www.waveshare.net 点击数:

107 更新时间:2008-4-1 23:50:33

ATmega16 指令执行时序
这一节介绍指令执行过程中的访问时序。AVR CPU 由系统时钟 clkCPU 驱动。此时钟直接来自选定的 时钟源。芯片内部不对此时钟进行分频。 Figure 6 说明了由 Harvard 结构决定的并行取指和指令执行,以及可以进行快速访问的寄存器文件的概 念。这是一个基本的流水线概念,性能高达 1 MIPS/MHz,具有优良的性价比、功能/ 时钟比、功能/ 功耗 比。 Figure 7 演示的是寄存器文件内部访问时序。在一个时钟周期里,ALU 可以同时对两个寄存器操作数进行 操作,同时将结果保存到目的寄存器中去。

ATmega16 复位与中断处理
AVR 有不同的中断源。每个中断和复位在程序空间都有独立的中断向量。所有的中断事件都有自己的使能 位。当使能位置位,且状态寄存器的全局中断使能位 I 也置位时,中断可以发生。根据程序计数器 PC 的 不同,在引导锁定位 BLB02 或 BLB12 被编程的情况下,中断可能被自动禁止。这个特性提高了软件的安全 性。详见 P247“ 存储器编程” 的描述。 程序存储区的最低地址缺省为复位向量和中断向量。完整的向量列表请参见 P43“中断”。列表也决定了 不同中断的优先级。向量所在的地址越低,优先级越高。RESET 具有最高的优先级,第二个为 INT0 – 外 部中断请求 0。通过置位 MCU 控制寄存器 (MCUCR) 的 IVSEL,中断向量可以移至引导 Flash 的起始处。编 程熔丝位 BOOTRST 也可以将复位向量移至引导 Flash 的起始处。具体参见 P234“支持引导装入程序 – 在 写的同时可以读(RWW,Read-While-Write) 的自我编程能力”。 任一中断发生时全局中断使能位 I 被清零,从而禁止了所有其他的中断。用户软件可以在中断程序里置位 I 来实现中断嵌套。此时所有的中断都可以中断当前的中断服务程序。执行 RETI 指令后 I 自动置位。 从根本上说有两种类型的中断。第一种由事件触发并置位中断标志。对于这些中断,程序计数器跳转到实 际的中断向量以执行中断处理程序,同时硬件将清除相应的中断标志。中断标志也可以通过对其写”1” 的方式来清除。当中断发生后,如果相应的中断使能位为“0”,则中断标志位置位,并一直保持到中断执 行,或者被软件清除。类似的,如果全局中断标志被清零,则所有已发生的中断都不会被执行,直到 I 置 位。然后挂起的各个中断按中断优先级依次执行。 第二种类型的中断则是只要中断条件满足,就会一直触发。这些中断不需要中断标志。若中断条件在中断 使能之前就消失了,中断不会被触发。 AVR 退出中断后总是回到主程序并至少执行一条指令才可以去执行其他被挂起的中断。要注意的是,进入 中断服务程序时状态寄存器不会自动保存,中断返回时也不会自动恢复。这些工作必须由用户通过软件来 完成。

使用 CLI 指令来禁止中断时,中断禁止立即生效。没有中断可以在执行 CLI 指令后发生,即使它是在执行 CLI 指令的同时发生的。下面的例子说明了如何在写 EEPROM 时使用这个指令来防止中断发生以避免对 EE PROM 内容的可能破坏。 汇编代码例程 in r16, SREG ; 保存 SREG cli ; 禁止中断 sbi EECR, EEMWE ; 启动 EEPROM 写操作 sbi EECR, EEWE out SREG, r16 ; 恢复 SREG (I 位) C 代码例程 char cSREG; cSREG = SREG; /* 保存 SREG */ /* 禁止中断*/ _CLI(); EECR |= (1<<EEMWE); /* 启动 EEPROM 写操作*/ EECR |= (1<<EEWE); SREG = cSREG; /* 恢复 SREG (I 位) */ 使用 SEI 指令使能中断时,紧跟其后的第一条指令在执行任何中断之前一定会首先得到执行。 汇编代码例程 sei ; 置位全局中断使能标志 sleep ; 进入休眠模式,等待中断发生 ; 注意: 在执行任何被挂起的中断之前 MCU 将首先进入休眠模式 C 代码例程 _SEI(); /* 置位全局中断使能标志*/ _SLEEP(); /* 进入休眠模式,等待中断发生*/ /* 注意: 在执行任何被挂起的中断之前 MCU 将首先进入休眠模式*/ AVR 中断响应时间最少为 4 个时钟周期。4 个时钟周期后,程序跳转到实际的中断处理例程。在这 4 个时 钟期期间 PC 自动入栈。在通常情况下,中断向量为一个跳转指令,此跳转需要 3 个时钟周期。如果中断 在一个多时钟周期指令执行期间发生,则在此多周期指令执行完毕后 MCU 才会执行中断程序。若中断发生 时 MCU 处于休眠模式,中断响应时间还需增加 4 个时钟周期。此外还要考虑到不同的休眠模式所需要的启 动时间。这个时间不包括在前面提到的时钟周期里。 中断返回需要 4 个时钟。在此期间 PC( 两个字节) 将被弹出栈,堆栈指针加二,状态寄存器 SREG 的 I 置位。

ATmega16 Flash 程序存储器
系统内可编程的 Flash 程序存储器

ATmega16 具有 16K 字节的在线编程 Flash,用于存放程序指令代码。因为所有的 AVR 指令为 16 位或 32 位,故而 Flash 组织成 8K x 16 位的形式。用户程序的安全性要根据 Flash 程序存储器的两个区:引导(B oot) 程序区和应用程序区,分开来考虑。 Flash 存储器至少可以擦写 10,000 次。ATmega16 的程序计数器(PC)为 13 位,因此可以寻址 8K 字的程序 存储器空间。引导程序区以及相关的软件安全锁定位请参见 P234“ 支持引导装入程序 – 在写的同时可 以读(RWW, Read-While-Write) 的自我编程能力” ,而 P247“存储器编程” 详述了用 SPI 或 JTAG 接口 实现对 Flash 的串行下载。 常数可以保存于整个程序存储器地址空间( 参考 LPM 加载程序存储器指令的说明)。取指与执行时序图请 参见 P11“ 指令执行时序”。

ATmega16 SRAM 数据存储器
SRAM 数据存储器 Figure 9 给出了 ATmega16 SRAM 空间的组织结构。

前 1120 个数据存储器包括了寄存器文件、I/O 存储器及内部数据 SRAM。起始的 96 个地址为寄存器文件 与 64 个 I/O 存储器,接着是 1024 字节的内部数据 SRAM。 数据存储器的寻址方式分为 5 种:直接寻址、带偏移量的间接寻址、间接寻址、带预减量的间接寻址和带 后增量的间接寻址。寄存器文件中的寄存器 R26 到 R31 为间接寻址的指针寄存器。 直接寻址范围可达整个数据区。 带偏移量的间接寻址模式能够寻址到由寄存器 Y 和 Z 给定的基址附近的 63 个地址。 在自动预减和后加的间接寻址模式中,寄存器 X、Y 和 Z 自动增加或减少。 ATmega16 的全部 32 个通用寄存器、64 个 I/O 寄存器及 1024 个字节的内部数据 SRAM 可以通过所有上述的 寻址模式进行访问。寄存器文件的描述见 P9“ 通用寄存器文件” 。 SRAM 数据存储器访 本节说明访问内部存储器的时序。如 Figure 10 所示,内部数据 SRAM 访问时间为两个 clkCPU 时钟。

ATmega16 EEPROM 数据存储器
ATmega16 包含 512 字节的 EEPROM 数据存储器。 它是作为一个独立的数据空间而存在的, 可以按字节读写。 EEPROM 的寿命至少为 100,000 次擦除周期。 EEPROM 的访问由地址寄存器、 数据寄存器和控制寄存器决定。 通过 SPI 和 JTAG 及并行电缆下载 EEPROM 数据的操作请分别参见 P260、 P265 及 P250。 EEPROM 读/ 写访问 EEPROM 读/ 写访问 EEPROM 的访问寄存器位于 I/O 空间。 EEPROM 的写访问时间由 Table 1 给出。自定时功能可以让用户软件监测何时可以开始写下一字节。用户操 作 EEPROM 需要注意如下问题:在电源滤波时间常数比较大的电路中,上电/ 下电时 VCC 上升/ 下降速度 会比较慢。此时 CPU 可能工作于低于晶振所要求的电源电压。请参见 P20“ 防止 EEPROM 数据丢失” 以 避免出现 EEPROM 数据丢失的问题。 为了防止无意识的 EEPROM 写操作,需要执行一个特定的写时序。具体参看 EEPROM 控制寄存器的内容。 执行 EEPROM 读操作时, CPU 会停止工作 4 个周期,然后再执行后续指令;执行 EEPROM 写操作时, CPU 会停止工作 2 个周期,然后再执行后续指令。 EEPROM 地址寄存器- EEARH 和 EEARL ? Bits 15..9 – Res: 保留 保留位,读操作返回值为零。

? Bits 8..0 – EEAR8..0: EEPROM 地址 EEPROM 地址寄存器– EEARH 和 EEARL 指定了 512 字节的 EEPROM 空间。 EEPROM 地址是线性的, 0 到 511。 从 EEAR 的初始值没有定义。在访问 EEPROM 之前必须为其赋予正确的数据。 EEPROM 数据寄存器 - EEDR ? Bits 7..0 – EEDR7.0: EEPROM 数据 对于 EEPROM 写操作, EEDR 是需要写到 EEAR 单元的数据;对于读操作, EEDR 是从地址 EEAR 读取的数 据。 EEPROM 控制寄存器- EECR ? Bits 7..4 – Res: 保留 保留位,读操作返回值为零。 ? Bit 3 – EERIE: 使能 EEPROM 准备好中断 若 SREG 的 I 为"1",则置位 EERIE 将使能 EEPROM 准备好中断。清零 EERIE 则禁止此中断。当 EEWE 清零 时 EEPROM 准备好中断即可发生。 ? Bit 2 – EEMWE: EEPROM 主机写使能 EEMWE 决定了 EEWE 置位是否可以启动 EEPROM 写操作。当 EEMWE 为"1"时,在 4 个时钟周期内置位 EEWE 将 把数据写入 EEPROM 的指定地址;若 EEMWE 为"0“,则操作 EEWE 不起作用。EEMWE 置位后 4 个周期,硬 件对其清零。见 EEPROM 写过程中对 EEWE 位的描述。 ? Bit 1 – EEWE: EEPROM 写使能 EEWE 为 EEPROM 写操作的使能信号。当 EEPROM 数据和地址设置好之后,需置位 EEWE 以便将数据写入 EEP ROM。此时 EEMWE 必须置位,否则 EEPROM 写操作将不会发生。写时序如下( 第 3 步和第 4 步的次序并不重 要): 1. 等待 EEWE 位变为零 2. 等待 SPMCSR 中的 SPMEN 位变为零 3. 将新的 EEPROM 地址写入 EEAR( 可选) 4. 将新的 EEPROM 数据写入 EEDR( 可选) 5. 对 EECR 寄存器的 EEMWE 写"1",同时清零 EEWE 6. 在置位 EEMWE 的 4 个周期内,置位 EEWE 在 CPU 写 Flash 存储器的时候不能对 EEPROM 进行编程。 在启动 EEPROM 写操作之前软件必须检查 Flash 写操作是否已经完成。步骤(2) 仅在软件包含引导程序并允许 CPU 对 Flash 进行编程时才有用。如果 CPU 永远都不会写 Flash,步骤(2) 可省略。请参见 P234“支持引导装入程序 – 在写的同时可以读(RWW, Re ad-While-Write)的自我编程能力” 。 注意:如果在步骤 5 和 6 之间发生了中断,写操作将失败。因为此时 EEPROM 写使能操作将超时。如果一 个操作 EEPROM 的中断打断了另一个 EEPROM 操作,EEAR 或 EEDR 寄存器可能被修改,引起 EEPROM 操作失 败。建议此时关闭全局中断标志 I。经过写访问时间之后,EEWE 硬件清零。用户可以凭借这一位判断写时 序是否已经完成。EEWE 置位后, CPU 要停止两个时钟周期才会运行下一条指令。

? Bit 0 – EERE: EEPROM 读使能 EERE 为 EEPROM 读操作的使能信号。当 EEPROM 地址设置好之后,需置位 EERE 以便将数据读入 EEAR。EEPR OM 数据的读取只需要一条指令,且无需等待。读取 EEPROM 后 CPU 要停止 4 个时钟周期才可以执行下一条 指令。 用户在读取 EEPROM 时应该检测 EEWE。如果一个写操作正在进行,就无法读取 EEPROM,也无法改变寄存器 EEAR。 经过校准的片内振荡器用于 EEPROM 定时。 Table 1 为 CPU 访问 EEPROM 的典型时间。 下面的代码分别用汇编和 C 函数说明如何实现 EEPROM 的写操作。在此假设中断不会在执行这些函数的过 程当中发生。同时还假设软件没有 Boot Loader。若 Boot Loader 存在,则 EEPROM 写函数还需要等待正 在运行的 SPM 命令的结束。 汇编代码例程 EEPROM_write: ; 等待上一次写操作结束 sbic EECR,EEWE rjmp EEPROM_write ; 设置地址寄存器 (r18:r17) out EEARH, r18 out EEARL, r17 ; 将数据写入数据寄存器(r16) out EEDR,r16 ; 置位 EEMWE sbi EECR,EEMWE ; 置位 EEWE 以启动写操作 sbi EECR,EEWE ret C 代码例程 void EEPROM_write(unsigned int uiAddress, unsigned char ucData) { /* 等待上一次写操作结束 */ while(EECR & (1<<EEWE)) ; /* 设置地址和数据寄存器*/ EEAR = uiAddress; EEDR = ucData; /* 置位 EEMWE */ EECR |= (1<<EEMWE); /* 置位 EEWE 以启动写操作*/ EECR |= (1<<EEWE); }

下面的例子说明如何用汇编和 C 函数来读取 EEPROM,在此假设中断不会在执行这些函数的过程当中发生。 汇编代码例程 EEPROM_read: ; 等待上一次写操作结束 sbic EECR,EEWE rjmp EEPROM_read ; 设置地址寄存器 (r18:r17) out EEARH, r18 out EEARL, r17 ; 设置 EERE 以启动读操作 sbi EECR,EERE ; 自数据寄存器读取数据 in r16,EEDR ret C 代码例程 unsigned char EEPROM_read(unsigned int uiAddress) { /* 等待上一次写操作结束 */ while(EECR & (1<<EEWE)) ; /* 设置地址寄存器*/ EEAR = uiAddress; /* 设置 EERE 以启动读操作*/ EECR |= (1<<EERE); /* 自数据寄存器返回数据 */ return EEDR; } 在掉电休眠模式下的 EEPROM 写操作 若程序执行掉电指令时 EEPROM 的写操作正在进行, EEPROM 的写操作将继续,并在指定的写访问时间之 前完成。但写操作结束后,振荡器还将继续运行,单片机并非处于完全的掉电模式。因此在执行掉电指令 之前应结束 EEPROM 的写操作。

防止 EEPROM 数据丢失

若电源电压过低,CPU 和 EEPROM 有可能工作不正常,造成 EEPROM 数据的毁坏( 丢失)。这种情况在使用 独立的 EEPROM 器件时也会遇到。因而需要使用相同的保护方案。

由于电压过低造成 EEPROM 数据损坏有两种可能:一是电压低于 EEPROM 写操作所需要的最低电压;二是 C

PU 本身已经无法正常工作。

EEPROM 数据损坏的问题可以通过以下方法解决: 当电压过低时保持 AVR RESET 信号为低。这可以通过使能芯片的掉电检测电路 BOD 来实现。如果 BOD 电平 无法满足要求则可以使用外部复位电路。若写操作过程当中发生了复位,只要电压足够高,写操作仍将正 常结束。

ATmega16 I/O 存储器
ATmega16 所有的 I/O 及外设都被放置于 I/O 空间。所有的 I/O 位置都可以通过 IN 与 OUT 指令来访问,在 32 个通用工作寄存器和 I/O 之间传输数据。 地址为 0x00 - 0x1F 的 I/O 寄存器还可用 SBI 和 CBI 指令 直接进行位寻址,而 SBIS 和 SBIC 则用来检查某一位的值。更多内容请参见指令集。使用 IN 和 OUT 指令 时地址必须在 0x00 - 0x3F 之间。如果要象 SRAM 一样通过 LD 和 ST 指令访问 I/O 寄存器,相应的地址 要加上 0x20。

为了与后续产品兼容,保留未用的未应写"0",而保留的 I/O 寄存器则不应进行写操作。

一些状态标志位的清除是通过写"1" 来实现的。要注意的是,与其他大多数 AVR 不同,CBI 和 SBI 指令只 能对某些特定的位进行操作,因而可以用于包含这些状态标志的寄存器。CBI 与 SBI 指令只对 0x00 到 0x 1F 的寄存器有效。

I/O 和外设控制寄存器在后续其他章节进行介绍。

AVR 教程(9):ATmega16 简介(四)

作者:微雪电子 文章来源:www.waveshare.net 点击数:

80 更新时间:2008-4-1 23:49:04

ATmega16 时钟系统及其分布
时钟系统及其分布 Figure 11 为 AVR 的主要时钟系统及其分布。这些时钟并不需要同时工作。为了降低功耗,可以通过使用 不同的睡眠模式来禁止无需工作的模块的时钟。时钟系统详见 Figure 11。

CPU

时钟-

clkCPU

CPU 时钟与操作 AVR 内核的子系统相连,如通用寄存器文件、状态寄存器及保存堆

栈指针的数据存储器。终止 CPU 时钟将使内核停止工作和计算。

I/O

时钟-

clkI/O

I/O 时钟用于主要的 I/O

模块,如定时器/ 计数器、SPI 和 USART。I/O 时钟还用于外

部中断模块。要注意的是有些外部中断由异步逻辑检测,因此即使 I/O 时钟停止 了这些中断仍然可以得到监控。此外,
USI

模块的起始条件检测在没有 clkI/O 的

情况下也是异步实现的,使得这个功能在任何睡眠模式下都可以正常工作。

Flash Flash

时钟-

clkFLASH

时钟控制 Flash 接口的操作。此时钟通常与 CPU 时钟同时挂起或激活。

异步定时器时钟-

clkASY kHz

异步定时器时钟允许异步定时器/ 计数器与 LCD 控制器直接由外部 32

时钟晶

体驱动。使得此定时器/ 计数器即使在睡眠模式下仍然可以为系统提供一个实时 时钟。

ADC

时钟-

clkADC

ADC 具有专门的时钟。 这样可以在 ADC 工作的时候停止 CPU 和 I/O 时钟以降低数字电

路产

生的噪声,从而提高 ADC 转换精度。

ATmega16 时钟源
ATmega16 芯片有如下几种通过 Flash 熔丝位进行选择的时钟源。时钟输入到 AVR 时钟发生器,再分配到相 应的模块。 不同的时钟选项将在后续部分进行介绍。当 CPU 自掉电模式或省电模式唤醒之后,被选择的时钟源用来为 启动过程定时,保证振荡器在开始执行指令之前进入稳定状态。当 CPU 从复位开始工作时,还有额外的延 迟时间以保证在 MCU 开始正常工作之前电源达到稳定电平。这个启动时间的定时由看门狗振荡器完成。看 门狗溢出时间所对应的 WDT 振荡器周期数列于 Table 3。看门狗振荡器的频率由工作电压决定,详见 P28 6“ATmega16 典型特性” 。 缺省时钟源

器件出厂时 CKSEL

= “0010”, SUT = “10”。这个缺省设置的时钟源是 1 MHz

的内部 R

C 振荡器,启动时间为最长。这种设置保证用户可以通过 ISP

或并行编程器得到

所需的时钟源。

ATmega16 晶体振荡器
XTAL1 与 XTAL2 分别为用作片内振荡器的反向放大器的输入和输出,如 Figure 12 所示,这个振荡器可以 使用石英晶体,也可以使用陶瓷谐振器。熔丝位 CKOPT 用来选择这两种放大器模式的其中之一。 当 CKOPT 被编程时振荡器在输出引脚产生满幅度的振荡。这种模式适合于噪声环境,以及需要通过 XTAL2 驱动第二个时钟缓冲器的情况。而且这种模式的频率范围比较宽。当保持 CKOPT 为未编程状态时,振荡器 的输出信号幅度比较小。其优点是大大降低了功耗,但是频率范围比较窄,而且不能驱动其他时钟缓冲器。 对于谐振器, CKOPT 未编程时的最大频率为 8 MHz, CKOPT 编程时为 16 MHz。C1 和 C2 的数值要一样, 不管使用的是晶体还是谐振器。最佳的数值与使用的晶体或谐振器有关,还与杂散电容和环境的电磁噪声 有关。Table8 给出了针对晶体选择电容的一些指南。对于陶瓷谐振器,应该使用厂商提供的数值。若想得 到更多的有关如何选择电容以及振荡器如何工作的信息,请参考多用途振荡器应用手册。

振荡器可以工作于三种不同的模式,每一种都有一个优化的频率范围。工作模式通过熔丝位 CKSEL3..1 来 选择,如 Table 4 所示。

如 Table 5 所示,熔丝位 CKSEL0 以及 SUT1..0 用于选择启动时间。

Notes: 1. 这些选项只能用于工作频率不太接近于最大频率,而且启动时的频率稳定性对于应用而言不重要的情 况。不适用于晶体。 2. 这些选项是为陶瓷谐振器设计的,可以保证启动时频率足够稳定。若工作频率不太接近于最大频率,而 且启动时的频率稳定性对于应用而言不重要时也适用于晶体。

ATmega16 低频晶体振荡器
为了使用 32.768 kHz 钟表晶体作为器件的时钟源,必须将熔丝位 CKSEL 设置为“1001”以选择低频晶体 振荡器。晶体的连接方式如 Figure 12 所示。通过对熔丝位 CKOPT 的编程,用户可以使能 XTAL1 和 XTAL 2 的内部电容,从而去除外部电容。内部电容的标称数 值为 36 pF。 选择了这个振荡器之后,启动时间由熔丝位 SUT 确定,如 Table 6 所示。

ATmega16 外部 RC 振荡器
对于时间不敏感的应用可以使用 Figure 13 的外部 RC 振荡器。频率可以通过方程 f =1/(3RC) 进行粗略 地鼓估计。电容 C 至少要 22 pF。通过编程熔丝位 CKOPT,用户可以使能 XTAL1 和 GND 之间的片内 36 pF 电容,从而无需外部点燃。若想获取有关振荡器如何工作以及如何选择 R 和 C 的具体信息,请参考外部 RC 振荡器应用手册。

振荡器可以工作于四个不同的模式,每个模式有自己的优化频率范围。工作模式通过熔丝位 CKSEL3..0 选 取,如 Table 7 所示。

选择了这个振荡器之后,启动时间由熔丝位 SUT 确定,如 Table 8 所示。

ATmega16 标定的片内 RC 振荡器
标定的片内 RC 振荡器提供了固定的 1.0、2.0、4.0 或 8.0 MHz 的时钟。这些频率都是 5V、25°C 下的标 称数值。这个时钟也可以作为系统时钟,只要按照 Table 9 对熔丝位 CKSEL 进行编程即可。 选择这个时钟(此时不能对 CKOPT 进行编程)之后就无需外部器件了。复位时硬件将标定字节加载到 OSCCAL 寄存器,自动完成对 RC 振荡器的标定。在 5V,25°C 和频率为 1.0 MHz 时,这种标定可以提供标称频率 ± 1% 的精度。 当使用这个振荡器作为系统时钟时,看门狗仍然使用自己的看门狗定时器作为溢出复位的依据。

选择了这个振荡器之后,启动时间由熔丝位 SUT 确定,如 Table 10 所示。XTAL1 和 XTAL2 要保持为空(N C)。

振荡器标定寄存器- OSCCAL

? Bits 7..0 – CAL7..0: 振荡器标定数据 将标定数据写入这个地址可以对内部振荡器进行调节以消除由于生产工艺所带来的振荡器频率偏差。复位 时 1 MHz 的标定数据( 标识数据的高字节,地址为 0x00) 自动加载到 OSCCAL 寄存器。 如果需要内部 RC 振荡器工作于其他频率,标定数据必须人工加载:首先通过编程器读取标识数据,然后将 标定数据保存到 Flash 或 EEPROM 之中。这些数据可以通过软件读取,然后加载到 OSCCAL 寄存器。当 OS CCAL 为零时振荡器以最低频率工作。 当对其写如不为零的数据时内部振荡器的频率将增长。写入 0xFF 即得到最高频率。标定的振荡器用来为 访问 EEPROM 和 Flash 定时。有写 EEPROM 和 Flash 的操作时不要将频率标定到超过标称频率的 10%,否 则写操作有可能失败。要注意振荡器只对 1.0、2.0、4.0 和 8.0 MHz 这四种频率进行了标定,其他频率则 无法保证。

AVR 教程(10):ATmega16 简介(四)

作者:微雪电子 文章来源:www.waveshare.net 点击数:

79 更新时间:2008-4-1 23:47:44

ATmega16 外部时钟
为了从外部时钟源驱动芯片, XTAL1 必须如 Figure 14 所示的进行连接。同时,熔丝位 CKSEL 必须 编程为“0000”。若熔丝位 CKOPT 也被编程,用户就可以使用内部的 XTAL1 和 GND 之间的 36 pF 电容。

选择了这个振荡器之后,启动时间由熔丝位 SUT 确定,如 Table 12 所示。

为了保证 MCU 能够稳定工作,不能突然改变外部时钟源的振荡频率。工作频率突 变超过 2% 将会产生异常现象。应该在 MCU 保持复位状态时改变外部时钟的振荡 频率。

ATmega16 定时器/计时器振荡器

对于拥有定时器/ 振荡器引脚(TOSC1 和 TOSC2) 的 AVR 微处理器,晶体可以直接与这两个引脚连接,无需 外部电容。此振荡器针对 32.768 kHz 的钟表晶体作了优化。不建议在 TOSC1 引脚输入振荡信号。

ATmega16 MCU 控制寄存器 MCUCR
MCU 控制寄存器包含了电源管理的控制位。

? Bits 7, 5, 4 – SM2..0: 休眠模式选择位 2、1 和 0 如 Table 13 所示,这些位用于选择具体的休眠 模式。

? Bit 6 – SE:

休眠使能
SE

为了使 MCU 在执行 SLEEP 指令后进入休眠模式,

必须置位。为了确保进入休眠

模式是程序员的有意行为, 建议仅在 SLEEP 指令的前一条指令置位 SE。MCU 一旦唤 醒立即清除 SE。

ATmega16 空闲模式
当 SM2..0 为 000 时, SLEEP 指令将使 MCU 进入空闲模式。在此模式下,CPU 停止运行,而 LCD 控制器、 SPI、USART、模拟比较器、ADC、USI、定时器/ 计数器、看门狗和中断系统继续工作。这个休眠模式只停 止了 clkCPU 和 clkFLASH,其他时钟则继续工作。 象定时器溢出与 USART 传输完成等内外部中断都可以唤醒 MCU。如果不需要从模拟比较器中断唤醒 MCU,

为了减少功耗,可以切断比较器的电源。方法是置位模拟比较器控制和状态寄存器 ACSR 的 ACD。如果 ADC 使能,进入此模式后将自动启动一次转换。

ATmega16 ADC 噪声抑制模式
当 SM2..0 为 001 时, SLEEP 指令将使 MCU 进入噪声抑制模式。在此模式下,CPU 停止运行,而 ADC、外 部中断、两线接口地址配置、定时器/ 计数器 0 和看门狗继续工作。这个睡眠模式只停止了 clkI/O、clk CPU 和 clkFLASH,其他时钟则继续工作。 此模式提高了 ADC 的噪声环境,使得转换精度更高。ADC 使能的时候,进入此模式将自动启动一次 AD 转 换。ADC 转换结束中断、外部复位、看门狗复位、BOD 复位、两线接口地址匹配中断、定时器/ 计数器 2 中断、SPM/EEPROM 准备好中断、外部中断 INT0 或 INT1,或外部中断 INT2 可以将 MCU 从 ADC 噪声抑制模 式唤醒。

ATmega16 掉电模式
当 SM2..0 为 010 时, SLEEP 指令将使 MCU 进入掉电模式。在此模式下,外部晶体停振,而外部中断、 两线接口地址匹配及看门狗(如果使能的话)继续工作。只有外部复位、看门狗复位、BOD 复位、两线接 口地址匹配中断、外部电平中断 INT0 或 INT1,或外部中断 INT2 可以使 MCU 脱离掉电模式。这个睡眠模 式停止了所有的时钟,只有异步模块可以继续工作。 当使用外部电平中断方式将 MCU 从掉电模式唤醒时,必须保持外部电平一定的时间。具体请参见 P65“ 外部中断”。 从施加掉电唤醒条件到真正唤醒有一个延迟时间,此时间用于时钟重新启动并稳定下来。唤醒周期与由熔 丝位 CKSEL 定义的复位周期是一样的,如 P23“ 时钟源” 所示。

ATmega16 省电模式
当 SM2..0 为 011 时, SLEEP 指令将使 MCU 进入省电模式。这一模式与掉电模式只有一点不同: 如果定时器/ 计数器 2 为异步驱动, 即寄存器 ASSR 的 AS2 置位, 则定时器/ 计数器 2 在睡眠时继续运行。 除了掉电模式的唤醒方式,定时器/ 计数器 2 的溢出中断和比较匹配中断也可以将 MCU 从休眠方式唤醒, 只要 TIMSK 使能了这些中断,而且 SREG 的全局中断使能位 I 置位。 如果异步定时器不是异步驱动的,建议使用掉电模式,而不是省电模式。因为在省电模式下,若 AS2 为 0, 则 MCU 唤醒后异步定时器的寄存器数值是没有定义的。这个睡眠模式停止了除 clkASY 以外所有的时钟, 只有异步模块可以继续工作。

ATmega16 Standby 模式

Standby 模式 当 SM2..0 为 110 时, SLEEP 指令将使 MCU 进入 Standby 模式。这一模式与掉电模式唯一的不同之处在 于振荡器继续工作。其唤醒时间只需要 6 个时钟周期。 扩展 Standby 模式 当 SM2..0 为 111 时, SLEEP 指令将使 MCU 进入扩展的 Standby 模式。这一模式与省掉电模式唯一的不 同之处在于振荡器继续工作。其唤醒时间只需要 6 个时钟周期。

ATmega16 减少功耗的方法
试图降低 AVR 控制系统的功耗时需要考虑几个问题。一般来说,要尽可能利用睡眠模式,并且使尽可能少 的模块继续工作。不需要的功能必须禁止。下面的模块需要特殊考虑以达到尽可能低的功耗。 模数转换器 使能时, ADC 在睡眠模式下继续工作。为了降低功耗,在进入睡眠模式之前需要禁止 ADC。重新启动后的 第一次转换为扩展的转换。具体请参照 P192“ 模数转换器” 。 模拟比较器 在空闲模式时,如果没有使用模拟比较器,可以将其关闭。在 ADC 噪声抑制模式下也是如此。在其他睡眠 模式模拟比较器是自动关闭的。如果模拟比较器使用了内部电压基准源,则不论在什么睡眠模式下都需要 关闭它。否则内部电压基准源将一直使能。请参见 P189“ 模拟比较器” 以了解如何配置模拟比较器。 掉电检测 BOD 如果系统没有利用掉电检测器 BOD,这个模块也可以关闭。如果熔丝位 BODEN 被编程,从而使能了 BOD 功 能,它将在各种休眠模式下继续工作。在深层次的休眠模式下,这个电流将占总电流的很大比重。请参看 P38“ 掉电检测” 以了解如何配置 BOD。 片内基准电压 使用 BOD、模拟比较器和 ADC 时可能需要内部电压基准源。若这些模块都禁止了,则基准源也可以禁止。 重新使能后用户必须等待基准源稳定之后才可以使用它。如果基准源在休眠过程中是使能的,其输出立即 可以使用。请参见 P40“ 片内基准电压” 以了解基准源启动时间的细节。

看门狗定时器 如果系统无需利用看门狗,这个模块也可以关闭。若使能,则在任何休眠模式下都持续工作,从而消耗电 流。在深层次的睡眠模式下,这个电流将占总电流的很大比重。请参看 P40“ 看门狗定时器” 以了解如 何配置看门狗定时器。 端口引脚 进入休眠模式时,所有的端口引脚都应该配置为只消耗最小的功耗。最重要的是避免驱动电阻性负载。在 休眠模式下 I/O 时钟 clkI/O 和 ADC 时钟 clkADC 都被停止了,输入缓冲器也禁止了,从而保证输入电路 不会消耗电流。在某些情况下输入逻辑是使能的,用来检测唤醒条件。用于此功能的具体引脚请参见 P52 “ 数字输入使能和休眠模式” 。 如果输入缓冲器是使能的,此时输入不能悬空,信号电平也不应该接近 VCC/2,否则输入缓冲器会消耗额外的电流。 JTAG 接口与片上调试系统 如果通过熔丝位 OCDEN 使能了片上调试系统,当芯片进入掉电或省电模式时主时钟保持运行。在休眠模式 中这个电流占总电流的很大比重。下面有三种替代方法: ? 不编程 OCDEN ? 不编程 JTAGEN ? 置位 MCUCSR 的 JTD 当 JTAG 接口使能而 JTAG TAP 控制器没有进行数据交换时,引脚 TDO 将悬空。如果与 TDO 引脚连接的硬 件电路没有上拉电阻,功耗将增加。器件的引脚 TDI 包含一个上拉电阻,因此在扫描链中无需为下一个芯 片的 TDO 引脚设置上拉电阻。 通过置位 MCUCSR 寄存器的 JTD 或不对 JTAG 熔丝位编程可以禁止 JTAG 接口。

ATmega16 复位源
复位 AVR 复位时所有的 I/O 寄存器都被设置为初始值,程序从复位向量处开始执行。复位向量处的指令必须是绝对 跳转 JMP 指令,以使程序跳转到复位处理例程。如果程序永远不利用中断功能,中断向量可以由一般的程 序代码所覆盖。这个处理方法同样适用于当复位向量位于应用程序区,中断向量位于 Boot 区 — 或者反 过来 — 的时候。Figure 15 为复位逻辑的电路图。Table 15 则定义了复位电路的电气参数。 复位源有效时 I/O 端口立即复位为初始值。此时不要求任何时钟处于正常运行状态。 所有的复位信号消失之后,芯片内部的一个延迟计数器被激活,将内部复位的时间延长。这种处理方式使 得在 MCU 正常工作之前有一定的时间让电源达到稳定的电平。延迟计数器的溢出时间通过熔丝位 SUT 与 C KSEL 设定。延迟时间的选择请参见 P23“ 时钟源” 。 复位源 ATmega16 有 5 个复位源:

? 上电复位。电源电压低于上电复位门限 VPOT 时, MCU 复位。 ? 外部复位。引脚 RESET 上的低电平持续时间大于最小脉冲宽度时 MCU 复位。 ? 看门狗复位。看门狗使能并且看门狗定时器溢出时复位发生。 ? 掉电检测复位。掉电检测复位功能使能,且电源电压低于掉电检测复位门限 VBOT 时 MCU 即复位。 ? JTAG AVR 复位。复位寄存器为 1 时 MCU 复位。详见 P215“IEEE 1149.1 (JTAG) 边界扫描”。

Notes: 1. 电压下降时,只有电压低于 VPOT 时复位才会发生。 2. 一些器件的 VBOT 可能比标称的最小工作电压还要低。这些器件在生产测试过程中进行了 VCC = VBOT 的测试,保证在 VCC 下降到处理器无法正常工作之前产生掉电检测复位。ATmega16L 的测试条件为 BODLE VEL=1, ATmega16 的测试条件为 BODLEVEL=0。BODLEVEL=1 不适用于 ATmega16。

ATmega16 上电复位
上电复位(POR) 脉冲由片内检测电路产生。检测电平请参见 Table 15。 无论何时 VCC 低于检测电平 POR 即发生。POR 电路可以用来触发启动复位,或者用来检测电源故障。 POR 电路保证器件在上电时复位。VCC 达到上电门限电压后触发延迟计数器。在计数器溢出之前器件一直 保持为复位状态。当 VCC 下降时,只要低于检测门限,RESET 信号立即生效。

ATmega16 外部复位
外部复位由外加于 RESET 引脚的低电平产生。当复位低电平持续时间大于最小脉冲宽度时( 参见 Table 1 5) 即触发复位过程,即使此时并没有时钟信号在运行。当外加信号达到复位门限电压 VRST( 上升沿) 时, tTOUT 延时周期开始。延时结束后 MCU 即启动。

ATmega16 掉电检测
ATmega16 具有片内 BOD(Brown-out Detection) 电路,通过与固定的触发电平的对比来检测工作过程中 V CC 的变化。此触发电平通过熔丝位 BODLEVEL 来设定, 2.7V(BODLEVEL 未编程),4.0V (BODLEVEL 已编 程)。BOD 的触发电平具有迟滞功能以消除电源尖峰的影响。这个迟滞功能可以解释为 VBOT+ = VBOT + VH YST/2 以及 VBOT- = VBOT- VHYST/2。 BOD 电路的开关由熔丝位 BODEN 控制。当 BOD 使能后(BODEN 被编程),一旦 VCC 下降到触发电平以下(VBOT -, Figure 19), BOD 复位立即被激发。当 VCC 上升到触发电平以上时(VBOT+,Figure 19),延时计数 器开始计数,一旦超过溢出时间 tTOUT,MCU 即恢复工作。

如果 VCC 一直低于触发电平并保持如 Table 15 所示的时间 tBOD, BOD 电路将只检测电压跌落。

ATmega16 看门狗复位
看门狗定时器溢出时将产生持续时间为 1 个 CK 周期的复位脉冲。在脉冲的下降沿,延时定时器开始对 tT OUT 记数。请参见 P40 以了解看门狗定时器的具体操作过程。

AVR 教程(12):ATmega16 简介(六)

作者:微雪电子 文章来源:www.waveshare.net 点击数:

89 更新时间:2008-4-1 23:45:28

ATmega16 控制和状态寄存器 MCUCSR
AVR 控制和状态寄存器提供了有关引起 AVR 复位的复位源的信息。 ? Bit 4 – JTRF: JTAG 复位标志 通过 JTAG 指令 AVR_RESET 可以使 JTAG 复位寄存器置位,并引发 MCU 复位,并使 JTRF 置位。上电复位 将使其清零,也可以通过写”0” 来清除。 ? Bit 3 – WDRF: 看门狗复位标志 看门狗复位发生时置位。上电复位将使其清零,也可以通过写”0” 来清除。 ? Bit 2 – BORF: 掉电检测复位标志 掉电检测复位发生时置位。上电复位将使其清零,也可以通过写”0” 来清除。 ? Bit 1 – EXTRF: 外部复位标志 外部复位发生时置位。上电复位将使其清零,也可以通过写”0” 来清除。 ? Bit 0 – PORF: 上电复位标志 上电复位发生时置位。只能通过写”0” 来清除。为了使用这些复位标志来识别复位条件,用户应该尽早 读取此寄存器的数据,然后将其复位。如果在其他复位发生之前将此寄存器复位,则后续复位源可以通过 检查复位标志来了解。

ATmega16 基准电压使能信号和启动时间
ATmega16 具有片内能隙基准源,用于掉电检测,或者是作为模拟比较器或 ADC 的输入。ADC 的 2.56V 基

准电压由此片内能隙基准源产生。 电压基准的启动时间可能影响其工作方式。启动时间列于 Table 16。为了降低功耗,可以控制基准源仅在 如下情况打开: 1. BOD 使能 ( 熔丝位 BODEN 被编程) 2. 能隙基准源连接到模拟比较器(ACSR 寄存器的 ACBG 置位) 3. ADC 使能 因此,当 BOD 被禁止时,置位 ACBG 或使能 ADC 后要启动基准源。为了降低掉电模式的功耗,用户可以禁 止上述三种条件,并在进入掉电模式之前关闭基准源。

ATmega16 看门狗定时器
看门狗定时器由独立的 1 Mhz 片内振荡器驱动。这是 VCC = 5V 时的典型值。请参见特性数据以了解其他 VCC 电平下的典型值。通过设置看门狗定时器的预分频器可以调节看门狗复位的时间间隔,如 P41Table 1 7 所示。看门狗复位指令 WDR 用来复位看门狗定时器。此外,禁止看门狗定时器或发生复位时定时器也被 复位。复位时间有 8 个选项。如果没有及时复位定时器,一旦时间超过复位周期, ATmega16 就复位,并 执行复位向量指向的程序。具体的看门狗复位时序在 P39 有说明。 为了防止无意之间禁止看门狗定时器,在看门狗禁用后必须跟一个特定的修改序列。详见看门狗定时器控 制寄存器。

看门狗定时器控制寄存器-WDTCR

? Bits 7..5 – Res: 保留位

ATmega16 保留位,读操作返回值为零。 ? Bit 4 – WDTOE: 看门狗修改使能 清零 WDE 时必须置位 WDTOE,否则不能禁止看门狗。一旦置位,硬件将在紧接的 4 个时钟周期之后将其清 零。请参考有关 WDE 的说明来禁止看门狗。 ? Bit 3 – WDE: 使能看门狗 WDE 为"1“ 时,看门狗使能,否则看门狗将被禁止。只有在 WDTOE 为"1“ 时 WDE 才能清零。以下为关闭 看门狗的步骤: 1. 在同一个指令内对 WDTOE 和 WDE 写"1“,即使 WDE 已经为"1“ 2. 在紧接的 4 个时钟周期之内对 WDE 写"0” ? Bits 2..0 – WDP2, WDP1, WDP0: 看门狗定时器预分频器 2, 1 和 0 WDP2、WDP1 和 WDP0 决定看门狗定时器的预分频器,如 Table 17 所示。

下面的例子分别用汇编和 C 语言实现了关闭 WDT 的操作。在此假定中断处于用户 控制之下
(

比如禁止全局中断) ,因而在执行下面程序时中断不会发生。

汇编代码例程
WDT_off: ; WDT WDR ;

复位

置位

WDTOE



WDE

in r16, WDTCR ori r16, (1<<WDTOE)|(1<<WDE) out WDTCR, r16 ;

关闭 WDT

ldi r16, (0<<WDE) out WDTCR, r16 ret C

代码例程

void WDT_off(void) { /* WDT _WDR(); /*

复位*/

置位

WDTOE



WDE*/

WDTCR |= (1<<WDTOE) | (1<<WDE); /*

关闭 WDT

*/

WDTCR = 0x00; }

ATmega16 中断向量
本节描述 ATmega16 的中断处理。

Table 19 给出了不同的 BOOTRST/IVSEL 设置下的复位和中断向量的位置。如果程序永远不使能中断,中断 向量就没有意义。用户可以在此直接写程序。同样,如果复位向量位于应用区,而其他中断向量位于 Boot 区,则复位向量之后可以直接写程序。反过来亦是如此。

ATmega16

典型的复位和中断设置如下:

地址 符号代码说明
$000 jmp RESET ;

复位中断向量 中断向量 中断向量 比较中断向量 溢出中断向量 捕捉中断向量 比较 A 中断向量 比较 B 中断向量

$002 jmp EXT_INT0 ; IRQ0 $004 jmp EXT_INT1 ; IRQ1

$006 jmp TIM2_COMP ; Timer2 $008 jmp TIM2_OVF ; Timer2 $00A jmp TIM1_CAPT ; Timer1 $00C jmp TIM1_COMPA ; Timer1 $00E jmp TIM1_COMPB ; Timer1 $010 jmp TIM1_OVF ; Timer1 $012 jmp TIM0_OVF ; Timer0 $014 jmp SPI_STC ; SPI

溢出中断向量 溢出中断向量

传输结束中断向量 结束中断向量

$016 jmp USART_RXC ; USART RX $018 jmp USART_UDRE ; UDR

空中断向量 结束中断向量

$01A jmp USART_TXC ; USART TX $01C jmp ADC ; ADC

转换结束中断向量 就绪中断向量

$01E jmp EE_RDY ; EEPROM $020 jmp ANA_COMP ; $022 jmp TWSI ;

模拟比较器中断向量

两线串行接口中断向量 中断向量

$024 jmp EXT_INT2 ; IRQ2 $026 jmp TIM0_COMP ;

定时器 0 比较中断向量

$028 jmp SPM_RDY ; SPM ;

就绪中断向量

$02A RESET: ldi r16,high(RAMEND) ; $02B out SPH,r16 ;

主程序

设置堆栈指针为 RAM 的顶部

$02C ldi r16,low(RAMEND) $02D out SPL,r16 $02E sei ;

使能中断

$02F <instr> xxx ... ... ...

当熔丝位 BOOTRST 未编程,Boot 区为 型的复位和中断设置如下: 地址符号代码说明
$000 RESET: ldi r16,high(RAMEND) ; $001 out SPH,r16 ;

2K

字节,且寄存器 GICR 的 IVSEL 置位时,典

主程序

设置堆栈指针为 RAM 的顶部

$002 ldi r16,low(RAMEND) $003 out SPL,r16 $004 sei ;

使能中断

$005 <instr> xxx ; .org $1C02 $1C02 jmp EXT_INT0 ; IRQ0 $1C04 jmp EXT_INT1 ; IRQ1 ... .... .. ; $1C28 jmp SPM_RDY ; SPM

中断向量 中断向量

就绪中断向量
2K

当熔丝位 BOOTRST 已编程,且 Boot 区为 地址符号代码说明
.org $002 $002 jmp EXT_INT0 ; IRQ0

字节时,典型的复位和中断设置如下:

中断向量

$004 jmp EXT_INT1 ; IRQ1 ... .... .. ; $028 jmp SPM_RDY ; SPM ; .org $1C00

中断向量

就绪中断向量

$1C00 RESET: ldi r16,high(RAMEND) ; $1C01 out SPH,r16 ;

主程序

设置堆栈指针为 RAM 的顶部

$1C02 ldi r16,low(RAMEND) $1C03 out SPL,r16 $1C04 sei ;

使能中断

$1C05 <instr> xxx

当熔丝位 BOOTRST 已编程,Boot 区为 2K 字节,且寄存器 GICR 的 IVSEL 置位时,典 型的复位和中断设置如下: 地址符号代码说明
.org $1C00 $1C00 jmp RESET ; Reset

中断向量 中断向量 中断向量

$1C02 jmp EXT_INT0 ; IRQ0 $1C04 jmp EXT_INT1 ; IRQ1 ... .... .. ; $1C28 jmp SPM_RDY ; SPM ;

就绪中断向量

$1C2A RESET: ldi r16,high(RAMEND) ; $1C2B out SPH,r16 ;

主程序

设置堆栈指针为 RAM 的顶部

$1C2C ldi r16,low(RAMEND) $1C2D out SPL,r16 $1C2E sei ;

使能中断

$1C2F <instr> xxx

在应用区和 Boot 区之间移动中断向量

通用中断控制寄存器决定中断向量表的放置地址

通用中断控制寄存器-

GICR

? Bit 1 – IVSEL:

中断向量选择

当 IVSEL 为"0“ 时,中断向量位于 Flash 存储器的起始地址;当 IVSEL 为"1“ 时, 中断向量转移到 Boot 区的起始地址。实际的 Boot 区起始地址由熔丝位 BOOTSZ 确 定。具体请参考 P234“ 支持引导装入程序
ite) –

在写的同时可以读(RWW,

Read-While-Wr

的自我编程能力” 。 为了防止无意识地改变中断向量表,修改 IVSEL 时需要

遵照如下过程:
1. 2.

置位中断向量修改使能位 IVCE 在紧接的 4 个时钟周期里将需要的数据写入 IVSEL,同时对 IVCE 写”0”

执行上述序列时中断自动被禁止。其实,在置位 IVCE 时中断就被禁止了,并一 直保持到写 IVSEL 操作之后的下一条语句。如果没有 IVSEL 写操作, 则中断在置位
IVCE

之后的 4 个时钟周期保持禁止。需要注意的是,虽然中断被自动禁止,但状

态寄存器的位 I 的值并不受此操作的影响。
Note:

若中断向量位于 Boot 区,且 Boot 锁定位 BLB02 被编程,则执行应用区的程序

时中断被禁止;若中断向量位于应用区,且 Boot 锁定位 BLB12 被编程, 则执行 B
oot

区的程序时中断被禁止。有关 Boot 锁定位的细节请参见 P234“ 支持引导装入


程序

在写的同时可以读 的自我编程能力” 。

(RWW, Read-While-Write)

? Bit 0 – IVCE:

中断向量修改使能
IVCE

改变 IVSEL 时 IVCE 必须置位。在 IVCE 或 IVSEL 写操作之后 4 个时钟周期, 硬件清零。如前面所述,置位 IVCE 将禁止中断。代码如下:



汇编代码例程:
Move_interrupts:

;

使能中断向量的修改

ldi r16, (1<<IVCE) out GICR, r16 ;

将中断向量转移到 boot 区

ldi r16, (1<<IVSEL) out GICR, r16 ret C

代码例程

void Move_interrupts(void) { /*

使能中断向量的修改*/

GICR = (1<<IVCE); /*

将中断向量转移到 boot 区

*/

GICR = (1<<IVSEL); }

ATmega16 通用中断控制寄存器 GICR

? Bit 1 – IVSEL: 中断向量选择 当 IVSEL 为"0“ 时,中断向量位于 Flash 存储器的起始地址;当 IVSEL 为"1“ 时,中断向量转移到 Bo ot 区的起始地址。实际的 Boot 区起始地址由熔丝位 BOOTSZ 确定。具体请参考 P234“ 支持引导装入程 序 – 在写的同时可以读(RWW, Read-While-Write) 的自我编程能力” 。 为了防止无意识地改变中断向 量表,修改 IVSEL 时需要遵照如下过程: 1. 置位中断向量修改使能位 IVCE 2. 在紧接的 4 个时钟周期里将需要的数据写入 IVSEL,同时对 IVCE 写”0” 执行上述序列时中断自动被禁止。其实,在置位 IVCE 时中断就被禁止了,并一直保持到写 IVSEL 操作之 后的下一条语句。如果没有 IVSEL 写操作,则中断在置位 IVCE 之后的 4 个时钟周期保持禁止。需要注意 的是,虽然中断被自动禁止,但状态寄存器的位 I 的值并不受此操作的影响。 Note: 若中断向量位于 Boot 区,且 Boot 锁定位 BLB02 被编程,则执行应用区的程序时中断被禁止;若中 断向量位于应用区,且 Boot 锁定位 BLB12 被编程, 则执行 Boot 区的程序时中断被禁止。有关 Boot 锁

定位的细节请参见 P234“ 支持引导装入程序 – 在写的同时可以读 (RWW, Read-While-Write) 的自我编程能力” 。 ? Bit 0 – IVCE: 中断向量修改使能 改变 IVSEL 时 IVCE 必须置位。在 IVCE 或 IVSEL 写操作之后 4 个时钟周期, IVCE 被硬件清零。如前面 所述,置位 IVCE 将禁止中断。代码如下: 汇编代码例程: Move_interrupts: ; 使能中断向量的修改 ldi r16, (1<<IVCE) out GICR, r16 ; 将中断向量转移到 boot 区 ldi r16, (1<<IVSEL) out GICR, r16 ret C 代码例程 void Move_interrupts(void) { /* 使能中断向量的修改*/ GICR = (1<<IVCE); /* 将中断向量转移到 boot 区 */ GICR = (1<<IVSEL); }

AVR 教程(13):AVR IO 输出之 LED 显示程序

作者:微雪电子 文章来源:www.waveshare.net 点击数: 系统功能

128 更新时间:2008-4-1 23:44:35

使用 AVR 控制 8 位 LED,做到想闪就闪,不想闪就不闪,左闪右闪,拚命 闪,演示 AVR 单片机之“点灯术”。
硬件设计 关于 AVR 的 I/O 结构及相关介绍详见 Datasheet,这里仅对作部分简单介绍,下面是 AVR 的 I/O 引脚配 置表:

AVR I/O 口引脚配置表
DDRXn 0 0 0 1 1 PORTXn 0 1 1 0 1 PUD X 0 1 X X I/O 方式 输入 输入 输入 输出 输出 内部上拉电阻 无效 有效 无效 无效 无效 引脚状态说明 三态(高阻) 外部引脚拉低时输出电流 (uA) 三态(高阻) 推挽 0 输出,吸收电流 (20mA) 推挽 1 输出,输出电流 (20mA)

虽然 AVR 的 I/O 口单独输出 “1” 时, 可输出较大电流足已点亮一盏灯, AVR 总的 I/O 输出毕竟是有限的, 但 所以, 有经验的点灯者考虑到除了点灯外可能还有其它费劲的活儿要干, 会将 AVR 的 I/O 口设计为输出 “0” 时点灯,输出“1”时熄灯。这种接法亦叫“灌电流接法”。

AVR 主控电路原理图

LED 控制电路原理图

软件设计

//目标系统: 基于 AVR 单片机 //应用软件: ICC AVR /*0101010101010101010101010101010101010101010101010101010101010101010 1 --------------------------------------------------------------------实验内容: 点灯,让灯左闪右闪,拼命闪。 --------------------------------------------------------------------硬件连接: 将 PD 口的 LED 指示灯使能开关切换到"ON"状态。 --------------------------------------------------------------------注意事项: (1)若有加载库程序,请将光盘根目录下的“库程序”下的“ICC_H”文件夹拷 到D盘 (2)请详细阅读:光盘根目录下的“产品资料开发板实验板 SMK 系列 SMK1632 说明资料”

--------------------------------------------------------------------10101010101010101010101010101010101010101010101010101010101010101010* / #include <iom16v.h> #include "D:ICC_HCmmICC.H" #define LED_DDR DDRD

#define LED_PORT PORTD /*------------------------------------------------------------------程序名称: 程序功能: 注意事项: 提示说明: 输 返 / void main(void) { uint8 i,j; LED_DDR=0XFF; while(1) { for(i=0;i<4;i++) { LED_PORT^=0xFF; delay50ms(10); } j=0x01; for(i=0;i<8;i++) { j<<=1; //我闪!拚命闪! 入: 回:

--------------------------------------------------------------------*

LED_PORT=j; } j=0x80;

//我左闪!

delay50ms(10);

for(i=0;i<8;i++) { j>>=1; LED_PORT=j; } } }
系统调试

//我右闪!

delay50ms(10);

本节的目的在于学习 AVR 的 IO 输出功能,对于 AVR 来说,它和传统的 51 单片机 不同,需要设置 IO 引脚方向。 作如下调试: (1)改变 IO 方向,即将“LED_DDR=0XFF;”改为“0X00”,观察现象。 (2) 将语句: delay50ms(10);改为语句: delay50ms(1);可以看到 LED 闪的更快, 眼都花了!

AVR 教程(14):AVR IO 输出之蜂鸣器控制程序

作者:微雪电子 文章来源:www.waveshare.net 点击数: 系统功能

108 更新时间:2008-4-1 23:43:08

使用 AVR 控制一个蜂鸣器,能随心所欲控制蜂鸣器的鸣叫,不会让它乱叫!
硬件设计 关于 AVR 的 I/O 结构及相关介绍详见 Datasheet,这里仅对作部分简单介绍,下面是 AVR 的 I/O 引脚配 置表:

AVR I/O 口引脚配置表
DDRXn 0 0 0 1 1 PORTXn 0 1 1 0 1 PUD X 0 1 X X I/O 方式 输入 输入 输入 输出 输出 内部上拉电阻 无效 有效 无效 无效 无效 引脚状态说明 三态(高阻) 外部引脚拉低时输出电流 (uA) 三态(高阻) 推挽 0 输出,吸收电流 (20mA) 推挽 1 输出,输出电流 (20mA)

虽然 AVR 的 I/O 口单独输出“1”时,可输出较大电流足已点驱动一个蜂鸣器(5V 型),但 AVR 总的 I/O 输出毕竟是有限的,所以,有经验者考虑到可能还有其它费劲的活儿要干,会将 AVR 的 I/O 口设计为输出 “0”时鸣叫,输出“1”时不叫。这种接法亦叫“灌电流叫法”。

AVR 主控电路原理图

软件设计

//目标系统: 基于 AVR 单片机 //应用软件: ICC AVR /*0101010101010101010101010101010101010101010101010101010101010101010 1 ---------------------------------------------------------------------

实验内容: 能随心所欲控制蜂鸣器的鸣叫,不会让它乱叫。 示例程序使蜂鸣器间歇式的进行鸣叫,叫 1 秒,停 1 秒。 --------------------------------------------------------------------硬件连接: 将 PD 口的 LED 指示灯使能开关切换到"ON"状态。 --------------------------------------------------------------------注意事项: (1)若有加载库程序,请将光盘根目录下的“库程序”下的“ICC_H”文件夹拷 到D盘 (2)请详细阅读:光盘根目录下的“产品资料开发板实验板 SMK 系列 SMK1632 说明资料” --------------------------------------------------------------------10101010101010101010101010101010101010101010101010101010101010101010* / #include <iom16v.h> #include "D:ICC_HCmmICC.H" #define OUT_BUZ #define BUZ_ON #define BUZ_OFF sbi(DDRB,3) cbi(PORTB,3) sbi(PORTB,3) //PB3

/*------------------------------------------------------------------程序名称: 程序功能: 注意事项: 提示说明: 输 返 / 入: 回:

--------------------------------------------------------------------*

void main(void) { OUT_BUZ; //设置相应的 IO 口为输出 while(1) { BUZ_ON; //我叫 delay50ms(20); BUZ_OFF; //我不叫 delay50ms(20); } }
系统调试

将语句:delay50ms(20);改为语句:delay50ms(1);可以听到叫的频率更高!

AVR 教程(15):AVR IO 输入之独立按键检测程序

作者:微雪电子 文章来源:www.waveshare.net 点击数: 系统功能

132 更新时间:2008-4-1 23:42:07

使用 AVR 检测八个独立按键, 一旦检测到按键被按, 立马做出指示, 非常牛 (吹 一下)!
硬件设计 关于 AVR 的 I/O 结构及相关介绍详见 Datasheet,这里仅对作部分简单介绍,下面是 AVR 的 I/O 引脚配置 表:

AVR I/O 口引脚配置表
DDRXn 0 0 0 1 1 PORTXn 0 1 1 0 1 PUD X 0 1 X X I/O 方式 输入 输入 输入 输出 输出 内部上拉电阻 无效 有效 无效 无效 无效 引脚状态说明 三态(高阻) 外部引脚拉低时输出电流 (uA) 三态(高阻) 推挽 0 输出,吸收电流 (20mA) 推挽 1 输出,输出电流 (20mA)

AVR 主控电路原理图

LED 控制电路原理图

独立按键电路原理图

软件设计

下面部分从 TXT 拷出, 拷到网页, 代码部分缺省了很多空格, 比较凌乱, 请谅解! //目标系统: 基于 AVR 单片机 //应用软件: ICC AVR /*0101010101010101010101010101010101010101010101010101010101010101010 1 --------------------------------------------------------------------实验内容: 循环扫描 PA 口接入的 8 位独立按键, 并使用 PD 口的 LED 指示灯指示按键的码值。 --------------------------------------------------------------------硬件连接: 将 PD 口的 LED 指示灯使能开关切换到"ON"状态,使其指示按键的码值。 SingleKeyBoard:K0----K7 | SMK1632: 注意事项: (1)若有加载库程序,请将光盘根目录下的“库程序”下的“ICC_H”文件夹拷 到D盘 (2)请详细阅读:光盘根目录下的“产品资料开发板实验板 SMK 系列 SMK1632 说明资料” --------------------------------------------------------------------10101010101010101010101010101010101010101010101010101010101010101010* / #include <iom16v.h> #include "D:ICC_HCmmICC.H" #define LED_DDR #define KEY_DDR DDRD DDRA | PA0--PA7

---------------------------------------------------------------------

#define LED_P0RT PORTD #define KEY_PORT PORTA

#define KEY_PIN

PINA

/*------------------------------------------------------------------程序名称:独立键盘扫描 程序功能: 注意事项: 提示说明: 输 返 / void scanKey() { KEY_PORT=0xFF; “0”,则表示被按 if(KEY_PIN==0xFE) { delay50us(1); //去抖 if(KEY_PIN==0xFE) //1111 1110 --> 确认最低位的按键被按 LED_P0RT=0xFE; //进行 LED 指示 } if(KEY_PIN==0xFD) { delay50us(1); //去抖 if(KEY_PIN==0xFD) //1111 1101 --> 确认最低位的按键被按 LED_P0RT=0xFD; //进行 LED 指示 } if(KEY_PIN==0xFB) { delay50us(1); if(KEY_PIN==0xFB) LED_P0RT=0xFB; } if(KEY_PIN==0xF7) { //1111 1101 --> 说明最低位的按键可能被按 //1111 1110 --> 说明最低位的按键可能被按 //设置按键输出“1”,之后语句检测按键,若端口变为 入: 回:

--------------------------------------------------------------------*

delay50us(1); if(KEY_PIN==0xF7) LED_P0RT=0xF7; } if(KEY_PIN==0xEF) { delay50us(1); if(KEY_PIN==0xEF) LED_P0RT=0xEF; } if(KEY_PIN==0xDF) { delay50us(1); if(KEY_PIN==0xDF) LED_P0RT=0xDF; } if(KEY_PIN==0xBF) { delay50us(1); if(KEY_PIN==0xBF) LED_P0RT=0xBF; } if(KEY_PIN==0x7F) { delay50us(1); if(KEY_PIN==0x7F) LED_P0RT=0x7F; } }
系统调试

按第一个键,第一个 LED 亮;按第二个键,第二个 LED 亮。。

AVR 教程(16):AVR IO 输出之数码管扫描程序

作者:微雪电子 文章来源:www.waveshare.net 点击数: 系统功能

109 更新时间:2008-4-1 23:41:08

使用 AVR 扫描四个数码管,动态扫描,动态显示,左扫,右扫,来回扫。。。

硬件设计

AVR 主控电路原理图

数码管动态扫描电路原理图

软件设计

//目标系统: 基于 AVR 单片机 //应用软件: ICC AVR /*01010101010101010101010101010101010101010101010101010101010101010

101 --------------------------------------------------------------------实验内容: 动态的循环显示“0-9”。 --------------------------------------------------------------------硬件连接: LedIndicator:VCC、GND、L0----L3、D0----D7 | SMK1632: --注意事项: (1)若有加载库程序,请将光盘根目录下的“库程序”下的“ICC_H”文件夹 拷到 D 盘 (2)请详细阅读:光盘根目录下的“产品资料开发板实验板 SMK 系列 SMK163 2 说明资料” --------------------------------------------------------------------1010101010101010101010101010101010101010101010101010101010101010101 0*/ #include <iom16v.H> #include "D:ICC_HCmmICC.H" #define LED_BIT_DDR #define LED_BIT_PORT #define LED_SEG_DDR #define LED_SEG_PORT DDRB PORTB DDRD PORTD //数码管 段选 //数码管 位选 | | | VCC、GND、PB7--PB4、PD0--PD7

-------------------------------------------------------------------

/*------------------------------------------------------------------程序名称:数码管扫描程序 程序功能: 注意事项: 提示说明:

输 返 -*/

入: 回:

------------------------------------------------------------------void main() { uint8 i; uint8 ledCode[]={0x28,0xAF,0x98,0x8A,0X0F,0x4A,0x48,0xAE,0x08,0x0 A}; LED_BIT_DDR = 0XFF; LED_BIT_PORT = 0x0F; LED_SEG_DDR = 0XFF; LED_SEG_PORT = 0X00; while(1) for(i=0;i<=9;i++) { LED_SEG_PORT = ledCode[i]; delay50ms(10); } }
系统调试

本程序仅给出四位数码管显示同一数字的简单示例,试改动“LED_BIT_DDR”、“LED_SEG_DDR”的方向, “LED_BIT_PORT”、“LED_SEG_PORT”的值,观察显示效果。。。

AVR 教程(17):AVR IO 输入之矩阵按键扫描程序

作者:微雪电子 文章来源:www.waveshare.net 点击数: 系统功能

74 更新时间:2008-4-1 23:40:13

使用 AVR 扫描 4*4 矩阵按键,一旦扫描到按键被按,做出被按的按键号指示。

硬件设计 关于 AVR 的 I/O 结构及相关介绍详见 Datasheet,这里仅对作部分简单介绍,下面是 AVR 的 I/O 引脚 配置表:

AVR I/O 口引脚配置表
DDRXn 0 0 0 1 1 PORTXn 0 1 1 0 1 PUD X 0 1 X X I/O 方式 输入 输入 输入 输出 输出 内部上拉电阻 无效 有效 无效 无效 无效 引脚状态说明 三态(高阻) 外部引脚拉低时输出电流 (uA) 三态(高阻) 推挽 0 输出,吸收电流 (20mA) 推挽 1 输出,输出电流 (20mA)

AVR 主控电路原理图

LED 控制电路原理图

4*4 矩阵按键扫描电路原理图

软件设计

//目标系统: 基于 AVR 单片机 //应用软件: ICC AVR /*01010101010101010101010101010101010101010101010101010101010101010 101 --------------------------------------------------------------------实验内容: 循环扫描 PA 口接入的按键,并使用 PB 口的 LED 指示灯指示按键的码值。 -------------------------------------------------------------------

--硬件连接: 将 PB 口的 LED 指示灯使能开关切换到"ON"状态,使其指示按键的码值。 MatrixKeyBoard:K0----K7 | SMK1632: --注意事项: (1)若有加载库程序,请将光盘根目录下的“库程序”下的“ICC_H”文件夹 拷到 D 盘 (2)请详细阅读:光盘根目录下的“产品资料开发板实验板 SMK 系列 SMK163 2 说明资料” --------------------------------------------------------------------1010101010101010101010101010101010101010101010101010101010101010101 0*/ #include <iom16v.H> #include "D:ICC_HCmmICC.H" #define LED_DDR #define LED_PORT #define KEY_DDR #define KEY_PORT #define KEY_PIN DDRB PORTB DDRA PORTA PINA | PA0--PA7

-------------------------------------------------------------------

/*------------------------------------------------------------------程序名称:4*4 按键扫描程序 程序功能:键盘扫描 注意事项: 提示说明: 输 返 -*/ 入: 回:

-------------------------------------------------------------------

/* K4-----K5-----K6-----K7 | | | | 03H----02H----01H----00H -K0 07H----06H----05H----04H -K1 0BH----0AH----09H----08H -K2 0FH----0EH----0DH----0CH -K3 */ const uint8 setSta_[4]={0xfe,0xfd,0xfb,0xf7}; const uint8 getSta_[4]={0x70,0xb0,0xd0,0xe0}; uint8 GetKeyVal() { uint8 i,j,getSta,keyVal; for(i=0;i<4;i++) { KEY_PORT = setSta_[i]; delay50us(1); if(KEY_PIN!=setSta_[i]) { getSta=KEY_PIN&0xf0; for(j=0;j<4;j++) if(getSta==getSta_ [j]) { keyVal=j+i*4; return keyVal; } } } return 0xFF; } /*------------------------------------------------------------------程序名称: 程序功能: 注意事项:

提示说明: 输 返 -*/ void main() { uint8 keyVal; LED_DDR = 0XFF; KEY_DDR = 0X0F; while(1) { keyVal = GetKeyVal(); if( keyVal!=0xFF ) LED_PORT = keyVal; } }
系统调试

入: 回:

-------------------------------------------------------------------

(1)按键,观察 LED 的指示。 (2)去除“delay50us(1);”观察效果

AVR 教程(18):AVR IO 输入之链式按键扫描程序

作者:微雪电子 文章来源:www.waveshare.net 点击数: 系统功能

81 更新时间:2008-4-1 23:39:17

在 AVR 的 8 个 IO 上挂 28 个按键,进行链式扫描,一旦扫描到按键被按,做出 被按的按键指示。
硬件设计 关于 AVR 的 I/O 结构及相关介绍详见 Datasheet,这里仅对作部分简单介绍,下面是 AVR 的 I/O 引脚 配置表:

AVR I/O 口引脚配置表
DDRXn 0 PORTXn 0 PUD X I/O 方式 输入 内部上拉电阻 无效 引脚状态说明 三态(高阻)

0 0 1 1

1 1 0 1

0 1 X X

输入 输入 输出 输出

有效 无效 无效 无效

外部引脚拉低时输出电流 (uA) 三态(高阻) 推挽 0 输出,吸收电流 (20mA) 推挽 1 输出,输出电流 (20mA)

AVR 主控电路原理图

LED 控制电路原理图

链式按键扫描电路原理图

软件设计

//目标系统: 基于 AVR 单片机 //应用软件: ICC AVR /*01010101010101010101010101010101010101010101010101010101010101010 101 --------------------------------------------------------------------实验内容: 循环扫描 PA 口接入的按键,并使用 PB 口的 LED 指示灯指示按键的码值。 --------------------------------------------------------------------硬件连接: 将 PB 口的 LED 指示灯使能开关切换到"ON"状态,使其指示按键的码值。 LinkKeyBoard: SMK1632: --注意事项: (1)若有加载库程序,请将光盘根目录下的“库程序”下的“ICC_H”文件夹 拷到 D 盘 (2)请详细阅读:光盘根目录下的“产品资料开发板实验板 SMK 系列 SMK163 2 说明资料” ------------------------------------------------------------------K0----K7 | | PA0--PA7

-------------------------------------------------------------------

--1010101010101010101010101010101010101010101010101010101010101010101 0*/ #include <iom16v.h> #include "D:ICC_HCmmICC.H" #define LED_DDR #define KEY_DDR #define KEY_PIN DDRB DDRA PINA

#define LED_PORT PORTB #define KEY_PORT PORTA

/*------------------------------------------------------------------程序名称:链式按键扫描程序 程序功能:键盘检测 注意事项: 提示说明: 输 返 -*/ void scanKey() { KEY_DDR = 0X01; KEY_PORT = 0xFE; delay50us(1); if(KEY_PIN==0xFC) LED_PORT=0x01; if(KEY_PIN==0xFA) LED_PORT=0x02; if(KEY_PIN==0xF6) LED_PORT=0x03; if(KEY_PIN==0xEE) LED_PORT=0x04; if(KEY_PIN==0xDE) 入: 回:

-------------------------------------------------------------------

LED_PORT=0x05; if(KEY_PIN==0xBE) LED_PORT=0x06; if(KEY_PIN==0x7E) LED_PORT=0x07; KEY_DDR = 0X02; KEY_PORT = 0xFD; delay50us(1); if(KEY_PIN==0xF9) LED_PORT=0x08; if(KEY_PIN==0xF5) LED_PORT=0x09; if(KEY_PIN==0xED) LED_PORT=0x0A; if(KEY_PIN==0xDD) LED_PORT=0x0B; if(KEY_PIN==0xBD) LED_PORT=0x0C; if(KEY_PIN==0x7D) LED_PORT=0x0D; KEY_DDR = 0X04; KEY_PORT = 0xFB; delay50us(1); if(KEY_PIN==0xF3) LED_PORT=0x0E; if(KEY_PIN==0xEB) LED_PORT=0x10; if(KEY_PIN==0xDB) LED_PORT=0x11; if(KEY_PIN==0xBB) LED_PORT=0x12; if(KEY_PIN==0x7B) LED_PORT=0x13; KEY_DDR = 0X08;

KEY_PORT = 0xF7; delay50us(1); if(KEY_PIN==0xE7) LED_PORT=0x14; if(KEY_PIN==0xD7) LED_PORT=0x15; if(KEY_PIN==0xB7) LED_PORT=0x16; if(KEY_PIN==0x77) LED_PORT=0x17; KEY_DDR = 0X10; KEY_PORT = 0xEF; delay50us(1); if(KEY_PIN==0xCF) LED_PORT=0x18; if(KEY_PIN==0xAF) LED_PORT=0x19; if(KEY_PIN==0x6F) LED_PORT=0x1A; KEY_DDR = 0X20; KEY_PORT = 0xDF; delay50us(1); if(KEY_PIN==0x9F) LED_PORT=0x1B; if(KEY_PIN==0x5F) LED_PORT=0x1C; KEY_DDR = 0X40; KEY_PORT = 0xBF; delay50us(1); if(KEY_PIN==0x3F) LED_PORT=0x1D; } /*------------------------------------------------------------------程序名称: 程序功能:

注意事项: 提示说明: 输 入: 返 回: -------------------------------------------------------------------*/ void main() { LED_DDR = 0XFF; while(1) scanKey(); }
系统调试

(1)按键,观察 LED 的指示。 (2)去除“delay50us(1);”观察效果。

AVR 教程(19):AVR 定时器中断程序

作者:微雪电子 文章来源:www.waveshare.net 点击数: 系统功能

184 更新时间:2008-4-1 23:38:19

使用 AVR 定时器做 1S 定时,并使用 LED 作出简单指示!
硬件设计 本设计基于 7.3728M 晶振作 AVR 定时器的时钟源进行 1S 定时!

AVR 主控电路原理图

LED 控制电路原理图

软件设计

//目标系统: 基于 AVR 单片机 //应用软件: ICC AVRAVR /*01010101010101010101010101010101010101010101010101010101010101010 101 --------------------------------------------------------------------实验内容: 使用 AVR 的定时器 T1 做 1S 定时,并使用 PD 口的 LED 指示灯做简单指示。 --------------------------------------------------------------------硬件连接: 将 PD 口的 LED 指示灯使能开关切换到"ON"状态。 --------------------------------------------------------------------注意事项: (1)若有加载库程序,请将光盘根目录下的“库程序”下的“ICC_H”文件夹 拷到 D 盘 (2)请详细阅读:光盘根目录下的“产品资料开发板实验板 SMK 系列 SMK163 2 说明资料” ---------------------------------------------------------------------

1010101010101010101010101010101010101010101010101010101010101010101 0*/ #include <iom16v.h> #include <macros.h> #define DISP_DDR #define DISP_PORT DDRD PORTD

/*------------------------------------------------------------------程序名称:定时器 1 初始化程序 程序功能: 注意事项:基于 7.3728M 晶振 提示说明:晶振不要买到假的,要不然,调不出来还以为电脑有鬼! 输 返 -*/ void timer1_init(void) { TCCR1B = 0x00; TCNT1H = 0xE3; TCNT1L = 0xE1; //stop timer //设置 TC1 的 计数寄存器 高 8 位值,基于 7.3728M 晶振 //设置 TC1 的 计数寄存器 低 8 位值,基于 7.3728M 晶振 入: 回:

-------------------------------------------------------------------

//OCR1AH = 0x1C; //设置 TC1 的 输出比较寄存器 A 高 8 位值 //OCR1AL = 0x20; //设置 TC1 的 输出比较寄存器 A 低 8 位值 //OCR1BH = 0x1C; //设置 TC1 的 输出比较寄存器 B 高 8 位值 //OCR1BL = 0x20; //设置 TC1 的 输出比较寄存器 B 低 8 位值 //ICR1H //ICR1L = 0x1C; //设置 TC1 的 输入捕获寄存器 高 8 位值 = 0x20; //设置 TC1 的 输入捕获寄存器 低 8 位值

TCCR1A = 0x00; TCCR1B = 0x05; //设置 TC1 为 CLK/1024 分频,启动 TC1

MCUCR = 0x00; //设置 MCU 的 控制寄存器 GICR = 0x00; //设置 中断控制寄存器 TIMSK = 0x04; //设置 定时计数器 的 屏蔽寄存器 //SEI(); //enable interrupts } /*------------------------------------------------------------------程序名称:定时器 1 中断服务程序 程序功能: 注意事项: 提示说明: 输 入: 返 回: -------------------------------------------------------------------*/ #pragma interrupt_handler timer1_ovf_isr:9 void timer1_ovf_isr(void) { TCNT1H = 0xE3; //reload counter high value TCNT1L = 0xE1; //reload counter low value DISP_PORT++; //每加 1S,显示加 1 } /*------------------------------------------------------------------程序名称: 程序功能: 注意事项:没什么好注意的,不要直接对单片机控制板加 220V 电压就行了! 提示说明: 输 入: 返 回: -------------------------------------------------------------------*/ void main(void) { DISP_DDR = 0XFF; //设置显示口为输出 timer1_init(); SEI(); while(1); }
系统调试

时间在累积,LED 也累积向上加,改变定时器的定时时间,LED 向上加的速度加快

AVR 教程(20):AVR 外部中断程序

作者:微雪电子 文章来源:www.waveshare.net 点击数: 系统功能

135 更新时间:2008-4-1 23:35:02

使用 AVR 外部中断 INT1 检测按键,并使用 LED 作出简单指示!
硬件设计

AVR 主控电路原理图

LED 控制电路原理图 软件设计

//目标系统: 基于 AVR 单片机 //应用软件: ICC AVR

/*10101010101010101010101010101010101010101010101010101010101010101 010 --------------------------------------------------------------------实验内容: 使用 AVR 的外部中断 INT1 检测 PD3Key,如果有按键按下,则唤醒休眠的 MCU,并使它的 P B 口的 LED 做加 1 指示。 --------------------------------------------------------------------硬件连接: 将 PB 口的 LED 指示灯使能开关切换到"ON"状态。 --------------------------------------------------------------------注意事项: (1)若有加载库程序,请将光盘根目录下的“库程序”下的“ICC_H”文件夹拷到 D 盘 (2) 请详细阅读: 光盘根目录下的 “产品资料开发板实验板 SMK 系列 SMK1632 说明资料” --------------------------------------------------------------------1010101010101010101010101010101010101010101010101010101010101010101 0*/

#include <iom16v.h> #include "D:ICC_HCmmICC.H"

#define DISP_DDR DDRB #define DISP_PORT #define IN_PD3 #define SET_PD3 #define GET_PD3 PORTB //PD3

cbi(DDRD,3) sbi(PORTD,3) gbi(PIND,3)

/*------------------------------------------------------------------程序名称:外部中断服务程序 程序功能: 注意事项: 提示说明: 输 返 入: 回:

-------------------------------------------------------------------*/ #pragma interrupt_handler int1_isr:3 void int1_isr(void) { GICR &= 0b01111111; DISP_PORT++; delay50ms(4); GICR |= 0b10000000; } /*------------------------------------------------------------------程序名称:外部中断初始化程序 程序功能: 注意事项: 提示说明: 输 返 入: 回: // enable int1 interrupt // disable int1 interrupt

// 显示口指示加 1,指示被按次数

-------------------------------------------------------------------*/ void int1_init() {

IN_PD3; SET_PD3;

// set PD3/INT1 as input // set PD3/INT1 as output,high level,avoid triggering // set PD3/INT1 as low level active // enable global interrupt

MCUCR |= 0b11110011; GICR |= 0b10000000;

SEI(); }

// enable external interrupt

/*------------------------------------------------------------------程序名称: 程序功能: 注意事项: 提示说明: 输 返 入: 回:

-------------------------------------------------------------------*/ void main(void) { DISP_DDR = 0xFF;

DISP_PORT = 0x00; int1_init(); asm("sleep"); while(1); } // set mcu as sleep modle

AVR 教程(21):AVR USART(UART)接收中断程序

作者:微雪电子 文章来源:www.waveshare.net 点击数: 系统功能

126 更新时间:2008-4-1 23:34:21

使用 AVR 的 USART 进行自发自收(将发送引脚 RXD 短接到接收引脚 TXD),发出 数据:0,1,2。。。数据,能接收到自己发出的数据:0,1,2。。。使用 LED 作出简单指示!
硬件设计

AVR 主控电路原理图

LED 控制电路原理图 软件设计

//目标系统: 基于 AVR 单片机

//应用软件: ICC AVR

/*01010101010101010101010101010101010101010101010101010101010101010 101 --------------------------------------------------------------------实验内容: USART 自发自收,使用 PB 口的 LED 指示接收到的数据,观察是否与发送的数据一致。 --------------------------------------------------------------------硬件连接: 将 MCU.RXD 与 MCU.TXD 使用短路帽短接, PB 口的 LED 指示灯使能开关切换到"ON"状态。 将 --------------------------------------------------------------------注意事项: (1)若有加载库程序,请将光盘根目录下的“库程序”下的“ICC_H”文件夹拷到 D 盘 (2)请详细阅读:光盘根目录下的“产品资料开发板实验板 SMK 系列 SMK1632 说明资料” --------------------------------------------------------------------1010101010101010101010101010101010101010101010101010101010101010101 0*/

#include <iom16v.h> #include "D:ICC_HCmmICC.H"

#define DISP_PORT PORTB #define DISP_DDR DDRB

/*------------------------------------------------------------------程序名称:UART 初始化程序

程序功能:初始化 UART 为:8 位,9.6K,接收中断 注意事项:基于 7.3728M 晶振 提示说明:晶振不要买到假的,要不然,调不出来还以为电脑有鬼! 输 返 入: 回:

-------------------------------------------------------------------*/ void uart0_init(void) { UCSRB = 0x00; UCSRA = 0x00; UCSRC = 0x86; UBRRL = 47; UBRRH = 0x00; UCSRB = 0x98; } /*------------------------------------------------------------------程序名称:UART 接收中断服务程序 程序功能: 注意事项: 提示说明: 输 返 入: 回: //disable while setting baud rate //U2X = 0,不加倍数率 //8 位 //set baud rate lo,波特率为 9.6K //set baud rate hi //接收中断允许,接收缓冲自动清空,接收允许

-------------------------------------------------------------------*/ #pragma interrupt_handler uart0_rx_isr:12 void uart0_rx_isr(void) { DISP_PORT = UDR;//显示接收到的数据

//用串口调试助手发送数据,则单片机端显示数据对应的 ASCII 值,如:接收到"1",显示 0X3 1 //delay50ms(1); } /*------------------------------------------------------------------程序名称: 程序功能: 注意事项: 提示说明: 输 返 入: 回:

-------------------------------------------------------------------*/ void mcu_init(void) { CLI(); uart0_init(); MCUCR = 0x00; GICR = 0x00; //timer interrupt sources //re-enable interrupts

TIMSK = 0x00; SEI(); }

/*------------------------------------------------------------------程序名称: 程序功能: 注意事项:没什么好说的。。。 提示说明: 输 入:



回:

-------------------------------------------------------------------*/ void main() { uint8 counter=0;

mcu_init();

DISP_DDR=0xFF;

while(1) { UDR=counter++; while(!(UCSRA&0x40)); UCSRA|=0x40; delay50ms(4); } } //发送数据,数据为变量 counter //等待发送结束 //清除发送结束标志位

系统调试

短接 RXD 与 TXD 能接收到自己发送的数据,断开短接没有接收到数据。 系统不断发送数据:0,1,2。。。若正常接收,将收到 0,1,2。。。。 用 LED 作数据指示,LED 往上加,说明系统程序正常执行。

AVR 教程(22):AVR USART(UART)发送中断程序 使用缓冲 器

作者:微雪电子 文章来源:www.waveshare.net 点击数: 系统功能

79 更新时间:2008-4-1 23:33:22

使用 USART 发送数据,需要一定时间,若是用传统方法,等发送完再处理其 它任务(如语句
while(!(UCSRA&0x40));),那么,将大大降低了高速的 AVR 的执

行效率!AVR 会等到“花都谢了~” 那么怎样处理才可以解决低速串口与高速 AVR 之间的矛盾呢?可以采用开 辟发送缓冲区的做法: 当 AVR 需要发送数据时,如果 USART 口不空闲或者发送缓冲区还有待发送的 数据,就将数据放入发送缓冲器中(如果缓冲器未满),AVR 不必等待,可以转 去执行其它任务。而后,等 USART 的硬件发送完一个数据后产生中断,由中断服 务程序负责将发送缓冲器中数据依次送出。 发送缓冲器数据结构的设计:循环队列,由读、写 2 个指针及一个队列计 数器控制,用于判断当前写入数据、读出数据在队列中的位置,并判断队列是 否为空,是否已满。 程序设计时需注意,为了防止处理冲突,在对数据缓冲器的读、写过程中, 要将中断关闭,避免错误产生,从而提高程序的可靠性。
硬件设计

AVR 主控电路原理图

LED 控制电路原理图 软件设计

//目标系统: 基于 AVR 单片机 //应用软件: ICC AVR

/*01010101010101010101010101010101010101010101010101010101010101010 101 --------------------------------------------------------------------实验内容: 使用 USART 的发送中断功能,并使用缓冲解决高速 AVR 与低速串口之间的矛盾 --------------------------------------------------------------------硬件连接: 将 PB 口的 LED 指示灯使能开关切换到"ON"状态。 --------------------------------------------------------------------注意事项: (1)若有加载库程序,请将光盘根目录下的“库程序”下的“ICC_H”文件夹拷到 D 盘

(2)请详细阅读:光盘根目录下的“产品资料开发板实验板 SMK 系列 SMK1632 说明资料” --------------------------------------------------------------------1010101010101010101010101010101010101010101010101010101010101010101 0*/

#include <iom16v.h> #include "D:ICC_HCmmICC.H"

#define DISP_PORT PORTB #define DISP_DDR DDRB

#define TX_BUFFER_SIZE 255 #define UDR_EMPTY (1<<UDRE)

uint8 tx_buffer[TX_BUFFER_SIZE],tx_wr_index=0,tx_rd_index=0,tx_coun ter=0;

/*------------------------------------------------------------------程序名称:UART 初始化程序 程序功能:初始化 UART 为:8 位,9.6K,接收中断 注意事项:基于 7.3728M 晶振 提示说明:晶振不要买到假的,要不然,调不出来还以为电脑有鬼! 输 返 入: 回:

-------------------------------------------------------------------*/ void uart0_init(void) { UCSRB = 0x00; UCSRA = 0x00; //disable while setting baud rate //U2X = 0,不加倍数率

UCSRC = 0x86; UBRRL = 47; UBRRH = 0x00; UCSRB = 0x58; }

//8 位 //set baud rate lo,波特率为 9.6K //set baud rate hi //发送中断允许,接收缓冲自动清空,接收允许

/*------------------------------------------------------------------程序名称:UART 发送中断服务程序 程序功能: 注意事项: 提示说明: 输 返 入: 回:

-------------------------------------------------------------------*/ #pragma interrupt_handler uart0_tx_isr:14 void uart0_tx_isr(void) { if (tx_counter) //如果缓冲区有数据则进入发送程序 { tx_counter--; UDR=tx_buffer[tx_rd_index]; if (++tx_rd_index == TX_BUFFER_SIZE) //如果缓冲区读指针满 tx_rd_index=0; } } /*------------------------------------------------------------------程序名称: 程序功能:UART 发送程序 //读指针置 0

注意事项: 提示说明: 输 返 入: 回:

-------------------------------------------------------------------*/ void uart0_putchar(uint8 c) { while (tx_counter == TX_BUFFER_SIZE); //如果缓冲区满则等待 CLI(); if (tx_counter || ((UCSRA & UDR_EMPTY)==0)) DR 不空闲 { tx_buffer[tx_wr_index]=c; //将数据写入缓冲 //如果已经写满 //如果缓冲区有数据或者 U

if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0; tx_counter++; } else //如果缓冲区没有数据且 UDR 空闲 UDR=c; SEI(); } //没什么事就发了吧 //写指针置 0

/*------------------------------------------------------------------程序名称: 程序功能: 注意事项: 提示说明: 输 返 入: 回:

-------------------------------------------------------------------*/ void mcu_init(void) { CLI(); uart0_init(); MCUCR = 0x00; GICR = 0x00; //timer interrupt sources //re-enable interrupts

TIMSK = 0x00; SEI(); }

/*------------------------------------------------------------------程序名称: 程序功能: 注意事项:没什么好说的。。。 提示说明: 输 返 入: 回:

-------------------------------------------------------------------*/ void main() { uint8 sendChar=0;

mcu_init(); DISP_DDR=0xFF;

while(1) {

uart0_putchar(sendChar); //发送数据,数据为变量 sendChar delay50us(20); DISP_PORT=tx_counter; } } //显示发送区数据量

系统调试

(1)缓冲区数据量 tx_counter 的值取决于 AVR 的发送频率及 UART 的波特率。假定 UART 的波特率一定, 若是 AVR 的发送频率过高,低速的 UART 的发送速度将跟不上,导致缓冲区数据量 tx_counter 不断增加。 用 LED 指示 tx_counter,将可以观察到向上加的现象。 (2)改变 UART 初始化语句:UBRRL = 47; 将“47”改为“40”、“60”、“80”,从而改变 UART 的 波特率。可以看到波特率越高,数据量 tx_counter 向上加的速度越低;当波特率高到一定程度,发送时 间将小于延时时间,UART 空闲,程序不将待发送的数据放入缓冲,即缓冲区没有数据,数据量 tx_coun ter 一直为“0”;波特率越低,数据量 tx_ounter 向上加的速度越高。用 LED 指示 tx_counter 的数据 量,观察现象。

AVR 教程(23):AVR 看门狗 WDT 程序

作者:微雪电子 文章来源:www.waveshare.net 点击数: 系统功能

54 更新时间:2008-4-1 23:32:24

很多人喜欢养宠物狗,很多单片鸭大侠则喜欢养看门狗,如果您也希望搞条 AVR 的看门狗养 养,那么本节很适合您。 养看门狗的用意,在于用它监控系统:在程序本该运行的地方喂狗,如果程序卡死或跑飞, 将不会运行到那,那样狗没有被喂到,饿死了,控制器复位,得以重启从而进行控制。 本节演示功能:养一只 AVR 内部看门狗,及时喂狗,狗不饿死,AVR 单片鸭不复位;不及时喂 狗,狗饿死了,AVR 单片鸭就复位。 本节的程序设计较为简单,旨在给出养狗、喂狗,不让狗饿死的简单示例。实际应用时考 虑情况较多的要注意什么时候喂狗,放狗。
硬件设计

AVR 主控电路原理图

LED 控制电路原理图 软件设计

//目标系统: 基于 AVR 单片机 //应用软件: ICC AVR

/*01010101010101010101010101010101010101010101010101010101010101010101 ----------------------------------------------------------------------

实验内容: 观察喂狗与不喂狗的区别,使用 PB 口的 LED 指示灯做状态指示。 ---------------------------------------------------------------------硬件连接: 将 PB 口的 LED 指示灯使能开关切换到"ON"状态。 ---------------------------------------------------------------------注意事项: (1)若有加载库程序,请将光盘根目录下的“库程序”下的“ICC_H”文件夹拷到 D 盘 (2)请详细阅读:光盘根目录下的“产品资料开发板实验板 SMK 系列 SMK1632 说明资料” ---------------------------------------------------------------------10101010101010101010101010101010101010101010101010101010101010101010*/

#include <iom16v.h> #include "D:ICC_HCmmICC.H"

#define DISP_DDR DDRB #define DISP_PORT PORTB

/*-------------------------------------------------------------------程序名称:看门狗 WDT 初始化程序 程序功能: 注意事项: 提示说明: 输 返 入: 回:

--------------------------------------------------------------------*/ void wdt_init(void) { asm("wdr"); //clr wdt

WDTCR=0x0F; }

//enable wdt,clk = 2048,2.1S

/*-------------------------------------------------------------------程序名称: 程序功能: 注意事项: 提示说明: 输 返 入: 回:

--------------------------------------------------------------------*/ void main(void) { uint8 i; 8 字节整型

DISP_DDR = 0XFF;定义为输出 wdt_init();

while(1) { DISP_PORT++; asm("wdr"); delay50ms(20); } } //数据显示向上加,作 AVR 正常运行的指示 //喂狗,去除此句将导致狗饿死,AVR 复位

系统调试

在 AVR 的运行程序中设置让 PB 显示端口自加。若 AVR 正常工作,及时喂狗,则单片机设置的显示端口正常自加。 去除语句:asm("wdr");单片机不断复位,程序得不到允许,自加数据没有显示往上加。

AVR 教程(24):AVR EEPROM

作者:微雪电子 文章来源:www.waveshare.net 点击数:

90 更新时间:2008-4-1 23:31:37

系统功能

对 AVR 内部的 EEPROM 写入数据,再读出 EEPROM 的数据,用 LED 进行指示,观察读出 的数据与写入的数据是否一致。
硬件设计

AVR 主控电路原理图

LED 控制电路原理图

软件设计

//目标系统: 基于 AVR 单片机 //应用软件: ICC AVR

/*010101010101010101010101010101010101010101010101010101010101010101 01 --------------------------------------------------------------------实验内容: 写入一些测试数据进 EEPROM,再读出,使用 PB 口的 LED 做指示,观测是否与写入一致。 --------------------------------------------------------------------硬件连接: 将 PB 口的 LED 指示灯使能开关切换到"ON"状态。 --------------------------------------------------------------------注意事项: (1)若有加载库程序,请将光盘根目录下的“库程序”下的“ICC_H”文件夹拷到 D 盘 (2)请详细阅读:光盘根目录下的“产品资料开发板实验板 SMK 系列 SMK1632 说明资料” --------------------------------------------------------------------10101010101010101010101010101010101010101010101010101010101010101010 */

#include <iom16v.h> #include "D:ICC_HCmmICC.H"

#define DISP_DDR #define DISP_PORT

DDRB PORTB

/*------------------------------------------------------------------程序名称: 程序功能: 注意事项: 提示说明: 输 返 入: 回:

-------------------------------------------------------------------*/ void main(void) { uint8 i; uint8 wrDat=0xAA; uint8 wrDat_[]={1,2,3,4,5,6,7,8},rdDat_[8]; DISP_DDR=0xFF; EEPROMwrite(0x01,wrDat); //写入单个数据 DISP_PORT=EEPROMread(0x01); //读出用指示灯验证是否正确 delay50ms(40); //有 2S 的观察时间

EEPROMWriteBytes(1,wrDat_,8); //对 EEPROM 写入数组数据 EEPROMReadBytes(1,rdDat_,8); //对 EEPROM 读出数据 for(i=0;i<7;i++) { delay50ms(40); //有 2S 的观察时间

DISP_PORT=rdDat_[i]; //读出用指示灯验证是否正确 } while(1); }

系统调试

观察读出的 EEPROM 数据与写入 EERPOM 的数据是否一致,用 LED 作为数据,没 什么好说的。。。

AVR 教程(25):AVR PWM OC0

作者:微雪电子 文章来源:www.waveshare.net 点击数: 系统功能

99 更新时间:2008-4-1 23:30:49

AVR 内部脉宽调制 OC0 输出实验, LED 指示 PWM 的频率, PWM 速度较低时, 用 在

可观察到 LED 的闪烁。
硬件设计

AVR 主控电路原理图

软件设计

//目标系统: 基于 AVR 单片机 //应用软件: ICC AVR

/*01010101010101010101010101010101010101010101010101010101010101010 101 --------------------------------------------------------------------实验内容: AVR 内部脉宽调制输出实验,用 LED 指示 PWM 的频率,在 PWM 速度较低时,可观察到 LED 的闪烁。 --------------------------------------------------------------------硬件连接: 将 UserLed 指示灯连接至 PWM 的端口 PB3/OC0。 --------------------------------------------------------------------注意事项: (1)若有加载库程序,请将光盘根目录下的“库程序”下的“ICC_H”文件夹拷到 D 盘 (2)请详细阅读:光盘根目录下的“产品资料开发板实验板 SMK 系列 SMK1632 说明资料” --------------------------------------------------------------------1010101010101010101010101010101010101010101010101010101010101010101 0*/

#include <iom16v.h> #include <macros.h>

#define OC0_OUT_EN DDRB |= 0b00001000

/*-------------------------------------------------------------------

程序名称:定时器 0 初始化程序 程序功能:定时器作 PWM 使用,设置 PWM 的工作模式 注意事项: 提示说明: 输 返 入: 回:

-------------------------------------------------------------------*/ void timer0_init(void) { TCCR0 = (1<<WGM01)|(1<<WGM00)|(1<<COM01)|(1<<COM00)|(1<<CS00); /* WGM01=1; WGM00=1; --> fast PWM modle COM01=1; COM00=0; --> 比较匹配时 set OC0 pin CS00=1; 够快 */ TCNT0 = 0x00; OCR0 } /*------------------------------------------------------------------程序名称: 程序功能: 注意事项: 提示说明: 输 返 入: 回: = 0x10; //设置 TC0 计数寄存器初值 //输出比较寄存器初值,设置该值可用于调节 OC0 输出占空比 --> timer0 source 不经过任何分频,直接为 Clk,使得 PWM 可以工作得足

-------------------------------------------------------------------*/

void main(void) { OC0_OUT_EN; timer0_init(); SEI(); while(1); } //为允许 PWM 工作,需设置 PB3 为输出

系统调试

改变 PWM 初始化代码的如下两个语句的赋值:

TCNT0 = 0x00; OCR0 = 0x10;

//设置 TC0 计数寄存器初值 //输出比较寄存器初值,设置该值可用于调节 OC0 输出占空比

从 LED 的闪烁频率可以看出,改变了 PWM 的频率。

AVR 教程(26):AVR PWM OC2

作者:微雪电子 文章来源:www.waveshare.net 点击数: 系统功能

73 更新时间:2008-4-1 23:29:58

AVR 内部脉宽调制 OC2 输出实验, LED 指示 PWM 的频率, PWM 速度较低时, 用 在

可观察到 LED 的闪烁。
硬件设计

AVR 主控电路原理图

软件设计

//目标系统: 基于 AVR 单片机 //应用软件: ICC AVR

/*01010101010101010101010101010101010101010101010101010101010101010 101 --------------------------------------------------------------------实验内容: AVR 内部脉宽调制输出实验,用 LED 指示 PWM 的频率,在 PWM 速度较低时,可观察到 LED 的闪烁。 --------------------------------------------------------------------硬件连接: 将 UserLed 指示灯连接至 PWM 的端口 PD7/OC2。 --------------------------------------------------------------------注意事项: (1)若有加载库程序,请将光盘根目录下的“库程序”下的“ICC_H”文件夹拷到 D 盘

(2)请详细阅读:光盘根目录下的“产品资料开发板实验板 SMK 系列 SMK1632 说明资料” --------------------------------------------------------------------1010101010101010101010101010101010101010101010101010101010101010101 0*/

#include <iom16v.h> #include <macros.h>

#define OC2_OUT_EN DDRD |= 0b10000000

/*------------------------------------------------------------------程序名称:定时器 2 初始化程序 程序功能:定时器作 PWM 使用,设置 PWM 的工作模式 注意事项: 提示说明: 输 返 入: 回:

-------------------------------------------------------------------*/ void timer2_init(void) { TCCR2 = (1<<WGM21)|(1<<WGM20)|(1<<COM21)|(1<<COM20)|(1<<CS20); /* WGM21=1; WGM20=1; --> fast PWM modle COM21=1; COM20=0; --> 比较匹配时 set OC2 pin CS20=1; 够快 */ TCNT2 = 0x00; //设置 TC2 计数寄存器初值 --> timer2 source 不经过任何分频,直接为 Clk,使得 PWM 可以工作得足

OCR2 }

= 0xE0;

//输出比较寄存器初值,设置该值可用于调节 OC2 占空比

/*------------------------------------------------------------------程序名称: 程序功能: 注意事项: 提示说明: 输 返 入: 回:

-------------------------------------------------------------------*/ void main(void) { OC2_OUT_EN; timer2_init(); SEI(); while(1); } //为允许 PWM 工作,需设置 PD7 为输出

系统调试

改变 PWM 初始化代码的如下两个语句的赋值:

TCNT2 = 0x00; OCR2 = 0xE0;

//设置 TC2 计数寄存器初值 //输出比较寄存器初值,设置该值可用于调节 OC2 占空比

从 LED 的闪烁频率可以看出,改变了 PWM 的频率。

AVR 教程(27):AVR AD 转换 中断

作者:微雪电子 文章来源:www.waveshare.net 点击数:

142 更新时间:2008-4-1 23:28:59

AVR AD 转换 中断
系统功能

大部分 AVR 内部带有 AD,本节以使用 ATMEGA16 的内部 AD 为例,给出 AD 转换中 断程序。
硬件设计

AVR 主控电路原理图 软件设计

//目标系统: 基于 AVR 单片机 //应用软件: ICC AVR

/*01010101010101010101010101010101010101010101010101010101010101010 101 --------------------------------------------------------------------实验内容: 使用中断检测 AD0 口,使用 PB/PD 口的 LED 指示 AD 读到的数据。 ---------------------------------------------------------------------

硬件连接: 将“ADJ0.AD0”引针与“MCU.AD0” 引针使用短路帽短接。 将 PB/PD 口的 LED 指示灯使能开关切换到"ON"状态。 --------------------------------------------------------------------注意事项: (1)若有加载库程序,请将光盘根目录下的“库程序”下的“ICC_H”文件夹拷到 D 盘 (2)请详细阅读:光盘根目录下的“产品资料开发板实验板 SMK 系列 SMK1632 说明资料” --------------------------------------------------------------------1010101010101010101010101010101010101010101010101010101010101010101 0*/

#include <iom16v.h> #include "D:ICC_HCmmICC.H"

#define H_VAL_DISP_DDR #define L_VAL_DISP_DDR

DDRD DDRB

#define H_VAL_DISP_PORT PORTD #define L_VAL_DISP_PORT PORTB

const uint8 ADEnStatus[8] = {0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7 F};

uint8 AdcMux; uint16 AdcVal;

//ADC 通道 //ADC 转换值

/*------------------------------------------------------------------程序名称:AD 转换初始化程序 程序功能: 注意事项:

提示说明: 输 返 入: 回:

-------------------------------------------------------------------*/ void adc_init() { /* 设置对应的 IO 口为输入高阻态 */ DDRA &= ADEnStatus[AdcMux]; PORTA &= ADEnStatus[AdcMux];

ADCSRA = 0x00;

//disable adc

ADMUX = (1<<REFS1)|(1<<REFS0)|(AdcMux&0x0F); //select adc input cha nnel ACSR = (1<<ACD); //close analog comparator

ADCSRA=(1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1); } /*------------------------------------------------------------------程序名称:AD 转换中断服务程序 程序功能: 注意事项: 提示说明: 输 返 入: 回:

-------------------------------------------------------------------*/ #pragma interrupt_handler adc_isr:15 void adc_isr(void) {

AdcVal = ADC&0x3FF; ADMUX = (1<<REFS0)|(AdcMux&0x0F); //使用 AVcc 作为 ADC 参考电源 ADCSRA |= (1<<ADSC); } /*------------------------------------------------------------------程序名称: 程序功能: 注意事项: 提示说明: 输 返 入: 回: //ADSC: AD start conversion

-------------------------------------------------------------------*/ void main(void) { H_VAL_DISP_DDR = 0xFF; L_VAL_DISP_DDR = 0xFF; AdcMux = 0; adc_init(); SEI(); while(1) { H_VAL_DISP_PORT = (AdcVal&0x300)>>8; //ADC 的高 2 位 Val L_VAL_DISP_PORT = AdcVal&0xFF; } } //ADC 的低 8 位 Val //使用 ADC 通道 0

系统调试

用 LED 显示 AD 转换值,调“ADJ0.AD0”的可调电阻可改变 AD 转换值,观察它的变化。


相关文章:
AVR单片机入门教程
AVR单片机入门教程_信息与通信_工程科技_专业资料。AVR 单片机入门教程 (一)AVR 单片机入门范例我们先以一个范例来带领大家进入 AVR 单片机的精彩世界 1. 新手在...
各种单片机的区别
各种单片机的区别_信息与通信_工程科技_专业资料。PIC单片机、AVR单片机、C51单片机有什么区别?PIC 单片机、AVR 单片机、C51 单片机有什么区别? 单片机、 单片机、 单...
51单片机系列与AVR单片机系列对比
083211 李英男 51 系列与 AVR 单片机对比的优势 单片机对比的优势 1、AVR 单片机(ATmega16)的时钟源(晶振、内部 RC 等)可以不经过分频直接提供给 CPU 使用,而...
avr单片机_教程_实例_附电路图
如 Attiny26,Atmega8,Atmega8515 等 AVR 单片机基本硬件电路设计包括:AVR 复位电路和下载电路的设计,另外 AVR 晶振电路可以不加。● AVR 复位电路的设计 与传统的...
简易AVR单片机教程
简易AVR单片机教程_其它_高等教育_教育专区。单片机入门 操作 的 简单 教程简易单片机教程 ICCAVR 的使用 参考程序代码 1 模拟比较器 #include<iom16v.h> #include...
AVR单片机的程序
AVR单片机的程序_电子/电路_工程科技_专业资料 暂无评价|0人阅读|0次下载|举报文档 AVR单片机的程序_电子/电路_工程科技_专业资料。/***相位修正模式***/ #inc...
avr单片机的优点
avr单片机的优点_电子/电路_工程科技_专业资料。avr单片机的优点,主要介绍avr单片机的发展史,应用领域,前景? AVR 单片机是 1997 年由 ATMEL 公司研发出的增强型内置...
各种单片机的比较
各种单片机的比较_电子/电路_工程科技_专业资料。1、AVR 单片机与 8051 的比较: 主要区别是内核不同,指令集不同,io 结构不同,外设不同。 优点是速度快,IO 强...
AVR单片机的基本结构
单片机的基本结构 第2章 AVR 单片机的基本结构单片机是构成单片机嵌入式系统的核心器件。 本章首先将介绍一般单片机的基本结构和 组成, 使大家对单片机芯片的内部硬件...
AVR单片机考试题及答案
AVR单片机考试题及答案_工学_高等教育_教育专区。AVR 单片机考试题及答案第一章(较易) 填空: 1. 单片机的基本组成结构包括: CPU 、、 数据寄存器 、 输入接口...
更多相关标签:
avr单片机教程 | 单片机 | avr单片机和51的区别 | avr | avr单片机选型 | 郭天祥 | pic单片机 | arm单片机 |