Arduino 外部中断重置内部定时器
文章目录
前言
- 本条博客的需求来源于自动驾驶中多传感器融合定位的硬件同步。
- 需要用GNSS
1Hz
的信号去重置lidar
(10Hz)和camera
(20Hz)的时钟。
一、准备工作
- 实验器材:Ardunio UNO开发板;信号发生器;多通道示波器。
- 需求:用1Hz方波的上升沿触发10Hz和20Hz的方波重置时钟。
- UNO开发板接口配置:
D2-----1Hz信号输入作为外部触发
D13----10Hz的方波输出
D7------20Hz的方波输出 - 代码思路:
- 首先用
MsTimer2
将设置timer2
为一个周期为25ms的时钟(25ms是20Hz方波的半个周期),然后用attachInterrupt
设置一个外部中断. - 当检测到上升沿
RISING
时外部中断被触发,进入到blink
函数中,首先停止timer2
,然后将两个输出引脚设置为高电平,并将下一轮的状态设置为低电平,然后使用MsTimer2::start()
函数重新打开之前设置的时钟。 - 时钟调用
flash
函数,其中每执行一次,对20Hz的方波输出口进行高低电平状态转换,每执行两次,对10Hz的方波输出口进行高低电平状态转换。
- 首先用
二、代码
#include <MsTimer2.h>
volatile boolean output1 = HIGH;
volatile boolean output2 = HIGH;
volatile int i=0;
void flash() {
digitalWrite(7, output1);
output1 = !output1;
if(i%2==1)
{
digitalWrite(13, output2); // 状态翻转
output2 = !output2;
}
i++;
}
void setup() {
pinMode(13, OUTPUT);
pinMode(7, OUTPUT);
MsTimer2::set(25, flash); // 50ms period
MsTimer2::start(); // enables the interrupt.
attachInterrupt(0, blink, RISING);//当int.0电平改变时,触发中断函数blink RISING
}
void loop() {
}
void blink()//中断函数
{
MsTimer2::stop();
digitalWrite(13, HIGH);
digitalWrite(7, HIGH);
output1 = LOW;
output2 = LOW;
i=0;
MsTimer2::start(); // enables the interrupt.
}
三、实验效果
1. 设置1Hz的方波(外部中断触发):
2. 观察示波器各个波形:
3. 延迟问题
看到20Hz的方波有3ms的延迟,这个我不太清楚问题出在哪里……
1.另,改用1.3hz方波进行外部中断触发
主要是为了避免和子波产生整数倍关系,更清晰明了地观察外部触发是否真正地重置了子波的时钟。
2. 观察示波器各个波形:
看到正在正常执行的子波,被外部中断
示波器上的黄线
触发后,立即转为高电平,并进入下一个时钟周期。但是这里的20hz方波存在3ms的延迟。
四、备注
-
Arduino UNO有三个定时器,
timer0:一个被Arduino的delay(), millis()和micros()使用的8位定时器 timer1:一个被Arduino的Servo()库使用的16位定时器 timer2:一个被Arduino的Tone()库使用的8位定时器
版权声明:本文为CSDN博主「chenyfan_」的原创文章,遵循CC 4.0
BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_19887221/article/details/124820081
- (1)如果你使用了 MsTimer2 库, 则
pin11
和pin3
就不能再用做 PWM 输出了! 因为该 pin3 和 pin11 的 PWM 是靠 timer2 帮忙的! (tone()也是)
(2)注意 Servo.h 库与 TimerOne 都是使用内部定时器 timer1 会影响pin9
,pin10
的 PWM
(3)tone() 使用 timer2 定时器; 若使用 Tone 库的 Tone 对象(Tone 变量)也是优先使用 timer2 定时器,若用两个 Tone 变量则 timer1 也会被用掉, 用三个 Tone 则连控制 millis( )的 timer0 也会被用掉。
(4)别忘了, timer0 负责帮忙控制pin 5
和pin 6
的 PWM 输出。只要不去改变 timer 的 Prescaler 就不会影响其控制的 PWM pin, 但MsTimer2 库与 tone( )都会改变 Prescaler ! !
版权声明:本文为CSDN博主「chenyfan_」的原创文章,遵循CC 4.0
BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_19887221/article/details/124820081
- 参考链接:Arduino教程——外部中断的使用
- 一些可能有用的博客:
Arduino基础篇(八)-- Arduino如何实现多线程(SCoop)
Arduino基础篇(二)-- 常用的基本函数
详解Arduino Uno开发板的引脚分配图及定义(重要且基础)
Arduino教程——外部中断的使用 讲解很形象
Arduino延迟函数delay(),以及为什么不应该使用它
总结
本文主要用了外部中断来重置内部定时器。
疑问:
-
但这里涉及到中断优先级的问题,具体是定时器中断优先还是外部中断优先?本文并没有细究。
我个人认为:
- 如果外部触发的时候没有进入定时器中断的话,那是没有问题的。
- 如果外部触发的时候程序已经进入了定时器中断,定时器中断就要更换输出口的高低电平位。如果程序出了定时器中断而没有进入外部中断的话,会导致该次外部触发无效;如果出了定时器中断后进入外部中断,则该次外部触发有效,但存在几行程序的延迟时间。
-一些拙见,不具有实际参考价值。
-
另外20Hz信号为什么存在3ms的延迟,经实验验证得出结论是示波器不同通道扫描时间的问题。
致谢
向开源致敬,向各位博主致敬!