AVR/Arduino定时/计数器、中断入门
在Arduino中,可以使用AnalogWrite来使用硬件产生490Hz/980Hz的pwm波,并可根据参数来设定占空比。不了解这个的同学可以去AnalogWrite学习下,SecretsOfArduinoPWM也是讲了Arduino在avr的定时/计数器上做的封装,我们这里并不讲Arduino相关,而是讲AVR的定时/计数器,如何产生更多PWM波和定时/计数器的中断使用。
AVR Timer/Counter(以下统称Timer)
以ATmega358p为例,其内部拥有一个16位计时器,两个8位计时器,下图则为16位计时器的大致图解:

对于没有接触过avr内部的Arduino同学来说,这张图看不出来任何意思,别急,这些都是AVR-GCC里定义的缩写,我们先来解释下图中的缩写对照:
| 缩写 | 全称 |
|---|---|
| TCNT | Timer/Counter Register |
| TCCR | Timer/Counter Control Register |
| OCR | Output Compare Register |
| OC | Output Compare Match Output |
| ICR | Input Capture Register |
| Int.Req | Interrupt Request |
| TOV | Timer Overflow |
| ICF | Input Capture Flag |
而图中TCNT为主要工作部件,其工作模式的是依据TCCR的设定值。以该16位计时器为例,该计时器在ATmega358p中的序号为1,则其所有缩写都会与1有关,即TCNT1的工作模式由TCCR1A和TCCR1B来决定。不急着看别的,我们先来瞅瞅TCCR1A与TCCR1B是怎么来配置TCNT1的工作模式的:
TCCR1A:

图中7、6、5、4位分别应该是COM1A1、COM1A0、COM1B1、COM1B0,话说这datasheet有时候也真是会省事儿
TCCR1B:

这两个寄存器都是八位寄存器,再来一张表来对照一下图中的缩写:
| 缩写 | 全称 |
|---|---|
| COMnA | Compare Output Mode for Channel A |
| COMnB | Compare Output Mode for Channel B |
| WGM | Wave Generation Mode |
| ICNC | Input Capture Noise Canceler |
| ICES | Input Capture Edge Select |
| CS | Clock Select |
我们通过配置这两个寄存器来控制TCNT1的工作模式,通过配置WGM来选择波型生成模式,主要有Fast PWM/PWM Phase Correct/CTC模式,并且也拥有不同的计数TOP值,有0xFF/ICR1/OCR1A等,通过COM结合WGM对针脚的输出做配置,用CS来选择生成波型的prescaler,分别有1/8/64/256/1024,或者外部时钟。TOP值为ICR1或OCR1A时,要对使用的寄存器进行赋值。工作模式中,Fast PWM与PWM Phase Correct这两种计数模式不同的是,PWM Phase Correct可以到达top值后又递减至0,Fast PWM到达top值后则会触发上升或下降沿。
如下配置:
TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM10);
TCCR1B = _BV(CS12) | _BV(CS10);
//WGM配置了PWM Phase Correct,使用的TOP值为0x00FF
//COM配置了在往上计数时清零,往下计数时置位
//使用了1024的prescaler
OCR1A = 100;
OCR1B = 50;
则我们可以得到的时钟频率为Fclk/(prescaler*TOP)=16000000/(1024*255)/2=30.63Hz,且OC1A占空比为OCR1A/TOP=100/255=39%,OC1B占空比为OCR1B/TOP=50/255=19.6%。
更多配置组合请看SecretsOfArduinoPWM/PWM的秘密或直接datasheet,其中要注意的是,使用OCR1A为TOP值时,可以在一定范围内配置任意频率,但OC1A的占空比为始终为50%,OC1B的占空比为(OCR1B+1)/(OCR1A+1)。
Interrupt
中断是其它与CPU异步进行的硬件与CPU交互的一种方法。这样我们就不用在CPU中去等待其它某些任务的完成和触发状态,由其它硬件去来触发进入CPU主进程的时机。回头看第一张大图,在图中可以找到四处(Int.Req),分别是TOVn(Timer/Counter Overflow), OCnA(Output Compare A Match), OCnB(Output Compare B Match), ICF(Input Capture Flag),根据字义我们便可了解到该中断的作用,在使用中断时,我们要先于TIMSK1(Timer/Counter 1 Interrupt Mask Register)中开启相应的中断位。
下图为TIMSK1:

图中的字母应为ICIE1, OCIE1B, OCIE1A, TOIE1,这数据手册,也是太懒了。下表为对照:
| 缩写 | 全称 |
|---|---|
| ICIE | Input Capture Interrupt Enable |
| OCIE | Output Compare Interrupt Enable |
| TOIE | Timer/Counter Overflow Interrupt Enable |
开启该遮罩位后,便可打开中断,前提也是在全局中断打开的情况下(sei()为打开全局中断,cli()为关闭全局中断)。在当下的AVR-GCC环境中,我们使用宏命令ISR来定义中断程序,使用方法如下:
ISR(xxxx_vect)
{
// user code here
}
而这里的xxxx_vect则是要监听的中断向量地址,可以于Atmel官网<avr/interrupt.h>: Interrupts上找得到所有中断对应的向量名称。
如上面的四种向量,于mega328p中,则分别对应:
| ICIE1 | TIMER1_CAPT_vect |
| OCIE1A | TIMER1_COMPA_vect |
| OCIE1B | TIMER1_COMPB_vect |
| TOIE1 | TIMER1_OVF_vect |
而中断又分为两种,一种为事件触发型,这种中断会在上一个中断没有运行结束前队列等待,直至前面优先的任务完成后才能执行;另一种为中断条件触发,如果上一个中断还没有返回回来,那么则不会触发这个中断(如果定时器为高频时则会出现该情况)。所以在使用中断的时候,进入中断、跳转、返回都需要耗费时钟,不要对高频使用中断,甚至会使主线程一直处于堆栈状态,且中断中不要运行太多程序。
There are basically two types of interrupts: The first type is triggered by an event that sets the Interrupt Flag. The second type of interrupts will trigger as long as the interrupt condition is present.
The traps when using interrupts中也是罗列了一些使用中断的坑和技巧,可以看看。附上Atmega328p的datasheet,真是有问题就看datasheet,上面的图与摘录都是从datasheet里出来的。
Have fun.
AVR/Arduino定时/计数器、中断入门的更多相关文章
- stm32寄存器版学习笔记04 定时计数器中断
STM32共有8个定时计数器,其中TIME1和TIME8是高级定时器,TIME2~TIME5是通用定时器,TIME6和TIME7是基本定时器.以TIME3为例总结定时计数器的基本用法. 1.TIM3的 ...
- 【CC2530入门教程-04】CC2530的定时/计数器原理与应用
第4课 CC2530的定时/计数器原理与应用 广东职业技术学院 欧浩源 一.定时/技术器的基本原理 定时/计数器,是一种能够对内部时钟信号或外部输入信号进行计数,当计数值达到设定要求时,向CPU提 ...
- AVR单片机教程——定时器中断
本文隶属于AVR单片机教程系列. 中断,是单片机的精华. 中断基础 当一个事件发生时,CPU会停止当前执行的代码,转而处理这个事件,这就是一个中断.触发中断的事件成为中断源,处理事件的函数称为中断 ...
- Arduino可穿戴开发入门教程(大学霸内部资料)
Arduino可穿戴开发入门教程(大学霸内部资料) 试读下载地址:链接:http://pan.baidu.com/s/1mg9To28 密码:z5v8 介绍:Arduino可穿戴开发入门教程(大学霸内 ...
- 51单片机 | 定时/计数器原理及结构(T0和T1)
———————————————————————————————————————————— 定时/计数器结构(T0和T1) 16位寄存器T0.T1分别由TH0.TL0和TH1.TL1四个8位计数器组成 ...
- Arduino可穿戴开发入门教程Windows平台下安装Arduino IDE
Arduino可穿戴开发入门教程Windows平台下安装Arduino IDE Windows平台下安装Arduino IDE Windows操作系统下可以使用安装向导和压缩包形式安装.下面详细讲解这 ...
- Arduino可穿戴开发入门教程Arduino开发环境介绍
Arduino可穿戴开发入门教程Arduino开发环境介绍 Arduino开发环境介绍 Arduino不像我们使用的PC端操作系统一样,可以直接在操作系统中安装软件为操作系统编程.Arduino的软件 ...
- Arduino可穿戴开发入门教程LilyPad和LilyPad Simple的介绍
Arduino可穿戴开发入门教程LilyPad和LilyPad Simple的介绍 LilyPad和LilyPad Simple的介绍 LilyPad和LilyPad Simple是LilyPad微控 ...
- Arduino可穿戴开发入门教程LilyPad介绍
Arduino可穿戴开发入门教程LilyPad介绍 Arduino输出模块 LilyPad官方共提供了4种输出模块,他们分别是单色LED模块(图1.5).三色LED模块(图1.6).蜂鸣器模块(图1. ...
随机推荐
- android XMl 解析神奇xstream 五: 把复杂对象转换成 xml ,并写入SD卡中的xml文件
前言:对xstream不理解的请看: android XMl 解析神奇xstream 一: 解析android项目中 asset 文件夹 下的 aa.xml 文件 android XMl 解析神奇xs ...
- IOS编程思想
从今天起想走进IOS架构的大门,一直不屑于学习第三方框架,觉得框架也是一点点代码给垒起来的,只要掌握了代码就可以了,殊不知垒代码的过程才是最重要的,而这个过程又岂是一朝一夕就能达到完美境界的,达到完美 ...
- TCP/IP协议握手过程详解
1,建立连接 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接,如图1所示. (1)第一次握手:建立连接时,客户端A发送SYN包(SYN=j)到服务器B,并进入SYN_SE ...
- 学习C语言常用的几个网站
今天整理资料,发现了以前学习C语言时,常用到的几个网站: 1.http://ganquan.info/standard-c/ 改网站包含了C语言标准版的15个头文件解释以及函数,137个函数和演示 ...
- Swift语言
本文为熟悉使用Objective-C开发iOS快速转入swift开发提供一些便利的途径,没有过多华丽的说明底层原理,也没有过多的概念说明,只提供swift的基本使用以及一些使用示例.高手请让路哈. S ...
- 21分钟 MySQL 入门教程
目录 一.MySQL的相关概念介绍 二.Windows下MySQL的配置 配置步骤 MySQL服务的启动.停止与卸载 三.MySQL脚本的基本组成 四.MySQL中的数据类型 五.使用MySQL数据库 ...
- 超链接的那些事(三): 属性target
a标签的属性之一 target 1. 定义 规定在何处打开链接文档. 如果a标签中有target属性,浏览器将会载入和显示用这个标签的 href 属性命名的.名称与这个目标吻合的框架或者窗口中 ...
- 嵌入式Linux应用程序开发详解------(创建守护进程)
嵌入式Linux应用程序开发详解 华清远见 本文只是阅读文摘. 创建一个守护进程的步骤: 1.创建一个子进程,然后退出父进程: 2.在子进程中使用创建新会话---setsid(): 3.改变当前工作目 ...
- 标准库shared_ptr智能指针的实现
目前测试功能正常.若有不完善的地方在改进吧.时候不早了睡觉去,哎,翘课会被抓,不冒险了.晚安全世界O(∩_∩)O /****************************************** ...
- Astyle编程语言格式化工具的中文说明
Artistic Style 1.23Maintained by: Jim PatteeOriginal Author: Tal Davidson Usage : astyle [options] ...