本文以ARM EP7312和CS5341为核心设计了音频信号采集系统,研究了嵌入式Linux系统的驱动程序设计和基于多线程、模块化的应用程序设计问题。该系统能够对采集的信号进行FFT变换、存储和显示。
在工程应用中,通过数字采集系统对信号进行采集和显示,可以获取直观的时域波形。但往往人们还需要从时域信息中提取出信号的其它特征,如信号的频域信息。本设计通过数据采集电路对模拟信号进行采集,采用512点的时间抽取基2 FFT算法对采集的数据进行处理,然后在LCD上显示其频谱曲线。系统构建于嵌入式Linux操作系统之上,具有嵌入式设备体积小、成本低、功耗低等特点,可便捷地进行语音采集、显示、处理和声音信号的频谱分析,适用于环境监测及故障诊断等场合。
图1 系统构成图
图2 多线程程序流程图
图3 信号的时域图和频谱图
数据采集电路设计
本系统由模数转换模块、数据处理和控制模块、显示模块这三部分组成,如图1所示。
模数转换芯片采用的是Cirrus Logic公司推出的24位两通道立体声模数转换芯片CS5341,其输出为串行形式,采样频率从32kHz 到192kHz。它有主从两种工作模式,由主从模式选择开关进行选择。
数据处理和控制模块采用了ARM7系列的嵌入式32位EP7312处理器,主频为74MHz。
在该设计中,模拟信号经过放大电路可放大为原来的1倍、2倍、4倍或10倍,具体可由放大倍数开关控制。放大倍数通过EP7312的通用端口控制LCD上每个刻度代表的电压值。CS5341的工作模式为从模式,在该模式下主时钟、串行数据时钟和通道选择时钟都由EP7312提供,串行数据时钟的频率为通道选择时钟的64倍,主时钟频率为通道选择时钟的256倍。当串行数据时钟处于上升沿时,CS5341输出一位数据。通道选择时钟高电平时左通道有效,低电平时右通道有效。
系统的软件设计
系统的软件设计包括驱动设计和应用设计两部分。
驱动设计
在嵌入式Linux系统中,设备驱动程序隐藏了各种设备的具体细节,维护着设备的正常工作,在用户与设备之间起到了桥梁作用。开发设备驱动程序是开发嵌入式系统的重要工作之一。在该系统中,涉及两个驱动程序:CS5341驱动和LCD驱动。EP7312为LCD的控制提供了良好的支持,驱动程序的具体设计可参照参考文献3。
下面介绍CS5341驱动程序的设计。由于CS5341数据采集速度较快,最高达192kHz。为了与其相匹配,我们采用了快速中断fiq。与普通中断不同,快速中断模式有专用的组合寄存器集,因而大大减少了中断时间。而快速中断的申请需要用到中断处理函数的首地址和末地址,为了得到这两个地址,中断处理函数必须用汇编来编写。因此,该驱动有两个文件构成:主文件cs5341.c和中断文件fiq.s。在此着重说明主文件中的设备初始化函数cs5341init()和中断函数。
int CS5341Init(void)
{
..................................
//禁止中断
INTMR3 = 0x0;
//设置相关寄存器
SYSCON3 |= 0x00000008;
DAI64FS = 0x60B;
DAIR =0x00220404;
DAISR =0xFFFFFFFF;
DAIR |=0x10000;
...................................
//注册设备
rc= register_chrdev (cs5341_major, "CS5341", &CS5341_fops);
...................................
//申请fiq
fiqhandler_start = &dai_fiq_handler_start;
fiqhandler_length = &dai_fiq_handler_end - &dai_fiq_handler_start;
if (claim_fiq(&cs5341_fh))
{
printk("cs5341_fh: couldn't claim FIQ.\n");
return;
}
set_fiq_hander(fiqhander_start, fiqhander_length);
set_fiq_regs(regs);
..................................
return 0;
}
中断处理程序:
.....................................
.text
.align 2
.global dai_fiq_handler_start
.global dai_fiq_handler_end
dai_fiq_handler_start:
//程序首地址
........................................
........................................
dai_fiq_handler_end:
//程序末地址
应用程序设计
该系统的应用程序设计主要包括数据存储、数据处理(FFT)和波形显示。
数据存储
在该模块中,申请两块缓冲区buf和buffer,buf用来存放采集的数据,buffer为临界资源。程序把数据从buf放入临界资源buffer中,设置一个共享锁,实现该模块、数据的处理和显示模块的互斥访问。
数据处理模块
该模块采用FFT算法对采集的数据进行处理。
FFT变换的具体实现如下:
首先进行码位倒置,得到FFT运算所需要的输入序列。然后采用3层循环完成N点FFT(这里N=512)。
第一层循环:“级”作为第一层循环,N点FFT运算共有M级,这里,我们用m作循环变量,。
第二层循环:“组”作为第二层循环,第m级的组数为,用j作循环变量,。
第三层循环:每组里的蝶形单元作为第三层循环,每一组里共有蝶型单元2m个,用i作循环变量,。
分析上面循环可以得出:第三层循环完成2m个蝶形单元计算;第二层循环使第三层循环进行次,因此,当第二层循环完成时,共进行次蝶形单元计算;第一层循环又使第二层循环进行了M次,因此,当第一层循环完成时,共进行了次蝶型单元计算。
波形显示模块
因为要把处理前的数据和经过FFT处理后的数据同时显示在LCD上,所以,把LCD的上半屏分配给未处理的数据,用于显示时域图;下半屏用于显示频谱图。为了把波形显示在特定的区域,需要对数据进行处理。所采集的数据和FFT变换过的数据的范围均为0~0XFF,0对应于LCD上Y轴坐标的120和210,0XFF对应于LCD上Y轴坐标的30和120。因此,用于显示时域图的数据VAL与其在LCD上Y坐标的关系式为:
Y=120-VAL×90/0XFF
用于显示频谱图的数据NUM与其在LCD上Y坐标的关系式为:
Y=210-NUM×90/0XFF
LCD一屏可显示310个数据点,点与点之间用矢量法直线相连。
多任务操作系统下的编程
与传统的单片机系统不同,Linux是一个多任务的嵌入式操作系统。内核允许将一项工作划分为几个相互独立的任务,这样就缩短了整个系统的响应时间,提高了系统性能。
在设计时采用了多线程的编程方式,从而克服了多进程编程中资源占用量多和响应时间慢等缺点。该程序包括三个线程,流程图如图2所示。主线程负责数据的采集和传输,另外两个辅助线程是在主线程的运行过程中产生的,分别完成数据的处理和波形的显示。
当输入信号的频率为0.377kHz (周期为2.65ms)时,该信号的时域波形及频谱曲线如图3所示。从图中可以看出,通过FFT变换,输入信号的频率特性可以较准确地反映出来。
结语
以EP7312处理器和模数转换芯片CS5341为核心构成的数据采集系统,充分运用了它们在音频采集和处理方面的优势,可以对音频数据流进行实时性的采集、变换、存储和显示,具有速度快、采样频率高、体积小和低功耗等特点。以该系统为核心技术开发的产品可应用于医疗、运输、娱乐等行业,具有广泛的应用前景。