树莓派 WiringPi 超声波

原文地址:https://blog.csdn.net/qq_25247589/article/details/62892140


首先一定要好好看看引脚图

[html]  view plain  copy
  1. +-----+-----+---------+------+---+---Pi 3---+---+------+---------+-----+-----+    
  2. | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |    
  3. +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+    
  4. |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |    
  5. |   2 |   8 |   SDA.1 | ALT0 | 1 |  3 || 4  |   |      | 5V      |     |     |    
  6. |   3 |   9 |   SCL.1 | ALT0 | 1 |  5 || 6  |   |      | 0v      |     |     |    
  7. |   4 |   7 | GPIO. 7 |   IN | 1 |  7 || 8  | 1 | ALT5 | TxD     | 15  | 14  |    
  8. |     |     |      0v |      |   |  9 || 10 | 1 | ALT5 | RxD     | 16  | 15  |    
  9. |  17 |   0 | GPIO. 0 |  OUT | 0 | 11 || 12 | 0 | IN   | GPIO. 1 | 1   | 18  |    
  10. |  27 |   2 | GPIO. 2 |   IN | 0 | 13 || 14 |   |      | 0v      |     |     |    
  11. |  22 |   3 | GPIO. 3 |   IN | 0 | 15 || 16 | 0 | IN   | GPIO. 4 | 4   | 23  |    
  12. |     |     |    3.3v |      |   | 17 || 18 | 0 | IN   | GPIO. 5 | 5   | 24  |    
  13. |  10 |  12 |    MOSI | ALT0 | 0 | 19 || 20 |   |      | 0v      |     |     |    
  14. |   9 |  13 |    MISO | ALT0 | 0 | 21 || 22 | 0 | IN   | GPIO. 6 | 6   | 25  |    
  15. |  11 |  14 |    SCLK | ALT0 | 0 | 23 || 24 | 1 | OUT  | CE0     | 10  | 8   |    
  16. |     |     |      0v |      |   | 25 || 26 | 1 | OUT  | CE1     | 11  | 7   |    
  17. |   0 |  30 |   SDA.0 |   IN | 1 | 27 || 28 | 1 | IN   | SCL.0   | 31  | 1   |    
  18. |   5 |  21 | GPIO.21 |   IN | 1 | 29 || 30 |   |      | 0v      |     |     |    
  19. |   6 |  22 | GPIO.22 |   IN | 1 | 31 || 32 | 0 | IN   | GPIO.26 | 26  | 12  |    
  20. |  13 |  23 | GPIO.23 |   IN | 0 | 33 || 34 |   |      | 0v      |     |     |    
  21. |  19 |  24 | GPIO.24 |   IN | 0 | 35 || 36 | 0 | IN   | GPIO.27 | 27  | 16  |    
  22. |  26 |  25 | GPIO.25 |   IN | 0 | 37 || 38 | 0 | IN   | GPIO.28 | 28  | 20  |    
  23. |     |     |      0v |      |   | 39 || 40 | 0 | IN   | GPIO.29 | 29  | 21  |    
  24. +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+    
  25. | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |    
  26. +-----+-----+---------+------+---+---Pi 3---+---+------+---------+-----+-----+  
因为用的是wpi的c函数库 所以一定要看仔细了 有可能造成树莓派损坏 

这次用的是超声波测距模块(昨天焊接小灯泡的时候不小心把led点断了 没得用了 远离焊接 珍爱生命)

首先接好管脚 先来看看这个模块 某宝上几块钱一个 


总之四个脚 上下两个是5V和接地的 第二个是输出管脚 就是你给一个高电平就发送一段声波 第三个是接收端

接下来是代码部分 和上次的编译是一样的

[html]  view plain  copy
  1. #include <wiringPi.h>    
  2. #include <stdio.h>    
  3. #include <sys/time.h>    
  4. #define Trig    4    
  5. #define Echo    5    
  6.     
  7. void ultraInit(void)    
  8. {    
  9.     pinMode(Echo, INPUT);  //设置端口为输入  
  10.     pinMode(Trig, OUTPUT);  //设置端口为输出  
  11. }    
  12.     
  13. float disMeasure(void)    
  14. {    
  15.     struct timeval tv1;  //timeval是time.h中的预定义结构体 其中包含两个一个是秒,一个是微秒  
  16.     /*  
  17.     struct timeval  
  18.     {  
  19.         time_t tv_sec;  //Seconds.   
  20.         suseconds_t tv_usec;  //Microseconds.   
  21.     };  
  22.     */  
  23.       
  24.     struct timeval tv2;    
  25.     long start, stop;    
  26.     float dis;    
  27.     
  28.     digitalWrite(Trig, LOW);    
  29.     delayMicroseconds(2);    
  30.     
  31.     digitalWrite(Trig, HIGH);    
  32.     delayMicroseconds(10);      //发出超声波脉冲    
  33.     digitalWrite(Trig, LOW);    
  34.         
  35.     while(!(digitalRead(Echo) == 1));    
  36.     gettimeofday(&tv1, NULL);           //获取当前时间 开始接收到返回信号的时候   
  37.     
  38.     while(!(digitalRead(Echo) == 0));    
  39.     gettimeofday(&tv2, NULL);           //获取当前时间  最后接收到返回信号的时候  
  40.     /*  
  41.     int gettimeofday(struct timeval *tv, struct timezone *tz);  
  42.     The functions gettimeofday() and settimeofday() can get and set the time as well as a timezone.   
  43.     The use of the timezone structure is obsolete; the tz argument should normally be specified as NULL.  
  44.     */  
  45.     start = tv1.tv_sec * 1000000 + tv1.tv_usec;   //微秒级的时间    
  46.     stop  = tv2.tv_sec * 1000000 + tv2.tv_usec;    
  47.     
  48.     dis = (float)(stop - start) / 1000000 * 34000 / 2;  //计算时间差求出距离    
  49.     
  50.     return dis;    
  51. }    
  52.     
  53. int main(void)    
  54. {    
  55.     float dis;    
  56.     
  57.     if(wiringPiSetup() == -1){ //如果初始化失败,就输出错误信息 程序初始化时务必进行  
  58.         printf("setup wiringPi failed !");    
  59.         return 1;     
  60.     }    
  61.     
  62.     ultraInit();    
  63.         
  64.     while(1){    
  65.         dis = disMeasure();    
  66.         printf("distance = %0.2f cm\n",dis);    
  67.         delay(1000);    
  68.     }    
  69.     
  70.     return 0;    
  71. }    


扫描二维码关注公众号,回复: 28075 查看本文章
运行结果如下


还是挺精确的



PS:以上代码借鉴了csdn上一个前辈的

关于wiringPi的函数库

官方的在这里https://projects.drogon.net/raspberry-pi/wiringpi/functions/

点击打开链接

还有一个前辈翻译了一部分的

[html]  view plain  copy
  1. API函数英文网页    :https://projects.drogon.net/raspberry-pi/wiringpi/functions/  
  2. BCM2835芯片手册 :https://github.com/raspberrypi/documentation/blob/master/hardware/raspberrypi/bcm2835  
  3. wiringPi库下载地址 : https://git.drogon.net/?p=wiringPi;a=summary  
  4. wiringPi库Git地址   : git://git.drogon.net/wiringPi  
  5.   
  6. 在使用wiringPi库之前,你需要包含头文件:  
  7. #include <wiringPi.h>  
  8. 依赖你正在使用的系统环境你需要增加 -I/usr/local/include -L/usr/local/lib -lwiringPi 在使用命令行的时候编译你的程序,最重要的是-lwiringPi。  
  9.   
  10. 设置函数(Setup Functions)  
  11.   
  12. 这里有3中方式来初始化wiringPi。  
  13. int wiringPiSetup (void) ;  
  14. int wiringPiSetupGpio (void) ;  
  15. int wiringPiSetupSys (void) ;  
  16. 在你程序开始的时候必须调用其中一个设置函数,如果返回-1则初始化GPIO失败,然后你应该查阅全局错误代码去看为什么会失败。  
  17. 下面是几个设置函数的区别:  
  18.   
  19. wiringPiSetup(void) ;  
  20. 这个设置函数初始化wiringPi系统,假定当前程序将要使用wiringPi引脚编号方案,这是一个简单的编号方案,它提供了将虚拟引脚编号0~16映射到实际的Broadcom GPIO引脚编号。查看pins page图表来了解wiringPi引脚编号、Broadcom GPIO引脚编号和树莓派板子的边缘连接器物理位置的映射情况。  
  21. 这个函数需要root权限才能调用。  
  22.   
  23. wiringPiSetupGpio(void) ;  
  24. 这个函数与上面那个函数相同,然而它允许当前程序不重新映射直接地使用Broadcom GPIO引脚编号。  
  25. 和上面一样,这个函数也需要root权限才能调用。  
  26.   
  27.   
  28. wiringPiSetupSys(void)  
  29. 这个函数初始化wiringPi系统,但是它用的是/sys/class/gpio接口而不是直接的访问硬件。它可以被非root用户调用,提供的GPIO引脚必须在事先使用gpio命令导出。在这种模式下的引脚编号是原生的Broadcom GPIO引脚编号。  
  30.   
  31. 注意:在这种模式下你仅仅能够使用通过/sys/class/gpio接口导出的引脚。在你调用你的程序之前你必须导出这些引脚。  
  32. 你可以通过一个单独的shell脚本来做这件事,或者在你的程序中使用system()函数。  
  33.   
  34. 还需要注意的是一些函数(下面列出的)在使用这种模式的时候是无效的,它们可能不能在非root权限的情况下进行操作。  
  35.   
  36.   
  37.   
  38. 一般wiring函数(General wiring functions)  
  39.   
  40. void pinMode (int pin, int mode) ;  
  41. 这个函数设置引脚的模式为INPUT、OUTPUT或者PWM_OUTPUT.注意仅仅wiringPi引脚1(BCM_GPIO 18)支持PWM输出,  
  42. 引脚的编号可以从pins table中获得。  
  43. 这个函数在系统模式( Sys mode)下无效。  
  44.   
  45.   
  46. void digitalWrite (int pin, int value) ;  
  47. 向给出的引脚写HIGH或者LOW(1 or 0)值,并确保该引脚在之前已经被设置成输出模式。  
  48.   
  49.   
  50. void digitalWriteByte (int value) ;  
  51. 这个函数写8位字节到8个GPIO引脚,最快的方式是马上设置所有8位字节成一个特定的值,尽管它仍然需要对GPIO硬件进行了两次写操作。  
  52.   
  53.   
  54. void pwmWrite (int pin, int value) ;  
  55. 向给出引脚的PWM寄存器写value值,value的值必须在0~1024之间。(再次注意,仅仅pin1(BCM_GPIO18)支持PWM)  
  56. 这个函数在系统模式( Sys mode)下无效。  
  57.   
  58.   
  59. int digitalRead (int pin) ;  
  60. 这个函数返回读取pin引脚所获得的值,这个值将会是HIGH或者LOW(1 or 0)取决于改pin的逻辑电平。  
  61.   
  62.   
  63. void pullUpDnControl (int pin, int pud) ;  
  64. 这个函数将给出的引脚设置成上拉或者下拉电阻模式,引脚必须设置成输入模式。和Arduino不同,BCM2835  
  65. 同时有用上拉和下拉内部电阻器。pud参数应该是;PUD_OFF(没有上拉或下拉),PUD_DOWN(下拉),PUD_UP(上拉到3.3V)。  
  66.   
  67. 这个函数在Sys模式下无效,如果你需要启动一个上拉或者下拉,你可以在你开始运行程序前在一个脚本中使用gpio命令来完成。  
  68.   
  69.   
  70. PWM控制(PWM Control)  
  71.   
  72. 当系统运行在Sys模式下的时候PWM不能被控制。  
  73.   
  74. pwmSetMode (int mode) ;  
  75. PWM发生器可以以两种模式工作-"平稳模式"和"mark:space"。mark:space模式时传统的,然而  
  76. PI的默认模式时平稳模式。你可以通过提供 PWM_MODE_BAL 或者 PWM_MODE_MS 参数来切换模式。  
  77.   
  78.   
  79. pwmSetRange (unsigned int range) ;  
  80. 这个函数设置了PWM发生器的寄存器的范围,默认是1024。  
  81.   
  82.   
  83. pwmSetClock (int divisor) ;  
  84. 这个函数用于设置PWM时钟的分频数。  
  85.   
  86. 你需要阅读Broadcom ARM 外设数据手册来了解更多关于PWM系统的信息。  
  87.   
  88.   
  89. 定时函数(Timing functions)  
  90.   
  91. unsigned int millis (void)  
  92. 这个函数返回一个数据,这个数据代表了从你的程序调用wiringPiSetup函数开始到当前所经历的毫秒数,它返回一个32位无符号数which wraps after 49 days。  
  93.   
  94.   
  95. void delay (unsigned int howLong)  
  96. 这个函数会导致程序执行暂停至少howLong毫秒,由于linux多任务的特性可能会更长。注意最大的延时时间是一个32位无符号整数或者大约为49天。  
  97.   
  98.   
  99. void delayMicroseconds (unsigned int howLong)  
  100. 这个函数会导致程序执行暂停至少howLong微秒,由于linux多任务的特性可能会更长。注意最大的延时时间是一个32位无符号整数微秒或者大约为71分钟。  
  101.   
  102.   
  103.   
  104. 程序/线程优先级(Program/Thread Priority)  
  105.   
  106. int piHiPri (int priority) ;  
  107.   
  108. 中断(Interrupts)  
  109.   
  110. 拥有一个更新了GPIO中断处理代码补丁的内核(也就是在2012年7月以后的内核),你现在就可以在你的程序  
  111. 中等待中断的发生。这个功能在你等待中断发生的时候释放处理器去做其它任务。GPIO口可以产生的中断输入信号  
  112. 有上升沿、下降沿或者两者都有。  
  113. 注意:2013年1月:waitForInterrupt()函数已经被弃用了,你应该使用下面这个更新更简单的wiringPiISR() 函数。  
  114.   
  115. int waitForInterrupt (int pin, int timeOut) ;  
  116. 当被调用的时候,你的程序会被挂起来等待该引脚有中断事件的发生。 timeOut 参数给入的是毫秒值,或者可以设置成-1当需要永久的等待的时候。  
  117. 返回值是-1意味着发生了错误(errno会相应的被设置),是0如果超时,是1代表了成功检测到了的一个中断事件。  
  118.   
  119. 在调用waitForInterrupt之前,你首先必须初始化GPIO引脚,目前唯一能够做这件事的方式是使用gpio命令,也可以在一个脚本中,或者在你的程序中使用system()。  
  120. 举例来说我们想要在GPIO引脚0上等待一个下降沿中断,因此要设置硬件,我们需要运行:  
  121.         gpio edge 0 falling  
  122. 在运行程序之前。  
  123.   
  124. int wiringPiISR (int pin, int edgeType,  void (*function)(void)) ;  
  125. 这个函数在特殊的引脚上注册一个函数来接收中断,edgeType参数是INT_EDGE_FALLING、INT_EDGE_RISING,INT_EDGE_BOTH or INT_EDGE_SETUP中的一个。如果它是INT_EDGE_SETUP,则不会有初始化引脚的操作发生-它假定你已经在别处设置了引(例如 使用gpio命令),但是如果你指定了其它类型中的一种,然后这个引脚就会按照规定被导出和初始化。它通过合适的调用gpio通用命令来实现,因此它应该被使用。  
  126.   
  127. 引脚编号由当前的模式提供-native wiringPi, BCM_GPIO or Sys 模式。  
  128.   
  129. 这个函数(wiringPiISR )可以在任何模式下工作,没必要获取root权限来工作。  
  130.   
  131. 当中断触发的时候function函数就会被调用,当它已经被触发了,在调用function函数之前它会在调度程序中被清除,因此如果在你处理完成(这次中断)之前一个后续的中断发生,然后它(后续的中断)不会被丢失。(不管怎样,它仅仅能够监测再多一个中断,它们(中断)会被忽略如果在一个中断正在被处理的时候又有不只一个中断发生)。  
  132.   
  133. 这个函数可以在高优先级别下运行(如果程序使用sudo运行或者在root权限下),与主程序同时执行。它能够完全访问所有的全局变量,打开文件句柄等等。  
  134.   
  135. 通过查看 isr.c例程来了解更多详细的内容和怎么去使用这些特性。  
  136.   
  137.   
  138. 并行处理(Concurrent Processing (multi-threading))  
  139.   
  140. int piThreadCreate (name) ;  
  141. piLock (int keyNum) ;  
  142. piUnlock (int keyNum) ;  
  143. 混杂函数(Misc. Functions)  
  144.   
  145. piBoardRev (void) ;  
  146.   
  147. wpiPinToGpio (int wPiPin) ;  
  148. setPadDrive (int group, int value) ;  
  149.   
  150. -----------------------------------------------------------------------------------------------------------------  
  151. 本文属于本人原创文章,转载请注明出处:http://blog.csdn.net/a656343072/article/details/41209857  
  152. 本人英文水平有限,欢迎指正错误。  
  153. --huangzhigang  
  154. -----------------------------------------------------------------------------------------------------------------  

猜你喜欢

转载自blog.csdn.net/Anton8801/article/details/79971550