找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 10579|回复: 21
打印 上一主题 下一主题
收起左侧

我的单片机声音定位系统课程设计 含源码,仿真,原理图,报告

  [复制链接]
跳转到指定楼层
楼主
这是我大三时的电子课程设计,做的声音定位系统,课设具体要求如下:

附件里包含了,整个系统的源码,设计报告(含原理图)



本次设计采用 STC89C52RC 单片机进行运算处理和驱动 LCD12864 液晶显示
屏显示定位结果,即利用单片机内部定时器 0 计时,由外部中断 0、外部中断 1和定时器 1触发,检测接收信号的下降沿,通过这种方式计算声音传播后,不同模块接收到信号的时间差,通过时间差计算出声源信号到接收模块距离,然后由单片机编程计算出声源的位置坐标,最终显示在液晶屏上。 STC89C52RC 单片机小系统电路和 LCD12864驱动电路如下图所示:

五、算法与程序设计
5.1数据处理原理:
本算法基于时间差算出未知点的坐标点。从理论上分析,只需三个已知点就可以对声音源进行定位,我们首先先将问题简化为二维平面内对声音源进行定位。  如下图所示,在一个平面内分布有三个传感器A、 B和C坐标分别为(0,350)、(0,0)、(500,0)。当平面内某处 S(x,y)发出声音时,3 个传感器将先后接收到信号,设信号到达A,B的时间差为 t1,到达B,C的时间差为 t2,则有:






六、测试方案
6.1  主要的测试仪器、仪表
本次主要使用的测试仪器与仪表有,函数信号发生器、示波器与数字万用表。  
6.2  测试方法
在硬件测试中,按键发声模块通过示波器测试电路输出波形,调节电位器改变电阻值来调节触发时间,保证发出的声响持续时间为 1s;另外使用数字万用表测量按键发声模块的功耗。声音接收模块通过数字万用表,测量当发声模块距接收模块不同距离时,比较器输出电压,直至调节电位器,改变比较器灵敏度使输出电压在要求距离内能受到信号,并以下降沿触发单片机。声响模块和接收模块都可以使用函数发生器和示波器来检测电路的连接是否正常。
在软件测试中,我们组软件调试的中心思想是分模块调试。先将程序分为三个接受模块,算法模块,显示模块,我们在分块调试时,将各个模块的输出都显示出来以便于观察各模块是否正确。运用这种方法,可以将软件上的错误精确定位到某一个环节,大大提高了调试的效率。以下是具体方法:
1、将程序中的标志位signalA,signalB,signalC 通过LCD屏幕显示出来,以方便
观察是否所有传感器都收到了信号。
2、将各信号间的时间差通过 LCD 屏幕显示出来,以方便观察各传感器的响应速度以及接受信号的先后顺序是否与实际一致。
3、在接入传感器前,先用另一片单片机模仿传感器发出的信号,并通过程序设置时间差等参数,用于检查算法是否正确。
七、系统调试   
7.1  按键发声模块
测试输出电流(通过测量蜂鸣器串联的 1Ω的电阻得到电流值),从图中可知
为0.042A:

7.2  声音接收模块
当声响模块离接收模块距离较近时,接收模块输出电压达到 3.6V 左右。

当声响模块离接收模块较远时(但坐标仍属于坐标纸的范围),接收模块输出电压将会变小。这个时候就需要调节电位器,改变电阻值以减小比较器 LM358 输入端参考电压的值。


7.3 LCD 液晶显示模块
进行测试时,LCD12864 液晶显示模块除了显示坐标 X 与 Y的值外,还会显示A、B、C 三个声音接收模块的中断触发标志值(如下图显示屏中第一行所显示的内容,其中显示值为 0 表示未触发,为 1 则表示已触发),以及 A、B 和 C 三个声音接收模块依次收到信号时的计时时刻(其中从右到左依次为0us,65us和68us,此时模块 C 最先收到声音信号) ,这样方便系统调试。 下图坐标 X 与Y值在误差范围内,满足测量要求。


从表 8.2 可以看出,当电位器阻值较小时即比较器输入端参考电压接近 0 时更易收到信号,但实际上这样做也更容易受到干扰。接收模块 C 相较于A、B 模块了,由于焊接工艺的问题,灵敏度较低。合理调节电位器阻值之后,三个模块最终都能受到信号,满足设计要求。
8.3  声源实测坐标记录表
对处于不同坐标的声源进行了实际测量,最终得到了以下的一些实测数据如下

从表中可以看出,除个别点外,坐标纸的四个方向边缘区域以及中间区域共取了5个点,其实测坐标基本满足设计要求。而个别点的误差可能是由于接收模块放置的位置不准确或声源放置地不准确而产生。
九、总结
本次设计以 STC89C52 为核心部件,利用了声音检测与辨识技术,利用严密的数学方法实现和确定了声源的准确定位。在系统设计过程中,力求硬件电路简单,降低硬件成本,节约功耗。
在这次课程设计中,我们遇到了许多问题,这些问题我们之前从未遇到过,
但最终我们都找到了解决这些问题的办法,这对我们来说是一次很好的锻炼。在程序设计与软件调试的过程之中,由于我们同时使用了 STC89C52 单片机中的四个中断进行控制处理,对于单片机各个中断的优先级与触发的考虑更为复杂,但只要结合函数信号发生器模拟声音信号触发单片机得到调试结果,并且根据这些结果不断改正程序,就能得到最优的程序设计。另外在程序设计过程,由于子程序中数据处理十分重要,我们查阅了许多的资料,对于 C51中的数据类型以及常用的库函数也更加的熟悉。 在硬件调试过程中,出现了声音接收模块电路不稳定,易受到干扰,以及放大电路难以调试的问题。对于接下来课程设计之后,我们也会考虑重新设计相关电路,例如采用双比较器电路进行比较放大,来提高电路的性能。


主程序源码
  1. #include<reg52.h>
  2. #include<stdio.h>
  3. #include "delay.h"
  4. #include "lcd.h"
  5. #include<math.h>
  6. #define uchar unsigned char
  7. #define uint unsigned int
  8. #define BOOL bit
  9. #define BYTE unsigned char
  10. #define WORD unsigned int

  11. uchar signalA,signalB,signalC;
  12. uchar wolsignalA,wolsignalB,wolsignalC;
  13. uchar wolCount,obv;
  14. unsigned int posX,posY;         //坐标取值

  15. code unsigned char byValidShow[] = {" V值:           "};
  16. code unsigned char DispX[] = {" X轴:           "};
  17. code unsigned char DispY[] = {" Y轴:           "};

  18. void Init_Show()           //LCD初始化显示子程序
  19. {
  20.         Delay400Ms();
  21.         LCDInit();
  22.         LCDClear();
  23.         Delay5Ms();
  24.         LCDClear();
  25.         //DisplayListChar(0,1,byValidShow);
  26.         DisplayListChar(0,2,DispX);
  27.         DisplayListChar(0,3,DispY);
  28.         Delay5Ms();
  29. }

  30. void Init_isr()                //中断初始化设置子程序
  31. {
  32.         EA = 0;
  33.         TMOD = 0x62;        
  34.         /*外部中断0*/
  35.         IT0 = 1; EX0 = 1;
  36.         /*外部中断1*/
  37.         IT1 = 1; EX1 = 1;
  38.         /* 计数器 0*/
  39.         TH1 = 0xFF; TL1 = 0xFF; TR1 = 1; ET1 = 1;
  40.         /* 定时器 1*/
  41.         TH0 = 246; TL0 = 246; TR0 = 0; ET0 = 0;
  42.         /***********/
  43.         IE0=0;IE1=0;TF1=0;TF0=0;
  44.         EA = 1;
  45. }

  46. void signalchuli(float m,float n)  //坐标定位计算程序
  47. {

  48.         BOOL r1=0;
  49.         BOOL r2=0; //方程是否成立变量
  50.         BOOL suc=0; //解题是否成功变量
  51.         float x,y;        
  52.         for(x=10;x<=500;x+=10)
  53.         {
  54.                 for(y=10;y<=350;y+=10)
  55.                 {
  56.                         if(fabs(sqrt(x*x+(350-y)*(350-y))- sqrt(x*x+y*y)-m)<=20.0)
  57.                                 r1=1;
  58.                         //else r1=0;
  59.                         if(fabs(sqrt(x*x+y*y)-sqrt(y*y+(500-x)*(500-x)) -n)<=20.0)
  60.                                 r2=1;
  61.                         //else r2=0;
  62.                         if(r1&&r2)
  63.                                 {
  64.                                         suc=1;
  65.                                         break;
  66.                                 }
  67.                         else
  68.                                 {
  69.                                         r1=0;
  70.                                         r2=0;
  71.                                 }
  72.                 }
  73.                 if(suc)
  74.                         break;
  75.         }
  76.         
  77.         posX=x;
  78.         posY=y;
  79.         
  80. }

  81. void main()
  82. {
  83.         float cha1,cha2;
  84.         uchar cha1_temp,cha2_temp;
  85.         EA=0;
  86.         Init_Show();
  87.         Init_isr();               
  88.         while(1)
  89.         {
  90.                 if( signalA && signalB && signalC)
  91.                 {
  92.                         EA = 0;
  93.                         TR0=0;
  94.                         obv++;
  95.                         cha1_temp = wolsignalA - wolsignalB;
  96.                         cha2_temp = wolsignalB - wolsignalC;
  97.                         if(wolsignalA < wolsignalB)
  98.                         {
  99.                                 cha1_temp = 65536 - cha1_temp;
  100.                                 cha1 = -(3.4*cha1_temp);
  101.                         }
  102.                         else
  103.                         {
  104.                                 cha1 = 3.4*cha1_temp;
  105.                         }
  106.                         if(wolsignalB < wolsignalC)
  107.                         {
  108.                                 cha2_temp = 65536 - cha2_temp;
  109.                                 cha2 = -(3.4*cha2_temp);
  110.                         }
  111.                         else
  112.                         {
  113.                                 cha2 = 3.4*cha2_temp;
  114.                         }
  115.                         signalchuli(cha1,cha2);
  116.                         DisplayADData(4,2,posX);
  117.                         DisplayADData(4,3,posY);  //显示坐标
  118.                         signalA = 0;         
  119.                         signalB = 0;
  120.                         signalC = 0;                        
  121.                         wolCount = 0;
  122.                         Init_isr();
  123.                 }
  124.                 DisplayADData(0,4,wolsignalA);
  125.                 DisplayADData(3,4,wolsignalB);
  126.                 DisplayADData(6,4,wolsignalC);        //显示时间插值,方便调试

  127.                 DisplayADData(0,1,signalA);        
  128.                 DisplayADData(3,1,signalB);
  129.                 DisplayADData(6,1,signalC);                //显示触发标志位,方便调试
  130.         }
  131. }

  132. void JsA_isr() interrupt 0         //外部中断0,下降沿触发
  133. {
  134.         EX0 = 0;
  135.         if(wolCount == 0)
  136.         {
  137.                 wolsignalA = 0;
  138.                 TR0 = 1;
  139.                 ET0 = 1;
  140.         }
  141.         else
  142.         {
  143.                 wolsignalA = wolCount;
  144.         }
  145.         signalA = 1;
  146. }

  147. void JsB_isr() interrupt 2          //外部中断1,下降沿触发
  148. {
  149.         
  150.         if(wolCount == 0)
  151.         {
  152.                 wolsignalB = 0;
  153.                 TR0 = 1;
  154.                 ET0 = 1;
  155.         }        
  156.         else
  157.         {
  158.                 wolsignalB = wolCount;
  159.         }
  160.         signalB =1;
  161.         EX1 = 0;
  162. }

  163. void Timer1_isr() interrupt 3        //计数器1,工作方式2
  164. {
  165.         if(wolCount == 0)
  166.         {
  167.                 wolsignalC = 0;
  168.                 TR0 = 1;
  169.                 ET0 = 1;
  170.         }
  171.         else
  172.         {
  173.                 wolsignalC = wolCount;
  174.         }
  175.         signalC = 1;
  176.         ET1 = 0;        
  177. }                 

  178. void Timer0_isr() interrupt 1  //定时器0,工作方式2 , 10us
  179. {
  180.         wolCount++;        
  181. }
复制代码
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


全部资料51hei下载地址:
声音定位系统.rar (1.6 MB, 下载次数: 351)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏11 分享淘帖 顶2 踩
回复

使用道具 举报

沙发
ID:403610 发表于 2018-10-28 21:06 | 只看该作者
楼主在吗,我们小组也做了这个,有些不懂得想问一下
回复

使用道具 举报

板凳
ID:487995 发表于 2019-3-10 17:07 | 只看该作者
架向樱的星空 发表于 2018-10-28 21:06
楼主在吗,我们小组也做了这个,有些不懂得想问一下

我也想问一下
回复

使用道具 举报

地板
ID:476221 发表于 2019-3-11 10:33 | 只看该作者
请问一下有清楚的原理图吗
回复

使用道具 举报

5#
ID:218046 发表于 2019-4-12 21:04 | 只看该作者
看设计报告蛮详细的,很有帮助,程序还没测试,感谢楼主
回复

使用道具 举报

6#
ID:514784 发表于 2019-4-17 17:22 | 只看该作者
问下,那个LCD.h和delay.h的源代码是怎么样的
回复

使用道具 举报

7#
ID:514845 发表于 2019-4-17 18:26 | 只看该作者
哎  求一个51 nrf24L01的收发完整控制灯亮程序
回复

使用道具 举报

8#
ID:366634 发表于 2019-5-23 20:32 | 只看该作者
对于下面这段话能再解释一下这三个时间怎么来的吗?谢谢。
以及 A、B 和 C 三个声音接收模块依次收到信号时的计时时刻(其中从右到左依次为0us,65us和68us,此时模块 C 最先收到声音信号)
回复

使用道具 举报

9#
ID:440755 发表于 2019-7-5 12:27 | 只看该作者
讲的很详细,谢谢楼主
回复

使用道具 举报

10#
ID:458437 发表于 2019-11-4 10:33 | 只看该作者
好东西
回复

使用道具 举报

11#
ID:662583 发表于 2019-12-31 15:10 | 只看该作者
这个真心不错
回复

使用道具 举报

12#
ID:692176 发表于 2020-2-11 18:21 | 只看该作者
请问楼主,这个声源定位系统能对3-5米的人声方位进行大概定位吗?
回复

使用道具 举报

13#
ID:707901 发表于 2020-3-13 19:27 来自手机 | 只看该作者
楼主在吗想联系一下解决一下问题
回复

使用道具 举报

14#
ID:707901 发表于 2020-3-15 16:30 | 只看该作者
有谁知道声音或者震动定位还有什么产品 比较成熟的那种
回复

使用道具 举报

15#
ID:698983 发表于 2020-4-21 16:15 | 只看该作者
飞飞会飞 发表于 2020-3-15 16:30
有谁知道声音或者震动定位还有什么产品 比较成熟的那种

问一下,你有用楼主这个设计吗?能行吗?
回复

使用道具 举报

16#
ID:698983 发表于 2020-4-21 16:18 | 只看该作者
看了下楼主的测试图,12684显示上,第一行为啥全是0(未触发中断)?
回复

使用道具 举报

17#
ID:698983 发表于 2020-4-25 12:23 | 只看该作者
我裂开了,我单独仿真了一次,发现根本不会产生中断,这也太坑了吧
回复

使用道具 举报

18#
ID:259850 发表于 2020-5-15 01:21 来自手机 | 只看该作者
飞飞会飞 发表于 2020-3-13 19:27
楼主在吗想联系一下解决一下问题

你解决好没
回复

使用道具 举报

19#
ID:259850 发表于 2020-5-15 22:22 来自手机 | 只看该作者
呼呼哈 发表于 2020-4-25 12:23
我裂开了,我单独仿真了一次,发现根本不会产生中断,这也太坑了吧

你解决好没
回复

使用道具 举报

20#
ID:660950 发表于 2021-1-2 19:56 | 只看该作者
你们根据这些文件做出来的实物实现定位的功能了吗?
回复

使用道具 举报

21#
ID:1026260 发表于 2022-5-13 22:20 来自手机 | 只看该作者
这个文件是有问题的吗
回复

使用道具 举报

22#
ID:1039802 发表于 2022-7-17 20:57 | 只看该作者
楼主的仿真图
是用什么打开的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表