声音定位系统Word文档格式.docx
- 文档编号:3957532
- 上传时间:2023-05-02
- 格式:DOCX
- 页数:20
- 大小:77.41KB
声音定位系统Word文档格式.docx
《声音定位系统Word文档格式.docx》由会员分享,可在线阅读,更多相关《声音定位系统Word文档格式.docx(20页珍藏版)》请在冰点文库上搜索。
有源滤波器除了滤除谐波外,同时还可以动态补偿无功功率。
其优点是反映动作迅速,滤除谐波可达到95%以上,补偿无功细致。
方案一中,谐波滤除率一般只有80%,对基波的无功补偿也是一定的,并且通频带比计算出的要宽,不太符合设计要求。
方案二中,电路比较复杂,但通过匹配后能较好的完成带通滤波,能达到预期的要求。
因此选择多路负反馈二阶有源带通滤波器,即方案二。
、定位算法理论分析与计算
根据题目要求,A,B,C,D为声音接收模块,现对元坐标系进行坐标变换,以A点
为坐标原点,建立笛卡尔坐标系,动点P(x,y)至点A,B,C,D的距离之差为一常数,
建立数学模型:
b-S=i,
得:
.x2(y-b)2-\
x2y2=pv
(x-a)2y2_、x
2y2二t2v
••…②
■■■..(x-a)2■(y-b)2-
…x2y2=t3v..
.….③
令t1v=C1x=
Rcos^
t2v二C2y二
Rsinv
二C3
原方程转化为:
2R(C1bsinJ二
b2-C12……
2R(C2acosj
二a2-C;
..…
………⑤
2R(C3acos71+bsin=a2
b2-C;
④得:
C1+bsin日
=b2-C2
⑤C2acos^
a2-C;
p=arctan
C21G
2(C「bsiz)
三、电路与程序设计
1.声响模块电路设计
声响模块是由STM32单片机输出频率为500Hz的正弦波,然后从单片机引脚输出,输出的信号经过功率放大电路放大后,再接入到蜂鸣器,驱动发声。
2.声音接收放大器电路设计
接收部分是用拾音器接收声音信号。
由于拾音器接收到的信号在不经过放大时信号很小,不易检测,故后级利用放大电路将接收的信号进行处理。
3.测量、数据处理电路设计
根据要求只有当接收到的信号为500Hz时,我们才能保证接收到的信号是由声源发出的。
而拾音器接收到的声音信号是任意频率的,故此处要进行滤波处理。
滤波采用的是带通滤波器,通过电容电阻的匹配,
最终滤波器的中心频率为500Hz带宽为50Hz,拾音器接收到的信号经
过带通滤波器后,能够将声源发出的信号滤出,正符合本题要求。
LJI
II4OUT
■4——
SSS.SkQ
RA22
31.SQ
图2二阶有源滤波电路
滤波后的信号为正弦波,但该信号不便于用单片机进行处理,故在后级加
入了相移检测电路。
其基本功能是对两路正弦波信号进行比较,并根据比较结果
输出一路方波信号。
并由此来判断声音信号的位置差。
能够用单片机然后用单片机进行捕获处理,效果比较满意。
图3相移检测电路
4.程序设计4.1该系统程序设计主要分为四部分:
①用STM3計生500hz正弦波;
③利用STM32勺输入捕获捕获相移检测电路后的方波信号;
③利用定位算法,通过单片机对检测到的相位差信号进行处理,得到声源位置坐
标;
O将得到的声源位置坐标送TFT屏显示,并将位置坐标存入数组中,实现连续显示声源位置轨迹的功能
四、测试方案与测试结果
1.测试方法与仪器
声源定位测试方法:
将声源放在坐标纸上的任意坐标,不让声源发声,
记下坐标值(xO,yO)。
然后启动声源,让声源发出1s左右的声音信号,同时单片机接收信号后开始进行计算,计算出的坐标值(x1,y1)通过
TFTLC[屏显示出来。
2.测试结果与分析
该系统的软件部分设计经验证,实现了捕获、处理、定位功能,如图所示为当声源信号位于(200,100)mm位置时,通过单片机定位算法得到的位置坐
标:
通道lHigh:
2Tlux
通道2Kigh:
203ui
坐标x:
197m
坐标y:
104mm
通道lHigh271us
通道263诽
坐标x:
坐标F-104M
通道LHighEVlus
個道2Mi^:
283ik
图4捕获的到的高电平及单片机处理得到的位置信息
该系统的缺陷为功率放大模块和滤波模块没有做好,滤波模块实际滤波中心频率约为460hz,带宽100hz。
效果不够理想。
五、思考与总结
经过几天的努力,终于基本完成了声音定位系统的制作与程序设计,在此过程中,收益颇多,熟悉了功放、滤波、放大等模块的制作以及如何利用STM32单
片机完成一个系统设计等。
在此过程中也认识到了许多不足,为以后的学习指明了方向。
六、参考文献(略)
七、附录
1、主程序#include"
led.h"
#include"
delay.h"
key.h"
sys.h"
lcd.h"
usart.h"
timer.h"
math.h"
mm
//全局变量x,y为坐标,以坐标纸左下角为原点,单位s32xx=0,yy=0;
u8xp=0,yp=0;
u8xp1=0,yp1=0;
u16cap_num1=0,cap_num2=0;
u32sum1=0,sum2=0;
s16t1=0,t2=0;
u16pointx[280];
//定义点的位置数组
u16pointy[280];
u8DrawLine_flag=0;
//定义画线标志位
externu8TIM5CH1_CAPTURE_STA;
//输入捕获状态
externu16TIM5CH1_CAPTURE_VAL;
输入捕获值externu8TIM5CH2_CAPTURE_STA;
externu16TIM5CH2_CAPTURE_VAL;
输入捕获值
voidDisplay_Change(void);
//对声源信号进行处理,得到声源位置
//当t1、t2情况为负值时,情况如何?
voidpxf(intt1,intt2)
{
inta=500;
intb=350;
floatv=340;
floatc1=t1*v/1000;
floatc2=t2*v/1000;
floatdelta=(b*b-c1*c1)/(a*a-c2*c2);
float
sita=atan2(b,delta*a)+acos((c2*delta-c1)/sqrt(delta*delta*a*a+b*b));
floatR=(b*b-c1*c1)/2/(c1+b*sin(sita));
xx=-R*cos(sita);
yy=R*sin(sita);
}
intmain(void)
u32temp1=0,temp2=0;
u16i=0,j=0;
Display_Change();
//通过读取A3管脚IO口的状态选择打点还是画线
delay_init();
//延时函数初始化
NVIC_Configuration();
//设置NVIC中断分组2:
2位抢占优先级,2位
响应优先级
uart_init(9600);
//
串口初始化为9600
LED_Init();
//LED端口初始化
LCD_Init();
TIM3_Int_lnit(1999,719);
〃每5ms进一次定时器3中断,进行液晶屏显示
TIM5_Cap_lnit(0XFFFF,72-1);
//以1Mhz的频率计数(每计数一次为1u
秒)
POINT_COLOR=RED;
LCD_Clear(YELLOW);
〃背景色为黄色
LCD_ShowChar(10,210,'
('
16,0);
LCD_ShowChar(90,210,'
)'
LCD_ShowChar(50,210,'
'
while
(1)
for(i=0;
i<
400;
i++)//进行400次输入捕获,理论应该执行800ms,
待验证
if(TIM5CH1_CAPTURE_STA&
0X80)成功完成一次捕获cap_num1++;
temp1=TIM5CH1_CAPTURE_STA&
0X3F;
temp1*=65536;
//溢出时间总和temp1+=TIM5CH1_CAPTURE_VAL;
//得到总的高电平时间sum1+=temp1;
TIM5CH1_CAPTURE_STA=0;
//开启下一次捕获
if(TIM5CH2_CAPTURE_STA&
0X80)成功完成一次捕获
cap_num2++;
temp2=TIM5CH2_CAPTURE_STA&
temp2*=65536;
//溢出时间总和
temp2+=TIM5CH2_CAPTURE_VAL;
//得到总的高电平时间
sum2+=temp2;
TIM5CH2_CAPTURE_STA=0;
t1=sum1/cap_num1;
//求平均值,提高捕获精度printf("
\r\n通道1High:
%dus\r\n"
t1);
sum1=0;
cap_num1=0;
t2=sum2/cap_num2;
printf("
\r\n通道2High:
t2);
sum2=0;
cap_num2=0;
pxf(t1,t2);
xp=xx/2.5;
yp=140-yy/2.5;
if(xp>
10&
&
xp<
210&
yp>
yp<
150)//判断点的坐标是否在正常范围内
//把点存入数组
if(xp!
=xp1|yp!
=yp1)
pointx[j]=xp;
pointy[j]=yp;
j++;
if(j==280)//只存280个点的位置
j=0;
xp1=xp;
//将上一次的位置值进行保存,与下一次进行比较,看是否有变化
yp1=yp;
2、定时器部分程序#include"
#include"
externs32xx,yy;
externu8xp,yp;
//注意:
对变量声明时不可以同时进行赋值
externu8xp1,yp1;
externu8DrawLine_flag;
//在定时器3中断中进行液晶显示
voidTIM3_Int_Init(u16arr,u16psc)
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
NVIC_InitTypeDefNVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
/时/钟使能
//定时器TIM3初始化
TIM_TimeBaseStructure.TIM_Period=arr;
//设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler=psc;
//设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
//设置时钟分害U:
TDTS=Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
//TIM
向上计数模式
TIM_TimeBaseInit(TIM3,&
TIM_TimeBaseStructure);
//根据指定的参数初始化TIMx的时间基数单位
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
//使能指定的TIM3中断,允许更新中断
//中断优先级NVIC设置
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;
//TIM3中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
//IRQ通道被使能
NVIC」nit(&
NVIC」nitStructure);
//初始化NVIC寄存器
TIM_Cmd(TIM3,ENABLE);
//使能TIMx
//定时器3中断服务程序(声源位置显示)
voidTIM3_IRQHandler(void)//TIM3中断
if(TIM_GetlTStatus(TIM3,TIM」T_Update)!
=RESET)//检查TIM3更
新中断发生与否
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
//清除TIMx更新
中断标志
LCD_ShowNum(20,210,xx,3,16);
//显示数字
LCD_ShowNum(65,210,yy,3,16);
LCD_DrawRectangle(10,10,210,150);
//画矩形
LCD_DrawPoint(xp,yp);
//画点if((xp!
=yp1)&
DrawLine_flag==1)
{LCD_DrawLine(xp1,yp1,xp,yp);
ShowChinese(10,170);
//显示汉字}
//定时器5通道1和通道2输入捕获配置TIM_ICInitTypeDefTIM5_ICInitStructure;
voidTIM5_Cap_Init(u16arr,u16psc)
GPIO_InitTypeDefGPIO_InitStructure;
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLER使能TIM5时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOAE,NABLE);
//使能GPIOA时钟
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
//PA0清除
之前设置
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;
//PA0下拉输入GPIO_Init(GPIOA,&
GPIO_InitStructure);
GPIO_ResetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1);
//初始化定时器时基参数TIM5
//设定计数器自动重装值
//预分频器
//TIM向上计数模式
TIM_TimeBaseInit(TIM5,&
//根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//初始化TIM5输入捕获1参数
TIM5_ICInitStructure.TIM_Channel=TIM_Channel_1;
//CC1S=01选
择输入端IC1映射到TI1上
TIM5_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;
//
上升沿捕获
TIM5_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;
//映射到TI1上
TIM5_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;
//配置输
入分频,不分频
TIM5_ICInitStructure.TIM_ICFilter=0x00;
//IC1F=0000配置输入滤波
器不滤波
TIM_ICInit(TIM5,&
TIM5_ICInitStructure);
//初始化TIM5输入捕获2参数
TIM5_ICInitStructure.TIM_Channel=TIM_Channel_2;
//CC1S=01
//上升沿捕获
//映射到TI1上
//配置输入分频,不分频
//IC1F=0000配置输入滤波器不滤波
//中断分组初始化
NVIC_InitStructure.NVIC_IRQChannel=TIM5_IRQn;
//TIM5中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
//先占优先级2级
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
//从优先级0级NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&
NVIC_InitStructure);
//根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1|TIM_IT_CC2,ENABLE);
允许更新中断,允许CC1IE捕获中断
//TIM_IT_CC1:
TIM捕获/比较1中断源
TIM_Cmd(TIM5,ENABLE);
//使能定时器5
u8TIM5CH1_CAPTURE_STA=0;
//输入捕获状态
u16TIM5CH1_CAPTURE_VAL;
输入捕获值u8TIM5CH2_CAPTURE_STA=0;
u16TIM5CH2_CAPTURE_VAL;
//定时器5中断服务程序
voidTIM5_IRQHandler(void)
//通道1进行捕获
if((TIM5CH1_CAPTURE_STA&
0X80)==0)/表示还未成功完成捕获
if(TIM_GetITStatus(TIM5,TIM_IT_Update)!
=RESET)//表示更新
中断已经发生
0X40)表示已经捕获到高电平了
0X3F)==0X3F)判断高电平太长了{
TIM5CH1_CAPTURE_STA|=0X80强制标记成功捕获了一次TIM5CH1_CAPTURE_VAL=0XFFFF;
elseTIM5CH1_CAPTURE_STA++;
if(TIM_GetITStatus(TIM5,TIM_IT_CC1)!
=
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 声音 定位 系统