
Arduino的定时器功能文章目录Arduino的定时器功能引言1.定时器相关的寄存器1.1 T/C1 控制寄存器 TCCR1A、TCCR1B2.TCNT1H 与 TCNT1L寄存器3.输出比较寄存器 1A OCR1AH与 OCR1AL4.输出比较寄存器 1B OCR1BH与OCR1BL5.输入捕捉寄存器 1 ICR1H 与ICR1L6.中断屏蔽寄存器 TIMSK7. 中断标志寄存器 TIFR实验程序1.time1的匹配模式(CTC)实现定时器的功能2.time1的普通模式实现定时器的功能3.通过time0/1/2输出PWM波(软件PWM频率高了会波形不稳定)4.MsTimer2库的使用5.TimerOne的使用6.Mega 2560板的time37.Mega 2560板的time48.Mega 2560板的time5引言作者小石头 时间2021年7月25日 邮箱786721684qq.com 声明本文所用素材、配图等均来源于公开分享内容仅作技术学习交流使用无任何商业用途若涉及侵权请及时告知我将第一时间进行删除处理。在开发Arduino的过程中我们往往使用已经封装好的API对于一些延时或定时器的操作也有一些封装好的API可供使用比如millis()、delay(ms)、analogWrite(pin, value)、pulseIn(EchoPin, HIGH)等等但这些都是写死的API无法做到像51和32单片机那样自己定义中断服务函数的内容这些API的底层其实也是操作定时器相关的寄存器来实现的自己去配置好寄存器即可自己定义中断服务函数的内容(自定义了指定的定时器相关的配置原本Arduino的一些API将不能使用后面将给出对应关系)。本博客的实验代码工程文件百度网盘链接(包含了其他模块的例程定时器的从第18个-第24个里面还有一些自己做的笔记文件)通过网盘分享的文件官方IDE链接: https://pan.baidu.com/s/1x6Bx8v8j9_eZiXfAFRNVQw?pwd1234 提取码: 1234Arduino Uno的定时器time0(8位)、time1(16位)、time2(8位)Arduino Mega 2560的定时器time0(8位)、time1(16位)、time2(8位)、time3(16位)、time4(16位)、time5(16位)MsTimer2(定时器2)、TimerOne(定时器1)库的使用定时器对应的API定时器0delay()|、millis()、micros()定时器1Servo库(Mega 2560为定时器5)定时器2tone() 定时器对应Arduino Uno的PWM口定时器0PWM口5、6(默认976Hz)定时器1PWM口9、10(默认490Hz)定时器2PWM口11、3(默认490Hz)注意Uno板子的11脚不能同时使用PWM和SPI协议的功能定时器对应Arduino Mega 2560的PWM口定时器0PWM口4、13定时器1PWM口11、12定时器2PWM口9、10定时器3PWM口2、3、5定时器4PWM口6、7、8定时器5PWM口44、45、46声明本博客参考的其他博客arduino 定时器、定时中断与PWM使用以及注意事项、[arduino 计时器和中断](arduino 计时器和中断_arduino timer-CSDN博客)、[【Arduino学习笔记】系列1 - 定时器配置](【Arduino学习笔记】系列1 - 定时器配置_tccr0b-CSDN博客)、[Arduino Uno 定时器中断 timer 0,1, 2 自定义配置、MsTimer2、TimerOne库](Arduino Uno 定时器中断 timer 0,1, 2 自定义配置、MsTimer2、TimerOne库-CSDN博客)、[AVR定时计数器1的控制寄存器说明](AVR定时计数器1的控制寄存器说明 - 百度文库 (baidu.com))。如有侵权请联系删除1.定时器相关的寄存器8/16位的T/C 可以实现精确的程序定时( 事件管理) 、波形产生和信号测量。其主要特点如下真正的16位设计( 即允许16位的PWM)2 个独立的输出比较单元双缓冲的输出比较寄存器一个输入捕捉单元输入捕捉噪声抑制器比较匹配发生时清除寄存器( 自动重载)无干扰脉冲相位正确的PWM可变的PWM 周期频率发生器外部事件计数器4 个独立的中断源(TOV1 、 OCF1A 、OCF1B与ICF1)1.1 T/C1 控制寄存器 TCCR1A、TCCR1BBit 7:6 – COM1A1:0: 通道A 的比较输出模式Bit 5:4 – COM1B1:0: 通道B 的比较输出模式COM1A1:0 与COM1B1:0 分别控制OC1A 与OC1B 状态。如果COM1A1:0 (COM1B1:0 )的一位或两位被写入1”FOC1A( FOC1B) 输出功能将取代 I/O 端口功能。此时 FOC1A(FOC1B)相应的输出引脚数据方向控制必须置位以使能输出驱动器。OC1A(OC1B) 与物理引脚相连时 COM1x1:0 的功能由WGM13:0的设置决定。下表给出当WGM13:0设置为普通模式与CTC模式( 非PWM) 时COM1x1:0 的功能定义。比较输出模式非PWMWGM11、WGM10及WGM13、WGM12配置定时器工作模式CS12、CS11、CS10配置定时器的分频系数WGM130设置为快速PWM 模式时COM1x1:0 的功能定义。比较输出模式快速 PWM。比较输出模式相位修正及相频修正 PWM 模式Bit 3 – FOC1A: 通道A 强制输出比较Bit 2 – FOC1B: 通道B 强制输出比较FOC1A/FOC1B 只有当WGM13:0指定为非PWM模式时被激活。为与未来器件兼容工作在PWM 模式下对TCCR1A写入时这两位必须清零。当 FOC1A/FOC1B 位置1 立即强制波形产生单元进行比较匹配。COM1x1:0 的设置改变 OC1A/OC1B 的输出。注意FOC1A/FOC1B 位作为选通信号。COM1x1:0 位的值决定强制比较的效果。在CTC模式下使用OCR1A 作为TOP值FOC1A/FOC1B 选通即不会产生中断也不好清除定时器。FOC1A/FOC1B 位总是读为0。波形产生模式的位描述注: 1. CTC1 和 PWM11:0 的定义已经不再使用了要使用WGM12:0 。但是两个版本的功能和位置是兼容的。CNC1: 入捕捉噪声抑制器置位ICNC1 将使能输入捕捉噪声抑制功能。此时外部引脚ICP1 的输入被滤波。其作用是从ICP1 引脚连续进行4 次采样。如果4 个采样值都相等那么信号送入边沿检测器。因此使能该功能使得输入捕捉被延迟了4 个时钟周期。ICES1: 输入捕捉触发沿选择该位选择使用ICP1 上的哪个边沿触发捕获事件。ICES 为0” 选择的是下降沿触发输入捕捉ICES1 为1” 选择的是逻辑电平的上升沿触发输入捕捉。按照ICES1 的设置捕获到一个事件后计数器的数值被复制到 ICR1 寄存器。捕获事件还会置为ICF1。如果此时中断使能输入捕捉事件即被触发。当ICR1 用作TOP值(见TCCR1A与TCCR1B寄存器中WGM13:0位的描述 ) 时ICP1与输入捕捉功能脱开从而输入捕捉功能被禁用。时钟选择位描述2.TCNT1H 与 TCNT1L寄存器TCNT1H 与TCNT1L 组成了T/C1的数据寄存器TCNT1。通过它们可以直接对定时器/计数器单元的16位计数器进行读写访问。为保证CPU对高字节与低字节的同时读写必须使用一个8 位临时高字节寄存器TEMP 。TEMP 是所有的16位寄存器共用的在计数器运行期间修改TCNT1的内容有可能丢失一次TCNT1与OCR1x的比较匹配操作。写TCNT1寄存器将在下一个定时器周期阻塞比较匹配。3.输出比较寄存器 1A OCR1AH与 OCR1AL4.输出比较寄存器 1B OCR1BH与OCR1BL该寄存器中的16位数据与TCNT1寄存器中的计数值进行连续的比较一旦数据匹配将产生一个输出比较中断或改变OC1x 的输出逻辑电平。输出比较寄存器长度为16位。为保证CPU对高字节与低字节的同时读写必须使用一个8 位临时高字节寄存器TEMP 。5.输入捕捉寄存器 1 ICR1H 与ICR1L当外部引脚ICP1(或 T/C1的模拟比较器)有输入捕捉触发信号产生时计数器TCNT1中的值写入ICR1 中。ICR1 的设定值可作为计数器的TOP值。输入捕捉寄存器长度为16位。为保证CPU对高字节与低字节的同时读写必须使用一个8 位临时高字节寄存器TEMP 。6.中断屏蔽寄存器 TIMSKOCIE为比较匹配中断允许标志位TOIE为溢出中断允许标志位。OCIE1A、OCIE1B比较匹配中断允许TOIE1溢出中断允许7. 中断标志寄存器 TIFROCF为比较匹配中断标志位TOV为溢出中断标志位ICF1: T/C1 输入捕捉标志位外部引脚ICP1 出现捕捉事件时ICF1 置位。此外当ICR1 作为计数器的TOP值时一旦计数器值达到TOPICF1 也置位。执行输入捕捉中断服务程序时ICF1 自动清零。也可以对其写入逻辑1” 来清除该标志位。实验程序1.time1的匹配模式(CTC)实现定时器的功能#defineledPin13voidsetup(){pinMode(ledPin,OUTPUT);// initialize timer1noInterrupts();// disable all interruptsTCCR1A0;//先将整个TCCR0A寄存器设置为0TCCR1B0;//先将整个TCCR0B寄存器设置为0TCNT10;//将计数器值初始化为0OCR1A31250;// compare match register 16MHz/(256*31250) 2Hz 每0.5s执行一次中断服务函数TCCR1B|(1WGM12);// CTC modeTCCR1B|(1CS12);// 256 prescalerTIMSK1|(1OCIE1A);// enable timer compare interruptinterrupts();// enable all interrupts}ISR(TIMER1_COMPA_vect)// timer compare interrupt service routine{digitalWrite(ledPin,digitalRead(ledPin)^1);// toggle LED pin}voidloop(){// your program here…}2.time1的普通模式实现定时器的功能#defineledPin13voidsetup(){pinMode(ledPin,OUTPUT);// initialize timer1noInterrupts();// disable all interruptsTCCR1A0;TCCR1B0;TCNT134286;// preload timer 65536-16MHz/256/2HzTCCR1B|(1CS12);// 256 prescalerTIMSK1|(1TOIE1);// enable timer overflow interruptinterrupts();// enable all interrupts}ISR(TIMER1_OVF_vect)// interrupt service routine that wraps a user defined function supplied by attachInterrupt{TCNT134286;// preload timerdigitalWrite(ledPin,digitalRead(ledPin)^1);}voidloop(){// your program here...}3.通过time0/1/2输出PWM波(软件PWM频率高了会波形不稳定)inttoggle0,toggle1,toggle2;voidsetup(){cli();//noInterrupts(); // disable all interrupts 关闭全局中断/* //设置定时器0为10kHz(100us) TCCR0A 0;//将整个TCCR0A寄存器设置为0 TCCR0B 0;//将整个TCCR0B寄存器设置为0 TCNT0 0;//将计数器值初始化为0 //设置计数器为10kHZ即100us OCR0A 24;//比较匹配寄存器 [16,000,000Hz /预分频器*所需中断频率] - 1 //比较匹配寄存器24,中断间隔100us即中断频率10khz TCCR0A | (1 WGM01);//打开CTC模式 TCCR0B | (1 CS01) | (1 CS00); //设置CS01位为1CS00位为1(64倍预分频) TIMSK0 | (1 OCIE0A);//启用定时器比较中断 *///设置定时器1为1kHzTCCR1A0;//将整个TCCR1A寄存器设置为0TCCR1B0;//将整个TCCR1B寄存器设置为0TCNT10;//将计数器值初始化为0//设置计数器为1kHZ即1msOCR1A156;// (16*10^6)/(1000*8) - 1 (must be 65536) 100hz/2TCCR1B|(1WGM12);//打开CTC模式TCCR1B|(1CS12)|(1CS10);// 1024分频 设置CS11位为1(8倍预分频)TIMSK1|(1OCIE1A);/* //设置定时器2为8kHz TCCR2A 0;// set entire TCCR2A register to 0 TCCR2B 0;// same for TCCR2B TCNT2 0;//initialize counter value to 0 // set compare match register for 8khz increments OCR2A 249;// (16*10^6) / (8000*8) - 1 (must be 256) // turn on CTC mode TCCR2A | (1 WGM21);//打开CTC模式 // Set CS21 bit for 8 prescaler TCCR2B | (1 CS21); // enable timer compare interrupt TIMSK2 | (1 OCIE2A); */sei();//interrupts(); // enable all interrupts //打开全局中断}/* //中断0服务函数 ISR(TIMER0_COMPA_vect){// timer0中断2Hz切换引脚13LED //产生频率为10kHz / 2 5kHz的脉冲波 if(toggle0){ digitalWrite(8,HIGH); toggle0 0; } else{ digitalWrite(8,LOW); toggle0 1; } } */ISR(TIMER1_COMPA_vect){// timer1中断2Hz切换引脚13LED //中断优先级相同 3个中断中基本轮不到 执行不了//产生频率为2Hz / 2 1Hz的脉冲波/* if(toggle1500) digitalWrite(13,HIGH); if(toggle1500) digitalWrite(13,LOW); toggle1 1; if(toggle1 1000) toggle1 0; */if(toggle1){digitalWrite(13,HIGH);toggle10;}else{digitalWrite(13,LOW);toggle11;}}/* ISR(TIMER2_COMPA_vect){// timer2中断8kHz切换引脚9 //产生频率为8kHz / 2 4kHz的脉冲波 if(toggle2){ digitalWrite(9,HIGH); toggle2 0; } else{ digitalWrite(9,LOW); toggle2 1; } } *///loop functionvoidloop(){// your program here...}4.MsTimer2库的使用#includeMsTimer2.hintled8;voidonTimer(){digitalWrite(LED_BUILTIN,HIGH);delay(300);digitalWrite(LED_BUILTIN,LOW);delay(300);}voidsetup(){Serial.begin(9600);pinMode(led,OUTPUT);pinMode(LED_BUILTIN,OUTPUT);MsTimer2::set(1000,onTimer);//设置中断每1000ms进入一次中断服务程序 onTimer()MsTimer2::start();//开始计时_开启定时器中}voidloop(){digitalWrite(led,HIGH);delay(1000);digitalWrite(led,LOW);delay(1000);}5.TimerOne的使用#includeTimerOne.h# 使用 timer1 产生自定义载波频率下不同 pwm 占空比输出 和 定时器中断。#includeTimerOne.hvoidsetup(){pinMode(10,OUTPUT);Timer1.initialize(500000);// initialize timer1, and set a 1/2 second periodTimer1.pwm(9,512);// setup pwm on pin 9, 50% duty cycleTimer1.attachInterrupt(callback);// attaches callback() as a timer overflow interrupt}voidcallback(){digitalWrite(10,!digitalRead(10));// 状态翻转}voidloop(){// your program here...}6.Mega 2560板的time3#defineledPin13voidsetup(){pinMode(ledPin,OUTPUT);// initialize timer1noInterrupts();// disable all interruptsTCCR3A0;TCCR3B0;TCNT30;OCR3A31250;// compare match register 16MHz/256/2HzTCCR3B|(1WGM32);// CTC modeTCCR3B|(1CS32);// 256 prescalerTIMSK3|(1OCIE3A);// enable timer compare interruptinterrupts();// enable all interrupts}ISR(TIMER3_COMPA_vect)// timer compare interrupt service routine{digitalWrite(ledPin,digitalRead(ledPin)^1);// toggle LED pin}voidloop(){// your program here…}7.Mega 2560板的time4#defineledPin13voidsetup(){pinMode(ledPin,OUTPUT);// initialize timer1noInterrupts();// disable all interruptsTCCR4A0;TCCR4B0;TCNT40;OCR4A31250;// compare match register 16MHz/256/2HzTCCR4B|(1WGM42);// CTC modeTCCR4B|(1CS42);// 256 prescalerTIMSK4|(1OCIE4A);// enable timer compare interruptinterrupts();// enable all interrupts}ISR(TIMER4_COMPA_vect)// timer compare interrupt service routine{digitalWrite(ledPin,digitalRead(ledPin)^1);// toggle LED pin}voidloop(){// your program here…}8.Mega 2560板的time5#defineledPin13voidsetup(){pinMode(ledPin,OUTPUT);// initialize timer1noInterrupts();// disable all interruptsTCCR5A0;TCCR5B0;TCNT50;OCR5A31250;// compare match register 16MHz/256/2HzTCCR5B|(1WGM52);// CTC modeTCCR5B|(1CS52);// 256 prescalerTIMSK5|(1OCIE5A);// enable timer compare interruptinterrupts();// enable all interrupts}ISR(TIMER5_COMPA_vect)// timer compare interrupt service routine{digitalWrite(ledPin,digitalRead(ledPin)^1);// toggle LED pin}voidloop(){// your program here…}