目录
一、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引脚为1
void 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引脚为2
void 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); //延时500ms
digitalWrite(Beep, HIGH); //关闭蜂鸣器
}else{
digitalWrite(Beep, HIGH); //关闭蜂鸣器
}
}
return 0;
}