声音定位系统
更新时间:2024-06-06 14:04:01 阅读量: 综合文库 文档下载
2014年重庆理工大学电子设计竞赛
声音定位系统(C题)
1
摘要:本系统使用STM32产生频率为500Hz的正弦波信号,该信号用LM386进行功率放大及驱动后输入到蜂鸣器作为声源。接收部分使用拾音器进行接收,首先对接收的信号经过同相放大,使变化的电流信号转换为变化的电压信号。然后经过由OP07组成的有源带通滤波器,该滤波器的中心频率为500Hz,带宽为100Hz,增益为1倍,去除周围环境的声波,滤波后的信号正好是蜂鸣器发出的声音信号。再对滤波后的两路信号经过相移检测电路,可以把滤波后的正弦波转换为方波,以便单片机STM32对相位差信号进行捕获。声源定位是通过对四个拾音器接收到相位差信号进行处理,经过一套比较完善的算法可得声源的坐标,即可进行声源定位。
关键词:500Hz 声音定位 STM32
一、系统方案
2
1.声音信号产生的选择
方案一:采用NE555产生频率为500Hz的方波用来作为声音信号。它的作用是用内部的定时器来构成时基电路。外部通过简单的电路可获得所得的信号。该电路搭建比较简单,原理易于理解,电路中元器件参数也比较好计算。
方案二:用单片机STM32来产生频率为500Hz的正弦波用来作为声音信号。该正弦波信号的产生实质上是将正弦波转换的到的数组存入单片机,经DA转换输出正弦波。
方案比较:方案一中,用NE555产生信源不是很稳定,波形不太规范且信号的频率不固定,这样的信号对本系统不太合适。方案二中,用软件来产生信号,该信号很稳定,是比较标准的频率为500Hz的正弦波信号,而且,产生波形比较灵活,从而为发挥部分做好准备。因此选择方案二。
2.声源的选择
方案一:采用低音扬声器作为声源。扬声器是一种把电信号转变为声信号的换能器件。将单片机产生的频率为500Hz的信号接在扬声器的接收端,扬声器能发出强度比较大的声音信号。
方案二:采用无源蜂鸣器作为声源。无源蜂鸣器在提供一定频率的正弦波震荡源时,能够发出声音。试验中用无源蜂鸣器发声时,声音比较清晰,但声音强度比扬声器稍弱。
方案比较:这里选择方案二。
3.滤波方案的选择
方案一:用RC无源滤波器。通过计算可以较方便的通过匹配电阻电容
得出所需要的通频带。该滤波电路抗干扰性较强,有较好的低频特性,并且选用标准的阻容元件易得。
方案二:用有源滤波器。有源滤波器是利用可关断电力电子器件,产生
与负荷电流中谐波分量大小相等、相位相反地电流来抵消谐波的滤波装置。
3
有源滤波器除了滤除谐波外,同时还可以动态补偿无功功率。其优点是反映动作迅速,滤除谐波可达到95%以上,补偿无功细致。
方案比较:方案一中,谐波滤除率一般只有80%,对基波的无功补偿也是一定的,并且通频带比计算出的要宽,不太符合设计要求。方案二中,电路比较复杂,但通过匹配后能较好的完成带通滤波,能达到预期的要求。因此选择多路负反馈二阶有源带通滤波器,即方案二。
二、定位算法理论分析与计算
根据题目要求,A,B,C,D为声音接收模块,现对元坐标系进行坐标变换,以A点为坐标原点,建立笛卡尔坐标系,动点P(x,y)至点A,B,C,D的距离之差为一常数,建立数学模型:
x2?(y?b)2?x2?y2??t1v...........①(x-a)2?y2?x2?y2??t2v.............②(x-a)2?(y-b)2?x2?y2??t3v.......③令?t1v=C1????????x?Rcos?????t2v??C2??????y?Rsin?????t3v?C3原方程转化为: 2R(C1?bsin?)?b2?C12..............④2??????????????????????????????2R(C2?acos?)?a2?C2.............⑤??????????????????????????????2R(C3?acos?+bsin?)?a2?b2?C32.............⑥C1+bsin?b2?C12④得:=22⑤C2?acos?a?C2
b2?C12令2=?1,得: 2a?C24
C2?1?C1b?=arctan?arccos22?1a?1a?b2b2?C12R?2(C1?bsin?)
三、电路与程序设计
1. 声响模块电路设计
声响模块是由STM32单片机输出频率为500Hz的正弦波,然后从单片机引脚输出,输出的信号经过功率放大电路放大后,再接入到蜂鸣器,驱动发声。
2. 声音接收放大器电路设计
接收部分是用拾音器接收声音信号。由于拾音器接收到的信号在不经过放大时信号很小,不易检测,故后级利用放大电路将接收的信号进行处理。
图 1 放大电路
3. 测量、数据处理电路设计
根据要求只有当接收到的信号为500Hz时,我们才能保证接收到的信号是由声源发出的。而拾音器接收到的声音信号是任意频率的,故此 处要进行滤波处理。滤波采用的是带通滤波器,通过电容电阻的匹配,
5
Display_Change();//通过读取A3管脚IO口的状态选择打点还是画线
delay_init(); //延时函数初始化
NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位u32 temp1=0,temp2=0; u16 i=0,j=0;
响应优先级
uart_init(9600); //串口初始化为9600
//LED端口初始化
LED_Init();
LCD_Init();
TIM3_Int_Init(1999,719);//每5ms进一次定时器3中断,进行液晶屏显示
TIM5_Cap_Init(0XFFFF,72-1); //以1Mhz的频率计数 (每计数一次为1u
秒)
LCD_ShowChar(10,210,'(',16,0); LCD_ShowChar(90,210,')',16,0); LCD_ShowChar(50,210,',',16,0); POINT_COLOR=RED;
LCD_Clear(YELLOW);//背景色为黄色
while(1)
{
//进行400次输入捕获,理论应该执行800ms,
for(i=0;i<400;i++)
待验证
{
if(TIM5CH1_CAPTURE_STA&0X80)//成功完成一次捕获
11
{ 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&0X3F;
temp2*=65536; //溢出时间总和 temp2+=TIM5CH2_CAPTURE_VAL; //得到总的高电平时间 sum2+=temp2;
TIM5CH2_CAPTURE_STA=0; //开启下一次捕获
}
}
t1=sum1/cap_num1;//求平均值,提高捕获精度 printf(\通道1High:%d us\\r\\n\ sum1=0; cap_num1=0;
t2=sum2/cap_num2;
printf(\通道2High:%d us\\r\\n\
12
sum2=0;
cap_num2=0;
xp=xx/2.5; yp=140-yy/2.5;
if(xp>10&&xp<210&&yp>10&&yp<150)//判断点的坐标是否在正常范pxf(t1,t2);
围内
{
//把点存入数组 if(xp!=xp1 | yp!=yp1) {
pointx[j]=xp; pointy[j]=yp; j++;
if(j==280)//只存280个点的位置 { }
xp1=xp;//将上一次的位置值进行保存,与下一次进行比较,
j=0;
看是否有变化 }
13
}
yp1=yp;
} }
2、定时器部分程序 #include \#include \#include \#include \
extern 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;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
//定时器TIM3初始化
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入NVIC_InitTypeDef NVIC_InitStructure;
活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟
频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟
分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM
14
向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初
始化TIMx的时间基数单位
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,
允许更新中断 }
//定时器3中断服务程序(声源位置显示) void TIM3_IRQHandler(void) //TIM3中断 {
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查TIM3更TIM_Cmd(TIM3, ENABLE); //使能TIMx
//中断优先级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_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx更新
中断标志
LCD_ShowNum(20,210,xx,3,16);//显示数字
15
}
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_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //使能TIM5时
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; //PA0 清除
16
之前设置
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_tim
TIM_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参数
17
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; //输入捕获状态
18
u16 TIM5CH1_CAPTURE_VAL; //输入捕获值
u8 TIM5CH2_CAPTURE_STA=0; //输入捕获状态 u16 TIM5CH2_CAPTURE_VAL; //输入捕获值
//定时器5中断服务程序 void TIM5_IRQHandler(void) {
//通道1进行捕获
if((TIM5CH1_CAPTURE_STA&0X80)==0)//表示还未成功完成捕获
{
if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET) //表示更新
中断已经发生
{ }
if (TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET)//表示捕获1发
if(TIM5CH1_CAPTURE_STA&0X40)//表示已经捕获到高电平了 {
if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)//判断高电平太长了 { }
else TIM5CH1_CAPTURE_STA++;
TIM5CH1_CAPTURE_STA|=0X80;//强制标记成功捕获了一次 TIM5CH1_CAPTURE_VAL=0XFFFF;
}
生捕获事件
{
19
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); TIM5CH1_CAPTURE_STA|=0X40;
//标记捕获到了上升沿
//清空
//还未开始,第一次捕获上升沿
TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling);
//CC1P=1 设置为下降沿捕获
}
}
}
//通道2进行捕获
if((TIM5CH2_CAPTURE_STA&0X80)==0)//表示还未成功完成捕获 {
if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET) //表示更新
中断已经发生
{
if(TIM5CH2_CAPTURE_STA&0X40)//表示已经捕获到高电平了 {
if((TIM5CH2_CAPTURE_STA&0X3F)==0X3F)//判断高电平太长了
20
}
{ }
else TIM5CH2_CAPTURE_STA++;
TIM5CH2_CAPTURE_STA|=0X80;//强制标记成功捕获了一次 TIM5CH2_CAPTURE_VAL=0XFFFF;
}
if (TIM_GetITStatus(TIM5, TIM_IT_CC2) != RESET)//表示捕获1发
生捕获事件
{
{
//标记成功捕获了一次
if(TIM5CH2_CAPTURE_STA&0X40)
//表示捕获到一个下降沿
TIM5CH2_CAPTURE_STA|=0X80;
TIM5CH2_CAPTURE_VAL=TIM_GetCapture2(TIM5); //得到高电
平的值
TIM_OC2PolarityConfig(TIM5,TIM_ICPolarity_Rising);
//CC1P=0 设置为上升沿捕获
} else {
TIM5CH2_CAPTURE_STA=0; TIM5CH2_CAPTURE_VAL=0; TIM_SetCounter(TIM5,0); TIM5CH2_CAPTURE_STA|=0X40;
//标记捕获到了上升沿
//清空
//还未开始,第一次捕获上升沿
TIM_OC2PolarityConfig(TIM5,TIM_ICPolarity_Falling);
//CC1P=1 设置为下降沿捕获
}
21
}
}
TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_CC2|TIM_IT_Update); //清除中断标志位 }
22
正在阅读:
声音定位系统06-06
美术学情分析07-11
考研政治重难知识点试题选编05-17
我有一个小秘密作文350字07-10
品质管理资料-微型计算机、便携式计算机、服务器(0901)类产品工厂检查作业指导书09-02
2019-2020年期末考试小学考试质量03-03
曲墙式衬砌计算 - 副本05-24
比的基本练习题03-26
精确温度显示的温控自动风扇系统07-17
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 定位
- 声音
- 系统
- 安徽省皖南八校2018届高三第三次联考(4月)理综化学试题
- DNA定量分析系统项目介绍(新版ZYJ)
- 吉林市IT零售和服务商名录2018版153家
- 匀变速直线运动规律的总结
- 二年级下册数学期中试卷(一)-轻巧夺冠苏州市实验小学
- 物联网中的关键技术研究及其应用
- 食品安全管理员培训证书试题——2015年12月2日更新
- 江苏省苏州市常熟市外国语学校2016届九年级上学期开学水平测试英
- 深圳公司注册流程及需要准备材料
- 国际结算单选参考答案
- 《木偶奇遇记》阅读测试题及答案
- 从消费者心理需求谈中国广告的创意困境毕业论文
- 九(1)班班级公约
- 世界服务贸易壁垒与我国对策研究
- 罗氏电化学发光仪器E170 SOP - 图文
- 甘肃金川铜镍矿床实验报告
- 砂和砂石地基工程检验批质量验收记录表
- 浅谈如何培养学生解决问题的能力
- 模拟试卷十二题目
- 2016卫生管理初级师考试试题总汇及答案(全)