基于STM32F103HAL库的声音定位系统

这篇具有很好参考价值的文章主要介绍了基于STM32F103HAL库的声音定位系统。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

stm32声源定位,32单片机,stm32,单片机,arm
这是一道学校出的电赛题目,要求在100*100cm的平面上实现定位实现声音定位。由于一米太大了,我们就做了40cm的,下面的讲解我按照40厘米的写。用到的处理器是stm32f103c8t6接下来分享一下调试心得。
硬件部分需要制作发声装置和接收装置,详细可以参考这个文章.
需要知道的是,扬声器发出的声音经过接收装置,得到的是一个方波信号,所以单片机需要根据这些方波求出距离

解题思路

一.直线

既然我们说,接收模块得到的是方波信号,那么单片机肯定可以检测到方波的下降沿和上升沿,在直线上,声源距离接收模块越近,声音先到达,就先接收到下降沿,相反,声源距离接收模块远,就后接受到下降沿,这样我们可以得到时间差。接下来就是小学数学了(手动狗头),根据两个时间可以算出距离。stm32声源定位,32单片机,stm32,单片机,arm
用C语言描述就是这样

传入参数:两个下降沿分别到两个接收器之间的时间差
传出参数:距离
float Find_Line(float ltime)
{
	float S=0,timeall=0,timefst=0;
	timeall=0.0012;        //单位是秒,根据ltime单位做调整     0.4/346
	timefst=(timeall+ltime)/2;
	S=0.4*(timefst/timeall);
	
	return S;
}

二.平面

在平面上,就需要三个接收模块,这样就能得出两个时间差。
像下面这幅图
stm32声源定位,32单片机,stm32,单片机,arm

用C语言描述是这样,得到的arv1和arv2就是坐标值,
整个函数就是解方程的思路,用穷举法求出合适的值,我在后面又对得到的值做了求平均处理。

//传入参数:两个时间差
void Find_Square(float ctime1,float ctime2)
{
	int count,i=0;

   for(x=0.0; x<=40.0; x++)
    {
        for(y=0.0; y<=40.0;y++)
        {
            if(fabs(sqrt(x*x+(y-40)*(y-40))-sqrt(x*x +y*y)-34000*ctime1)<3 && fabs(sqrt(x*x +y*y)-sqrt((40-x)*(40-x)+y*y)-34000*ctime2)<3)  
             {  
                    a[i]=x;
                    b[i]=y;
                    i++;
                    count =i;
                printf("x=%.2f  y=%.2f count=%d\n",x,y,count);
             }  
            else{printf("方程无解");}
        }
    }
//		count=Del_Zero(a,count);
//		Del_Zero(b,count);
        for(int i=0; i< count; i++)
        {
            sum1=sum1+a[i];
            sum2=sum2+b[i];
            arv1=sum1/count;
            arv2=sum2/count;
						
             printf("a[i]=%.2f  b[i]=%.2f count=%d  %f\n",a[i],b[i],count,sum1);
        }
        printf("arv1=%.2f arv2=%.2f\n",arv1,arv2);
				sum1=0;sum2=0;
}

二.单片机获取时间

其实解题思路不难,难点就在于获取到准确的时间,我使用的获取方法是外部中断,当单片机的一个IO口检测到下降沿,定时器开始计时,另一个IO口检测到下降沿停止计时,这样就得到时间差

1.cubemx配置

1.外部中断
stm32声源定位,32单片机,stm32,单片机,arm
stm32声源定位,32单片机,stm32,单片机,arm
2.定时器
由于晶振是72MHZ,而且接收到下降沿的时间在微秒级别,所以将单位时间设置为100us(72000000/72/100=10000hz)(1/10000=100us)
stm32声源定位,32单片机,stm32,单片机,arm

/**
  * 函数功能: 按键外部中断回调函数
  * 输入参数: GPIO_Pin:中断引脚
  * 返 回 值: 无
  * 说    明: 无
  */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	
  if(GPIO_Pin==GPIO_PIN_0)//A
  {
		if(time1==0)
		{
			wosignA=0;
			HAL_TIM_Base_Start_IT(&htim2); //使能刚刚配置的定时器
		}
		else
		{
			wosignA=time1+255*time2;
			//HAL_TIM_Base_Stop_IT(&htim2);
		}
				signA=1; 
	}
		 if(GPIO_Pin==GPIO_PIN_1)//B
		{
			if(time1==0)
			{
				wosignB=0;
				HAL_TIM_Base_Start_IT(&htim2); //使能刚刚配置的定时器
			}
			else
			{
				wosignB=time1+255*time2;
				//HAL_TIM_Base_Stop_IT(&htim2);
			}
			signB=1;
			//EXTI->IMR &= ~(GPIO_PIN_1); 
		}
		 if(GPIO_Pin==GPIO_PIN_11)//B
		{
			if(time1==0)
			{
				wosignC=0;
				HAL_TIM_Base_Start_IT(&htim2); //使能刚刚配置的定时器
			}
			else
			{
				wosignC=time1+255*time2;
				//HAL_TIM_Base_Stop_IT(&htim2); //使能刚刚配置的定时器
			}
			signC=1;
			//EXTI->IMR &= ~(GPIO_PIN_1); 
		}

}
/**
  * 函数功能: 定时器中断回调函数
  * 输入参数: 
  * 返 回 值: 无
  * 说    明: 无
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{

		 if (htim->Instance == htim2.Instance)
		 {

					time1++;	 
					if(time1==255){time2++;time1=0;}//定时器计数255次溢出一次
		 }
		 if (htim->Instance == htim1.Instance)
		 {

		 }
}
		key=read_key();
		if(key==1) {mode=1;OLED_Clear();}
		if(key==2) {mode=2;OLED_Clear();}
		if(key==3) {mode=3;OLED_Clear();}
		if(mode==1)
		{
				if(signA&&signB)
			{
				EXTI->IMR &= ~(GPIO_PIN_0);//关闭外部中断
				EXTI->IMR &= ~(GPIO_PIN_1);
				HAL_TIM_Base_Stop_IT(&htim2);
				if(wosignA<wosignB){t1=wosignB;}
				else	{t1=wosignA;}
				if(t1>11){t1=11;}
				s=Find_Line(fabs((float)(t1))*100/1000000);
				printf("%d   %d    %f   %d   %d  %d %d\n",time1,time2,s,wosignA,wosignB,wosignC,t1);
				OLED_ShowFloat(0,0,s,2,4,16);
				HAL_Delay(100);
				EXTI->IMR |= GPIO_PIN_0; //开启外部中断
				EXTI->IMR |= GPIO_PIN_1;
				signA=0;signB=0;
				time1=0;time2=0;
			}
		}
//printf("%d   %d   %d    %d  %d  %d\n",signA,signB,signC,wosignC,wosignA,wosignB);
			if(mode==2)
			{
						if(signA&&signB&&signC)
					{
						EXTI->IMR &= ~(GPIO_PIN_0);
						EXTI->IMR &= ~(GPIO_PIN_1);
						EXTI->IMR &= ~(GPIO_PIN_11);
						HAL_TIM_Base_Stop_IT(&htim2);
						if((wosignA<wosignB)&&(wosignB<wosignC)){t2=wosignB;t3=wosignC;}
						if((wosignA<wosignC)&&(wosignB>wosignC)){t2=wosignC;t3=wosignB;}
						if((wosignB<wosignA)&&(wosignA<wosignC)){t2=wosignA;t3=wosignC;}
						if((wosignB<wosignC)&&(wosignC<wosignA)){t2=wosignC;t3=wosignA;}
						if((wosignC<wosignA)&&(wosignA<wosignB)){t2=wosignA;t3=wosignB;}
						if((wosignC<wosignB)&&(wosignB<wosignA)){t2=wosignB;t3=wosignA;}
						if(t2>11){t2=11;}
						if(t3>11){t3=11;}
//						t2=wosignA-wosignB;
//						t3=wosignB-wosignC;
						printf("%d   %d    %f   %d   %d  %d %d %d\n",time1,time2,s,wosignA,wosignB,wosignC,t2,t3);
						Find_Square((float)t2/10000,(float)t3/10000);
						OLED_ShowFloat(0,0,arv1,2,4,16);
						OLED_ShowFloat(0,2,arv2,2,4,16);
						//HAL_Delay(100);
						EXTI->IMR |= GPIO_PIN_0; 
						EXTI->IMR |= GPIO_PIN_1;
						EXTI->IMR |= GPIO_PIN_11;
						signA=0;signB=0;signC=0;
						time1=0;time2=0;
					}
				}
			if(mode==3){goto MENU;}
			}

可以用自己的按键,设置标志位做两个模式,完成持续监测。

成品的误差稍微有些大,不乏温度,湿度,以及硬件误差,和单片机检测误差,没有滤波等等,总的来说,大体方向是对的,我们的作品还能进一步完善。
在调试的时候,单片机PB10引脚接收不到方波信号,拆了板子打电表,查不出问题,结果换了个引脚,好了,,,,,文章来源地址https://www.toymoban.com/news/detail-625422.html

到了这里,关于基于STM32F103HAL库的声音定位系统的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • HAL库(STM32CubeMX)之外部中断(STM32F103C8T6)

    HAL库(STM32CubeMX)——ADC学习总结(包含单次/连续模式下的轮询/中断/DMA)(蓝桥杯STM32G431RBT6) HAL库(STM32CubeMX)——DAC学习(STM32G431RBT6) HAL库(STM32CubeMX)——USART配置(中断接收/STM32G431RBT6) HAL库(STM32CubeMX)——基本定时器、PWM、输入捕获、输出比较、互补式PWM等综合学习(STM32

    2024年02月06日
    浏览(50)
  • 正点原子STM32F103精英版+HAL库实现4×4矩阵按键检测

    首先声明,本人小白一枚,所做的工作都是借鉴网上的大佬+自己摸索,但是都是亲测实际有效的。 因为所需要的功能开发板自带按键不够用,所以购买了4×4矩阵按键,当时购买的时候以为一个按键对应一个IO口,后来发现不是这样的,会浪费太多的IO口,4×4矩阵键盘用8个

    2024年02月06日
    浏览(58)
  • STM32F103C8T6(HAL库函数 - 内部Flash操作)

    STM32F103C8T6 内部Flash 为 64KB,本次将对他多余空间进行读写。 数据手册下载 STM32F103x8/STM32F103xB 数据手册 包含Flash Memory Page分布 STM32F设备命名 设备容量类型 中容量类型 内部空间介绍 Flash Memory 从 0x0800 0000 ~ 0x0801 FFFF 页分布1K每页, STM32F103C8T6 只有64KByte, 那就是64页 使用 controll

    2024年01月21日
    浏览(64)
  • 【STM32】基于STM32F103C8T6的水质检测系统设计(声光报警、多级菜单)

    1.检测参数:水温、TDS、浊度、PH 2.超出阈值声光报警 3.LCD显示目标参数的测量结果 4.测量模式:单参数测量、所有参数表同时测量 切换方式:按键切换 单总线技术 单总线技术采用单根信号线实现时钟、数据的传输,且数据的传输是双向的,能够控制一个或多个从机设备。主

    2024年02月01日
    浏览(49)
  • [STM32F103C8T6]W5500+Modbus TCP(HAL库)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 本章节是博主学习Modbus TCP所写的一篇文章 Modbus TCP是Modbus的一个分支,主要用到网口通信的,在工业上也用的很频繁,我们公司最近的项目就是用的W5500+modbus TCP来和PC端的上位机通信和交互的。虽然这个

    2024年02月15日
    浏览(44)
  • WS2812B彩灯 STM32HAL库开发:PWM+DMA(stm32f103c8t6)

    目录 一、摘要 二、WS2812B介绍 三、CUBEMX配置 四、程序介绍(KEIL编译器) 五、数据手册         1、本文使用示例单片机型号为 stm32f103c8t6 ,RGB型号为 WS2812B ;          2、主要实现功能是实现用 PWM+DMA 使RGB_LED亮起不同颜色的灯光;         3、目的:简单调通该型号

    2024年02月03日
    浏览(49)
  • STM32CubeIDE + HAL + STM32f103C8T6 系列教程1 ---板载PC13LED闪烁

    之前的系列教程都是基于Arduino的,但是公司招聘51和stm32的开发还是多些,所以特别开了一个stm32的系列。 这个系列特点是注重了 Arduino 编程思维和习惯下向STM32开发的过渡 。前期没有涉及到太多寄存器相关的知识,利用HAL库和STM32CubeIDE快速入手STM32的数字输入/输出、模拟输

    2024年02月16日
    浏览(44)
  • 基于STM32F103C8T6(HAL库)的HC-SR501红外人体传感及HC-SR04超声波测距

    一、基于STM32F103C8T6最小系统板和STM32CubeMX实现LED灯循环闪烁 二、基于STM32F103C8T6和STM32CubeMX实现UART串口通信数据收发 三、实战小例程 基于STM32F103C8T6最小系统板和STM32CubeMX驱动WS2812B光立方 四、基于STM32F103C8T6最小系统板HAL库CubeMX驱动HC-SR501红外人体传感模块 五、基于STM32F103C8

    2023年04月17日
    浏览(108)
  • 基于STM32F103C8T6的物联网温湿度光照烟雾监测系统

    1、系统组成:STM32F103C8T6最小系统、S8050三极管、有源高电平触发蜂鸣器、ESP8266_01S模块、DHT11温湿度传感器、0.96OLED显示屏、BH1750光照度传感器、MQ2烟雾浓度传感器、LED灯、碳膜电阻(300欧)、独立按键、排针若干、杜邦线若干、微信小程序、USB转TTL串口烧录工具等。 2、需要

    2024年02月04日
    浏览(37)
  • STM32F103C8T6基础开发教程(HAL库)—点亮第一颗LED灯

    STM32F103C8T6基础开发教程(HAL库)—开发环境配置 STM32F103C8T6基础开发教程(HAL库)—Keil添加注释的快捷键 STM32F103C8T6基础开发教程(HAL库)—点亮第一颗LED灯 STM32F103C8T6基础开发教程(HAL库)—LED灯交替闪烁 STM32F103C8T6基础开发教程(HAL库)—LED灯呼吸闪烁 STM32F103C8T6基础开发

    2024年01月18日
    浏览(63)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包