目录
一、HC-SR04超声波模块原理和硬件接线
1.1 超声波测距原理:
1.2 超声波时序图:
1.3 HC-SR04超声波模块硬件接线:
二、时间函数
2.1 时间函数gettimeofday()原型和头文件:
2.2 使用gettimeofday()函数获取当前时间的秒数和微妙数:
2.3 使用gettimeofday()函数计算全志H616数10万次的耗时:
三、实现超声波测距
3.1 使用wiringOP库和时间函数实现超声波测距:
3.2 实现超声波测距(距离小于10cm时蜂鸣器发出警报):
一、HC-SR04超声波模块原理和硬件接线
1.1 超声波测距原理:
-
让它发送波:给Trig端口至少10us的高电平
-
开始发送波:Echo信号由低电平跳转到高电平
-
接收返回波:Echo信号由高电平跳转回低电平
-
计算时间 :Echo引脚维持高电平的时间!
-
开始发送波,启动定时器,接收到返回波,停止计时器
-
计算距离 :测试距离=(高电平时间*声速(340m/s))/2
1.2 超声波时序图:
1.3 HC-SR04超声波模块硬件接线:
-
超声波的VCC接到板子上的5V
-
超声波的GND接到板子上的GND
-
超声波的Trig口对应的物理引脚的3号,其对应的wPi的第0号
-
超声波的Echo口对应的物理引脚的5号,其对应的wPi的第1号
二、时间函数
2.1 时间函数gettimeofday()原型和头文件:
#include <sys/time.h>int gettimeofday(struct timeval *tv, struct timezone *tz);int 函数返回值,如果成功,gettimeofday 返回 0。如果失败,它返回 -1 并设置 errno 以指示错误。struct timeval *tv 这是一个指向 timeval 结构体的指针,该结构体用于存储当前时间。timeval 的定义如下:struct timeval { time_t tv_sec; /* 秒 */ suseconds_t tv_usec; /* 微秒 */
};time_t tv_sec 是一个整数,表示自 Unix 纪元(1970年1月1日 00:00:00 UTC)以来的秒数。
suseconds_t tv_usec 是一个整数,表示微秒数(0 到 999,999)。struct timezone *tz 这是一个指向 timezone 结构体的指针,用于存储时区信息。但在现代系统中,这个参数通常被忽略,因为大多 数系统都使用 UTC 时间,并且不再使用本地时区偏移。这个参数我们通常设置为NULL/*函数说明:
gettimeofday 是一个 Unix 和 Linux 系统调用,用于获取当前的时间(包括秒和微秒)和时区信息(尽管时区信息在大多数现代系统中可能不太常用)
*/
2.2 使用gettimeofday()函数获取当前时间的秒数和微妙数:
#include <stdio.h>
#include <sys/time.h>int main()
{struct timeval tv;//int gettimeofday(struct timeval *tv, struct timezone *tz);if(gettimeofday( &tv, NULL) == 0){ //获取当前时间的秒数和微妙数printf("自1970-01-01 00:00:00的秒数:%ld\n",tv.tv_sec);printf("微妙:%ld\n",tv.tv_usec);}else{perror("gettimeofday"); //打印出错信息}return 0;
}
2.3 使用gettimeofday()函数计算全志H616数10万次的耗时:
#include <stdio.h>
#include <sys/time.h>void cntTest() //全志H616数数十万次
{int i;int j;for(i=0; i<100; i++)for(j=0; j<1000; j++);
}int main()
{struct timeval timeStart; struct timeval timeStop;long diffTime;//int gettimeofday(struct timeval *tv, struct timezone *tz);gettimeofday( &timeStart, NULL); //获取数数之前的时间cntTest(); //数数十万次gettimeofday( &timeStop, NULL); //获取数数之后的时间//秒之所以要乘以1000000是因为后面加了微妙,所以要将秒转化为微秒 //获取数数十万次的时间diffTime = 1000000 * (timeStop.tv_sec - timeStart.tv_sec) + (timeStop.tv_usec - timeStart.tv_usec); printf("全志H616数10万次耗时:%ldus\n",diffTime);return 0;
}
三、实现超声波测距
3.1 使用wiringOP库和时间函数实现超声波测距:
#include <stdio.h> // 包含标准输入输出库头文件
#include <sys/time.h> // 包含时间相关函数的头文件
#include <wiringPi.h> // 包含wiringPi库的头文件,用于GPIO控制
#include <unistd.h> // 包含标准库函数,如sleep
#include <stdlib.h> // 包含标准库函数,如malloc和free#define Trig 0 // 定义Trig引脚为0
#define Echo 1 // 定义Echo引脚为1void startHC()
{digitalWrite(Trig, LOW); //给Trig端口发送低电平信号 usleep(5); digitalWrite(Trig, HIGH); //给Trig端口发送高电平信号 usleep(10); digitalWrite(Trig, LOW); //给Trig端口发送低电平信号
}double getDistance()
{double dis; //距离struct timeval Start; //开始时间 struct timeval Stop; //结束时间startHC(); //给Trig端口10us的高电平while(!digitalRead(Echo)); //Echo信号由低电平跳转到高电平gettimeofday(&Start, NULL); //获取时间while(digitalRead(Echo)); //Echo信号由高电平跳转回低电平gettimeofday(&Stop, NULL); //获取时间long diffTime = 1000000 * (Stop.tv_sec - Start.tv_sec) + (Stop.tv_usec - Start.tv_usec); //计算时间差 dis = (double)diffTime/1000000 * 34000 / 2; //计算距离 return dis;
}int main()
{double dis; //距离if(wiringPiSetup() == -1){ //初始化wiringPi库printf("初始化wiringPi库失败\n");exit(-1);} pinMode(Trig, OUTPUT); //设置超声波Trig引脚为输出模式pinMode(Echo, INPUT); //设置超声波Echo引脚为输入模式while(1){dis = getDistance(); //获取超声波距离printf("当前超声波距离是:%.2lf\n",dis);usleep(500000); //每500ms获取一次}return 0;
}
3.2 实现超声波测距(距离小于10cm时蜂鸣器发出警报):
#include <stdio.h> // 包含标准输入输出库头文件
#include <sys/time.h> // 包含时间相关函数的头文件
#include <wiringPi.h> // 包含wiringPi库的头文件,用于GPIO控制
#include <unistd.h> // 包含标准库函数,如sleep
#include <stdlib.h> // 包含标准库函数,如malloc和free#define Trig 0 // 定义Trig引脚为0
#define Echo 1 // 定义Echo引脚为1
#define Beep 2 // 定义Beep引脚为2void startHC()
{digitalWrite(Trig, LOW); //给Trig端口发送低电平信号 usleep(5); digitalWrite(Trig, HIGH); //给Trig端口发送高电平信号 usleep(10); digitalWrite(Trig, LOW); //给Trig端口发送低电平信号
}double getDistance()
{double dis; //距离struct timeval Start; //开始时间 struct timeval Stop; //结束时间startHC(); //给Trig端口10us的高电平while(!digitalRead(Echo)); //Echo信号由低电平跳转到高电平gettimeofday(&Start, NULL); //获取时间while(digitalRead(Echo)); //Echo信号由高电平跳转回低电平gettimeofday(&Stop, NULL); //获取时间long diffTime = 1000000 * (Stop.tv_sec - Start.tv_sec) + (Stop.tv_usec - Start.tv_usec); //计算时间差 dis = (double)diffTime/1000000 * 34000 / 2; //计算距离 return dis;
}int main()
{double dis; //距离if(wiringPiSetup() == -1){ //初始化wiringPi库printf("初始化wiringPi库失败\n");exit(-1);} pinMode(Trig, OUTPUT); //设置超声波Trig引脚为输出模式pinMode(Echo, INPUT); //设置超声波Echo引脚为输入模式pinMode(Beep, OUTPUT); //设置蜂鸣器Beep引脚为输出模式while(1){dis = getDistance(); //获取超声波距离printf("当前超声波距离是:%.2lf\n",dis);usleep(500000); //每500ms获取一次if(dis < 10){ //当距离小于10cm时,蜂鸣器发出警报){printf("警报!当前距离:%.2lf\n",dis);digitalWrite(Beep, LOW); //打开蜂鸣器usleep(500000); //延时500msdigitalWrite(Beep, HIGH); //关闭蜂鸣器}else{digitalWrite(Beep, HIGH); //关闭蜂鸣器} }return 0;
}