声音定位系统.doc_第1页
声音定位系统.doc_第2页
声音定位系统.doc_第3页
声音定位系统.doc_第4页
声音定位系统.doc_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

2014年重庆理工大学电子设计竞赛声音定位系统(C题)摘要:本系统使用STM32产生频率为500Hz的正弦波信号,该信号用LM386进行功率放大及驱动后输入到蜂鸣器作为声源。接收部分使用拾音器进行接收,首先对接收的信号经过同相放大,使变化的电流信号转换为变化的电压信号。然后经过由OP07组成的有源带通滤波器,该滤波器的中心频率为500Hz,带宽为100Hz,增益为1倍,去除周围环境的声波,滤波后的信号正好是蜂鸣器发出的声音信号。再对滤波后的两路信号经过相移检测电路,可以把滤波后的正弦波转换为方波,以便单片机STM32对相位差信号进行捕获。声源定位是通过对四个拾音器接收到相位差信号进行处理,经过一套比较完善的算法可得声源的坐标,即可进行声源定位。关键词:500Hz 声音定位 STM32 一、系统方案1.声音信号产生的选择 方案一:采用NE555产生频率为500Hz的方波用来作为声音信号。它的作用是用内部的定时器来构成时基电路。外部通过简单的电路可获得所得的信号。该电路搭建比较简单,原理易于理解,电路中元器件参数也比较好计算。 方案二:用单片机STM32来产生频率为500Hz的正弦波用来作为声音信号。该正弦波信号的产生实质上是将正弦波转换的到的数组存入单片机,经DA转换输出正弦波。 方案比较:方案一中,用NE555产生信源不是很稳定,波形不太规范且信号的频率不固定,这样的信号对本系统不太合适。方案二中,用软件来产生信号,该信号很稳定,是比较标准的频率为500Hz的正弦波信号,而且,产生波形比较灵活,从而为发挥部分做好准备。因此选择方案二。2.声源的选择 方案一:采用低音扬声器作为声源。扬声器是一种把电信号转变为声信号的换能器件。将单片机产生的频率为500Hz的信号接在扬声器的接收端,扬声器能发出强度比较大的声音信号。 方案二:采用无源蜂鸣器作为声源。无源蜂鸣器在提供一定频率的正弦波震荡源时,能够发出声音。试验中用无源蜂鸣器发声时,声音比较清晰,但声音强度比扬声器稍弱。方案比较:这里选择方案二。 3.滤波方案的选择 方案一:用RC无源滤波器。通过计算可以较方便的通过匹配电阻电容得出所需要的通频带。该滤波电路抗干扰性较强,有较好的低频特性,并且选用标准的阻容元件易得。 方案二:用有源滤波器。有源滤波器是利用可关断电力电子器件,产生与负荷电流中谐波分量大小相等、相位相反地电流来抵消谐波的滤波装置。有源滤波器除了滤除谐波外,同时还可以动态补偿无功功率。其优点是反映动作迅速,滤除谐波可达到95以上,补偿无功细致。 方案比较:方案一中,谐波滤除率一般只有80,对基波的无功补偿也是一定的,并且通频带比计算出的要宽,不太符合设计要求。方案二中,电路比较复杂,但通过匹配后能较好的完成带通滤波,能达到预期的要求。因此选择多路负反馈二阶有源带通滤波器,即方案二。二、定位算法理论分析与计算根据题目要求,A,B,C,D为声音接收模块,现对元坐标系进行坐标变换,以A点为坐标原点,建立笛卡尔坐标系,动点P(x,y)至点A,B,C,D的距离之差为一常数,建立数学模型:三、电路与程序设计1. 声响模块电路设计声响模块是由STM32单片机输出频率为500Hz的正弦波,然后从单片机引脚输出,输出的信号经过功率放大电路放大后,再接入到蜂鸣器,驱动发声。2. 声音接收放大器电路设计接收部分是用拾音器接收声音信号。由于拾音器接收到的信号在不经过放大时信号很小,不易检测,故后级利用放大电路将接收的信号进行处理。图 1 放大电路3. 测量、数据处理电路设计根据要求只有当接收到的信号为500Hz时,我们才能保证接收到的信号是由声源发出的。而拾音器接收到的声音信号是任意频率的,故此 处要进行滤波处理。滤波采用的是带通滤波器,通过电容电阻的匹配,最终滤波器的中心频率为500Hz,带宽为50Hz。拾音器接收到的信号经过带通滤波器后,能够将声源发出的信号滤出,正符合本题要求。图 2 二阶有源滤波电路滤波后的信号为正弦波,但该信号不便于用单片机进行处理,故在后级加入了相移检测电路。其基本功能是对两路正弦波信号进行比较,并根据比较结果输出一路方波信号。并由此来判断声音信号的位置差。能够用单片机然后用单片机进行捕获处理,效果比较满意。图 3 相移检测电路4. 程序设计4.1该系统程序设计主要分为四部分:用STM32产生500hz正弦波;利用STM32的输入捕获捕获相移检测电路后的方波信号;利用定位算法,通过单片机对检测到的相位差信号进行处理,得到声源位置坐标;将得到的声源位置坐标送TFT屏显示,并将位置坐标存入数组中,实现连续显示声源位置轨迹的功能 四、测试方案与测试结果1. 测试方法与仪器声源定位测试方法:将声源放在坐标纸上的任意坐标,不让声源发声,记下坐标值(x0,y0)。然后启动声源,让声源发出1s左右的声音信号,同时单片机接收信号后开始进行计算,计算出的坐标值(x1,y1)通过TFTLCD屏显示出来。 2. 测试结果与分析该系统的软件部分设计经验证,实现了捕获、处理、定位功能,如图所示为当声源信号位于(200,100)mm位置时,通过单片机定位算法得到的位置坐标:图 4 捕获的到的高电平及单片机处理得到的位置信息该系统的缺陷为功率放大模块和滤波模块没有做好,滤波模块实际滤波中心频率约为460hz,带宽100hz。效果不够理想。五、思考与总结经过几天的努力,终于基本完成了声音定位系统的制作与程序设计,在此过程中,收益颇多,熟悉了功放、滤波、放大等模块的制作以及如何利用STM32单片机完成一个系统设计等。在此过程中也认识到了许多不足,为以后的学习指明了方向。六、参考文献(略)七、附录1、主程序#include led.h#include delay.h#include key.h#include sys.h#include lcd.h#include usart.h#include timer.h#include math.h /全局变量x,y为坐标,以坐标纸左下角为原点,单位mms32 xx=0,yy=0;u8 xp=0,yp=0;u8 xp1=0,yp1=0;u16 cap_num1=0,cap_num2=0;u32 sum1=0,sum2=0;s16 t1=0,t2=0;u16 pointx280;/定义点的位置数组u16 pointy280;u8 DrawLine_flag=0;/定义画线标志位extern u8 TIM5CH1_CAPTURE_STA;/输入捕获状态 extern u16TIM5CH1_CAPTURE_VAL;/输入捕获值extern u8 TIM5CH2_CAPTURE_STA;/输入捕获状态 extern u16TIM5CH2_CAPTURE_VAL;/输入捕获值void Display_Change(void);/对声源信号进行处理,得到声源位置/当t1、t2情况为负值时,情况如何?void pxf(int t1,int t2) int a=500;int b=350;float v=340;float c1=t1*v/1000;float c2=t2*v/1000;float delta=(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);float R=(b*b-c1*c1)/2/(c1+b*sin(sita);xx=-R*cos(sita);yy=R*sin(sita); int main(void) u32 temp1=0,temp2=0; u16 i=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_Init(1999,719);/每5ms进一次定时器3中断,进行液晶屏显示 TIM5_Cap_Init(0XFFFF,72-1);/以1Mhz的频率计数 (每计数一次为1u秒)POINT_COLOR=RED;LCD_Clear(YELLOW);/背景色为黄色LCD_ShowChar(10,210,(,16,0);LCD_ShowChar(90,210,),16,0);LCD_ShowChar(50,210,16,0); while(1) for(i=0;i10&xp10&yp150)/判断点的坐标是否在正常范围内/把点存入数组if(xp!=xp1 | yp!=yp1)pointxj=xp;pointyj=yp;j+;if(j=280)/只存280个点的位置j=0;xp1=xp;/将上一次的位置值进行保存,与下一次进行比较,看是否有变化yp1=yp; 2、定时器部分程序#include timer.h#include led.h#include usart.h#include lcd.hextern s32 xx,yy;extern u8 xp,yp;/注意:对变量声明时不可以同时进行赋值extern u8 xp1,yp1;extern u8 DrawLine_flag;/在定时器3中断中进行液晶显示void TIM3_Int_Init(u16 arr,u16 psc) TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;NVIC_InitTypeDef NVIC_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; /设置时钟分割:TDTS = Tck_timTIM_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_Init(&NVIC_InitStructure); /初始化NVIC寄存器TIM_Cmd(TIM3, ENABLE); /使能TIMx /定时器3中断服务程序(声源位置显示)void TIM3_IRQHandler(void) /TIM3中断if (TIM_GetITStatus(TIM3, TIM_IT_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!=xp1 | yp!=yp1)&DrawLine_flag=1)LCD_DrawLine(xp1, yp1, xp, yp);ShowChinese(10,170);/显示汉字/定时器5通道1和通道2输入捕获配置TIM_ICInitTypeDef TIM5_ICInitStructure;void TIM5_Cap_Init(u16 arr,u16 psc) GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);/使能TIM5时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); /使能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_TimeBaseStructure.TIM_Period = arr; /设定计数器自动重装值 TIM_TimeBaseStructure.TIM_Prescaler =psc; /预分频器 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; /设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; /TIM向上计数模式TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); /根据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 选择输入端 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);/中断分组初始化NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn; /TIM5中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; /先占优先级2级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /从优先级0级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /IRQ通道被使能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 u8 TIM5CH1_CAPTURE_STA=0;/输入捕获状态 u16TIM5CH1_CAPTURE_VAL;/输入捕获值u8 TIM5CH2_CAPTURE_STA=0;/输入捕获状态 u16TIM5CH2_CAPTURE_VAL;/输入捕获值 /定时器5中断服务程序 void TIM5_IRQHandler(void) /通道1进行捕获 if(TIM5CH1_CAPTURE_STA&0X80)=0)/表示还未成功完成捕获 if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET) /表示更新中断已经发生 if(TIM5CH1_CAPTURE_STA&0X40)/表示已经捕获到高电平了if(TIM5CH1_CAPTURE_STA&0X3F)=0X3F)/判断高电平太长了TIM5CH1_CAPTURE_STA|=0X80;/强制标记成功捕获了一次TIM5CH1_CAPTURE_VAL=0XFFFF;else TIM5CH1_CAPTURE_STA+; if (TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET)/表示捕获1发生捕获事件if(TIM5CH1_CAPTURE_STA&0X40)/表示捕获到一个下降沿 TIM5CH1_CAPTURE_STA|=0X80;/标记成功捕获了一次TIM5CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5); /得到高电平的值TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); /CC1P=0 设置为上升沿捕获else /还未开始,第一次捕获上升沿TIM5CH1_CAPTURE_STA=0;/清空TIM5CH1_CAPTURE_VAL=0;TIM_SetCounter(TIM5,0);TIM5CH

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论