本帖最后由 加米 于 2016-3-22 17:41 编辑
分析了一下Super169的帖子,结合自己的理解,觉得pulseIn函数还是有一定缺陷的,嗯,没错!
http://www.geek-workshop.com/thread-11138-1-1.html
unsigned long (uint8_t pin, uint8_t state, unsigned long timeout);pulseIn函数返回值类型为无符号长整型(unsigned long),3个参数分别表示脉冲输入的引脚、脉冲响应的状态(高脉冲或低脉冲)和超时时间。这样的缺陷在于,如果状态一开始就是HIGH/LOW,那就会一直触发等待,而且如果状态一直保持,那只能通过Super169的方法通过多次测量取最大值了。
所以总结起来pulseIn有以下缺陷:
1、需要等待时间
对于程序执行效率而言,等待意味着白白损耗了CPU时间,导致效率低下,而且pulseIn的默认等待时间是1s(如果没记错的话)。
对于高频信号,如果不想过多等待,得把 timeout 改小一点,改太小又不行;
对于低频信号(比如10s才电平转换一次),那只能等了,但是,10s可以做很多事情了。
2、需要对齐电平转换的位置,或者多次测量取max。
具体分析,Super169已经说得很明白了。
http://www.geek-workshop.com/for ... page%3D1&page=1
解决方法:
对于需要等待时间的解决方法是使用中断,或者类中断(定时器中断)。
对于需要对齐电平转换的解决方法是,使用上升沿/下降沿触发计时/结束。
具体看代码:
[pre lang="arduino" line="1" file="test"] unsigned long duration = 0;//duration 就是要测量的IO口电平转换时间了
void setup()
{
attachInterrupt(0,FLASH,RISING);//0号外部中断.上升沿触发,FLASH为中断服务程序
}
void loop()
{
duration = 0;//重新幅值
/*你想做的一大堆事^v^*/
/*此处省略一万行代码...*/
}
void FLASH()
{
static unsigned long OldTime = 0;
duration = micros() - OldTime;
OldTime = micros();
}[/code]
使用这种方法的不足是,检测引脚只能是外部中断引脚,但好处也是显而易见的,如果还有什么好方法别忘了告诉我哦
如果不需要us的时间精度可以将void FLASH()中的micros换成精度为ms的millis就可以了。
另外,这种方法也可以用来测试哦,不过前提是你只有两个轮子的话(普通arduino只有两个中断引脚)
附上自己的调试图一张:
|