本文章是作者个人记录所用,包含网上一些转载的知识点,秉着自用原则,方便自己日后用到类似的模块可以直接复习上手
1、超声波模块
//=============================================
// 超声波
//============================================
for(i = 0; i < 10; i++)//发送信号并获取距离
{
gpio_set(B2,1);//发射引脚
systick_delay_us(20) ;//产生一个20us以上的高电平信号
gpio_set(B2,0);
while(gpio_get(D14)== 0 && (--status) );
//发成功后回波引脚会变成低电平 status是测试所用,怕卡死在这里
systick_start();//发射成功开启计时
while(gpio_get(D14) == 1);//回波引脚接收到信号
distance[i] = systick_getval(); //获取时间
}
for(j = 0; j < 10; j ++)//排序 滤波
{
for(i = j+1; i < 10; i ++)
{
if(distance[i] > distance[j])
{
temp = distance[j];
distance[j] = distance[i];
distance[i] = temp;
}
}
}
Real_distance = 0;
for(i = 1; i<9; i++)//输出
{
Real_distance += (distance[i]>>3);
}
if(Real_distance < 30000)//根据需求修改触发条件//150cm对应三万左右
flag_open = 1;
以上代码编辑于2021-5-13
当时用着用点问题,但是因为没时间就没有去解决,凑合用着了。
当时的问题主要是超声波精度还有数据范围很奇怪。对照着逐飞科技的超声波代码源码,发现了几点问题。现更新代码,该代码基本准确无误。
gpio_set(TRIG_PIN,1);//发射引脚
systick_delay_us(10) ;//产生一个10us以上的高电平信号
gpio_set(TRIG_PIN,0);
//while(gpio_get(ECHO_PIN)== 0 );
//发成功后回波引脚会变成低电平 status是测试所用,怕卡死在这里
while(!gpio_get(ECHO_PIN) ); //检测到接收引脚为高电平则开始计时
//systick_start();//发射成功开启计时
pit_start(PIT_CH0);
wait_time = 0;
while(gpio_get(ECHO_PIN)) //检测到接收引脚为低电平则结束计时
{
wait_time++; //超时检测
systick_delay(5);
if(wait_time>20000000) break; //超过等待时间
}
if(wait_time<200000)
//distance_time = systick_getval(); //获取时间
distance_time = pit_get_us(PIT_CH0); //获取定时的时间
else distance_time = 200000;
//while(gpio_get(ECHO_PIN) == 1);//回波引脚接收到信号
//distance_time = systick_getval(); //获取时间
//distance_time = pit_get_us(PIT_CH0);
pit_close(PIT_CH0);
distance = distance_time*340/2/1000; //计算距离 单位毫米
systick_delay_ms(5); //需要定时2Ms以上
反思问题应该有1、定时器的选取,应该用周期定时器会更加的准确。2、在每次读完回波之后先延时个几毫秒再发送下一次光波信号,不然发送引脚发送之后回波引脚不会置位。3、防止超声波距离过远的超时应该加在等待回波引脚收到信号的期间。