极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 16636|回复: 3

想实现pulseIn功能,又不想等待,解决方案是millis和micros(测速新方法!)

[复制链接]
发表于 2016-3-22 16:21:58 | 显示全部楼层 |阅读模式
本帖最后由 加米 于 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只有两个中断引脚)


附上自己的调试图一张:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

 楼主| 发表于 2016-3-22 16:28:16 | 显示全部楼层
自己顶一下
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-3-22 16:31:27 | 显示全部楼层
板凳也自己占了
回复 支持 反对

使用道具 举报

发表于 2016-4-25 00:00:52 | 显示全部楼层
超声波的可以用这个吗?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-15 17:28 , Processed in 0.053410 second(s), 20 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表