环境:win7 64   vivado 2014.1
开发板:zedboard version d    xc7z020clg484-1
串口软件:SecureCRT
目标:对一段随机的音频信号进行实时频谱分析。从pc获取音频信号,经由PL的fft IP处理后送入OLED,进行音频频谱的实时显示。通过本实例学习vivado+zedboard软硬件设计的方法,学习控制zedboard外设的方法。本文在商品博客的基础上,把fft函数改为fft ip,实现相同的功能,对部分函数进行优化。

说明:本文的fft算法部分采用硬件实现的,使用的是vivado自带的ip,参考ug871。

注意:本文中所有的源码、工程文件在“我的资源”中可以找到,如果没有请联系作者本人。转载请注明出处。

正文:

本文将分为以下步骤:

1. 使用Vivado 建一个工程,添加oled、audio_ctrl等IP,完成硬件设计。generate,最后导入到SDK中

2. 在SDK中新建工程,添加文件,编译。下载到ZedBoard上进行调试

3. 程序分析

4. 总结

1. 使用Vivado 建一个工程,添加oled、audio_ctrl等IP,完成硬件设计。generate,最后导入到SDK中

1)新建目录audio_fre_hw,在其下新建vivado工程。选择zedboard开发板。

2)将ip_repo拷贝到audio_fre_hw/下。打开IP catalog目录,选择IP setting,添加/audio_fre_hw/ip_repo.

3)将system.tcl拷贝到audio_fre_hw/下。

4)打开vivado的TCL console,

输入:cd (dir)/project/audio_fre_sw。

输入:source system.tcl

此时可以看到自动创建了一个system.bd。

5)generate output product

6) create HDL wrapper

7) 添加约束文件。oled.xdc和zed_audio_constraints.xdc

8)generate bitstream

9)open implementation design & block design

10) export for SDK

2. 在SDK中新建工程,添加文件,编译。下载到ZedBoard上进行调试

11) 在SDK中新建工程,audio_fre_hw,选择空模板

12)添加源文件,见/src/sdk

13) 检查自动编译的结果是否正确。如果报错,提示缺少sin、cos等,在project->property->build setting->linker library中添加参数m,以使用数学函数库

添加完毕后,SDK会自动编译程序。出现“'Finished building: test_audio.elf.size'”说明成功。

14)使用音频线(音箱和电脑连接的那个线)连接pc的音频口和zedboard的LINE IN接口,将耳机的音频插头接入LINE OUT接口。使用miniUSB连接J14和J17接口用于串口通信和烧写程序。

15)打开SecureCRT并连接。选择Xilinx tools->Program FPGA,烧写程序,蓝灯DONE亮说明成功。

16)打开PC的音频播放器,随便播放一段音频。run->run as,选择GDB。

17)可通过开关选择可以进行控制。

SW0:0--播放原始音频;1--进行音频实时fft分析;

3. 程序分析

18) 关于fft

fft ip是参考ug871进行实现的,核心是vivado自带的fft,再加上通过HLS生成的前处理和后处理的IP核,共同构成了RealFFT核(本来想单独给它生成IP的,一时未验证成功)。博主本人之前尝试着把上篇软件的fft经HLS转为IP,虽然转成功了,但是vivado综合不了,猜想是数据类型和数据量的原因以至于无法传输大批量数据。本文默认的FFT_SIZE是1024,数据量更为庞大,那么是如何处理的呢?通过使用streaming方式使FFT IP直接与cpu通信,即采用DMA IP连接RealFFT IP和CPU,从而CPU只需要对DMA进行操作即可。因此数据的输入输出只需要和DMA打交道就可以了。这里贴上代码和个人注释,以供参考。这里面使用的simpleTransfer函数,只能处理长度为32位的数据,因此本文的输入输出数据均为short类型,更为复杂的类型还需后续研究。

void RealFFT_DMA(XAxiDma *InstancePtr,short *dataIn,compx * dataOut)
{int i=0;int status;// *IMPORTANT* - flush contents of 'realdata' from data cache to memory// before DMA. Otherwise DMA is likely to get stale or uninitialized dataXil_DCacheFlushRange((unsigned)dataIn, 4 * FFT_SIZE * sizeof(short));        //refresh cache// DMA enough data to push out first result data set completely  ??why 4?why must be?why not 5,6,..?//      Request DMA transfer from PS to PL. Enough data to fill the front-end block and the FFT processing//    pipelines must be sent in order for spectral data to be ready when the PL to PS transfer is requested.//    Therefore, four data sets are sent before the first output set is requested:status = XAxiDma_SimpleTransfer(InstancePtr, (u32)dataIn,           //send enough data to DMA4 * FFT_SIZE * sizeof(short), XAXIDMA_DMA_TO_DEVICE);// Do multiple DMA xfers from the RealFFT core's output stream and// display data for bins with significant energy. After the first frame,// there should only be energy in bins around the frequencies specified// in the generate_waveform() function - currently bins 191~193 onlyfor (i = 0; i < 2; i++)           //8?2*4?    2 is ok  initial value 8 is assuring the fft out is ok{// Setup DMA from PL to PS memory using AXI DMA's 'simple' transfer modestatus = XAxiDma_SimpleTransfer(InstancePtr, (u32)dataOut,FFT_SIZE / 2 * sizeof(compx), XAXIDMA_DEVICE_TO_DMA);      //send result to PS// Poll the AXI DMA coredo{status = XAxiDma_Busy(InstancePtr, XAXIDMA_DEVICE_TO_DMA);       //wait until transfer done} while(status);// Data cache must be invalidated for 'realspectrum' buffer after DMAXil_DCacheInvalidateRange((unsigned)dataOut,                       //invalidated cacheFFT_SIZE / 2 * sizeof(compx));// DMA another frame of data to PL//Push another set of stimulus data to the PL in order to start the accelerator processing the next frame:if (!XAxiDma_Busy(InstancePtr, XAXIDMA_DMA_TO_DEVICE))         //continue sending datastatus = XAxiDma_SimpleTransfer(InstancePtr, (u32)dataIn,FFT_SIZE * sizeof(short), XAXIDMA_DMA_TO_DEVICE);printf("\n\rFrame #%d received:\n\r", i);printf("End of frame.\n\r");}printf("fft done.\n\r");fflush(stdout);printf("fft done 1.\n\r");
}

在使用时还必须注意dataIn和dataOut的类型,本文为:

 short dataIn[FFT_SIZE*4];compx out[FFT_SIZE/2];float mag[FFT_SIZE/2];

数组长度必须使用上述所示,因为设计函数时没有考虑通用性,只考虑功能实现了。(新手不容易啊~~)

为什么要乘4呢?博主认为乘其他的也可以,但是没有去验证了,它只是为了多传点数据以供处理,包括for循环也是如此,目的都是为了最终的处理数据准确,不会因为时间问题处理错了或者没来得及传出来等。对于本例的音频数据,本文处理如下:

     //====== audio value =============get_audioData(dataIn);for (i = 1; i < 4; i++)for(j=0;j<FFT_SIZE;j++)dataIn[j + i * FFT_SIZE]=dataIn[j];

19) OLED显示

本来在之前的例子中是么有这个问题的,但是由于本文采用了1024点,那么显示的时候就出问题了,因为OLED只能显示128的长度,因此必须重新写它的显示函数,而且对于音频数据,想要其显示的好看,还必须设置显示高度。经多次尝试,本文成功实现在OLED的中央显示最大幅值,两侧均匀分布。

void oled_show(float *mag)
{printf("oled_show begin \r\n");int outLED[oled_L];int i,maxi;float tmp;u8 oled_equalizer_buf[oled_L];for (i = 0; i < oled_L; i++) outLED[i] = 0;for(i=1; i<FFT_SIZE/2; i++)         //get the  max mag & its fre{if(tmp<mag[i]){tmp=mag[i];maxi=i;}//xil_printf("Cur Mag= %x MHz\r\n",mag[i]);}if(FFT_SIZE/2>=oled_L)               //the max fre will be shown in the middle{if(maxi-64<0){for(i=0;i<maxi+64;i++)outLED[i+64-maxi]+=mag[i];for(i=0;i<64-maxi;i++)outLED[i]+=0;}else if(maxi+64>FFT_SIZE/2){for(i=0;i<FFT_SIZE/2+64-maxi;i++)outLED[i]+=mag[i+maxi-64];for(i=FFT_SIZE/2;i<maxi+64;i++)outLED[i+64-maxi]+=0;}else{for(i=0;i<oled_L;i++)outLED[i]+=mag[i+maxi-64];}}else{for(i=0;i<FFT_SIZE/2;i++)outLED[i+64-maxi]+=mag[i];for(i=0;i<i+64-maxi;i++)outLED[i]+=0;for(i=0;i<oled_L;i++)outLED[i+64-maxi+FFT_SIZE/2]+=0;}oled_equalizer_buf[0]=mag[0]/2;for (i=1; i<oled_L; i++){oled_equalizer_buf[i]=outLED[i]*AMP;         //control the height
//      if(i%10==0)
//          printf("oled_equalizer_buf[%d]=%d\r\n",i,oled_equalizer_buf[i]);}OLED_Clear();OLED_Equalizer_128(oled_equalizer_buf);OLED_Refresh_Gram();//OLED_ShowString(0,0,"hello world!");
}

20) AUDIO数据获取

在"vivado+zedboard之audio驱动"一文中已经做了分析。此处就不详述了。
4. 总结

本文学习和使用了FFT、DMA等ip核,在使用audio、oled、fft前后处理等自定义ip的基础上,构建了音频分析仪的硬件部分,并在SDK中编写了控制程序,在zedboard中成功验证。可以实时显示音频频谱。关于例子本身还有诸多要优化的地方,参见上篇博文。

vivado+zedboard之音频分析仪_HW相关推荐

  1. vivado+zedboard之音频分析仪_SW

    环境:win7 64   vivado 2014.1 开发板:zedboard version d    xc7z020clg484-1 串口软件:SecureCRT 目标:对一段随机的音频信号进行实 ...

  2. vivado + zedboard 初体验

    vivado + zedboard 初体验 参考文章:https://www.cnblogs.com/rocbomb/archive/2014/07/29/3876683.html vivado:20 ...

  3. SYS-2722双域sys2722系统两级联音频分析仪

    Audio Precision 2722 音频分析仪是 Audio Precision 屡获殊荣的 PC 控制音频分析仪的旗舰型号,长期以来一直是公认的音频设备设计和测试的全球标准.全功能的 SYS- ...

  4. 实验 使用 vivado zedboard GPIO 开关 开控制 LED

    前面我做了几个实验 都没有用过 开关,这一次用一用 发现 vivado 真的挺方便 所以 使用 vivado 开发 1.建工程 我使用 vivado 2013.4 创建新工程 –> next – ...

  5. 博杰声学测试软件,音频分析仪 - Audio Precision 官方网站 - 声学和音频测试公认的标准...

    测量麦克风和声学测试配件 测量麦克风和声学测试配件 为端对端模拟,数字和声学测试启用完整的音频测量解决方案 Audio Precision提供多种测量麦克风,旨在为我们的声学测试工作人员提供便捷的解决 ...

  6. s6和thinkpad x1音频对比 (APX 音频分析仪)

    目的 对比s6和thinkpad x1音频的优劣. 测试仪器: APX555 测试内容: 1.      频率响应 2.      频率 3.      信噪比 4.      失真率 5.      ...

  7. 电声测试仪 音频分析仪 rta噪声频谱分析仪 噪音计 声压级表 麦克风录音系统动态范围 音频采集系统输入动态范围 噪声 最大声压级 放大器增益

    这部分来自我的免费电子书<音频测量指南>beta版本,可能存在错误,可能会更新,因为我的健康状况我不做保证.如果有人可以修正数学计算的部分我会非常感激. 问:为什么我买了一个麦克风,自我噪 ...

  8. linux fpga 开发环境,- Vivado+Zedboard之Linux开发环境搭建

    自行编译任意版本的方法: 下载Qt-lib源码包,此处以qt-everywhere-opensource-src-4.7.3.tar.gz为例 注意前面两步是可选的.因为后续我们建立的Qt-ZYNQ库 ...

  9. 声音分析+android,声音分析仪Sound Analyzer-声音分析仪 Sound Analyzer2.1安卓版-蜻蜓手游网...

    可让您将智能手机用作声级计(SLM)和实时音频分析仪(RTA).可以实时监测以分贝(dB)测量的环境噪声.麦克风灵敏度可通过校准菜单进行调节. 没有广告,横幅或弹出式窗口的应用. 作为声表的特点(分贝 ...

最新文章

  1. Entity Framework 实体关系总结:one-to-one, one-to-many, many-to-many
  2. php的数据校验,php 数据类型校验函数的简单示例
  3. mysql中sum (if)_mysql 中sum (if())
  4. IOS15使用Masonry和自动计算Cell的高度
  5. html css 核心设计理念
  6. 玩转oracle 11g(37):rman备份-数据库指定文件恢复
  7. 6. A Deeper Understanding of Deep Learning
  8. win7设置计算机临时用户,Win7小技巧:用户账户自动登录方法汇总
  9. element-UI组件el-button样式覆写 - 生效篇
  10. springboot 集成quartz带数据库持久化
  11. java获取本机的外网IP地址(亲测有效)
  12. Google浏览器被劫持解决方法
  13. JQuery使用及基础原理解析相关笔记(一)
  14. 提升睡眠质量的助眠好物,拥有这些,不再担忧睡眠质量
  15. linux配置iscsi无账号密码,linux iscsi Initiator配置CHAP认证
  16. java 生成电子合同_java实现电子合同签名
  17. MySQL系列:innodb源码分析之表空间管理
  18. 怎么选择好的便宜云虚拟主机?分享挑选便宜云虚拟主机的小技巧
  19. 周鸿袆:360回归A股不是为炒股 是出于国家安全考虑
  20. ASP.NET MVC3 技术(五) JSON 数据的传递

热门文章

  1. 燕麦云何洋开讲 | 既安全又简单?我的产品设计心经分享(上)
  2. snm算法_基于SNM算法的大数据量中文地址清洗方法-计算机工程与应用.PDF
  3. 从UCSC下载基因组的GTF文件
  4. fatal unable to access ‘httpsgithub.comnhnraphael.git‘ OpenSSL SSL_read Connection was rese
  5. java中的 @Seria注解是什么意思
  6. Data Integrity For JEDEC DRAM Memories
  7. Galera Cluster for MySQL 详解(四)——性能测试
  8. Linux分配home的磁盘空间给根目录
  9. DBR分区表详解(FAT)
  10. MMEngine理解