本帖最后由 znmcu 于 2012-9-3 08:53 编辑
============================================
振南的znFAT 单片机上的FAT32文件系统
关注znFAT 加入QQ群 106889506
============================================
源代码下载:
430.zip
(562.41 KB)
znFAT移植与应用手册:
znFAT移植与使用手册.pdf
(285.28 KB)
============================================
实验演示视频:
1、 http://v.youku.com/v_show/id_XNDQ2MDczNTYw.html
2、 http://v.youku.com/v_show/id_XNDQ2MDcyMDM2.html
3、 http://v.youku.com/v_show/id_XNDQ2MDcwMTY4.html
============================================
wav文件,想必很多人都很熟悉,它被称为“波形文件”,用于存储音频数据。Wav这种音频格式记录的就是原始的声波信号的采样电压(PCM),因此我们可以把它的数据直接送到DAC,就可以播放出声音,而不需要任何的解码。
wav文件的缺点是数据量比较大,这是因为它的数据没有经过压缩处理(其实有些wav文件也是经过压缩的,压缩算法是ADPCM,不过它的压缩强度比较弱,远比不上像MP3或WMA那样的高强度压缩算法)。
这里我们就使用
MSP430 单片机来作一个wav音频播放实验,DAC芯片使用TLC5615(430单片机的型号为F149,它没有片内DAC,F16X的芯片有)。wav文件的存储我们使用SD卡。
如何从SD卡中读取WAV文件?这将涉及FAT32文件系统的相关内容。要正确的读到文件的数据,我们就必须遵循FAT32文件系统的格式协议。FAT32文件系统是比较复杂的,在编程实现上难度是很大的。振南长期研究和编写的znFAT,其实就是在实现对FAT32文件系统的各种文件操作。通过它,可以轻松完成对文件数据的读取。
文件数据的读取其实是此实验的一大重点,也是难点。除此之外的工作其实就比较简单了,直接把读到的数据“扔”给TLC5615即可。
把数据送给TLC5615还原为电压,进而拟合出声音信号。这里有一个问题!一个是采样频率、另一个是采样精度。采样频率是指每秒对原始声波信号的采样次数,比如一个wav文件的采样率为16kHz,即每次采样16000次。我们在将数据送给DAC芯片TLC5615时,自然也要按照这个频率,否则声音将或快或慢,造成失真。很显然,声音采样频率越高,wav文件的数据量也就越大。另一方面,采样精度也影响着数据量的大小,采样精度其实就是在对原始声音信号进行采样时所使用的ADC的位数,比如8位、16位、24位等。当然,这个位数越高,数据量就越大,同时声音的质量也就越高。综上所述,如果一个wav采样频率高,同时采样精度也高,那么它可能就是一个具有高保真音质的文件了。
我们希望我们的“wav音频播放器”可以放出最好的声音,究其实质是对原始声音信号还原的能力较强。这就需要一个音频质量较高的wav文件,这样一个问题又产生了:“wav的数据量如果比较大的话,我们实际读取文件数据的速度能不能跟得上?”
MSP430单片机是以超低功耗著称的,但在一定程度上它是以牺牲主频和速度为代价的!这注定了,在MSP430单片机上,我们可能达不到太高的数据读取速度。采用IO模拟SPI驱动SD卡,8M的晶振,实际测得的数据读取速度为25KB/S。在这种情况下,我们只能酌情降低一些wav文件的质量。我们采用4KHz的采样率、8位采样精度,单声道。这样的音频质量可能不会太好,但起码能有一个差不多的声音出来。我们这也只是一个测试性的实验!
实际,如果你想作出高质量的声音,就请换用更高性能的CPU,更好的DAC,当然还有高质量的wav文件。
现在的问题又出现了:“到哪里去获取4K采样率、8位精度的单声道的wav音频文件呢?”我们可以使用cooledit软件来进行转换。
实现的主要代码(znFAT读wav文件数据送给DAC的实现采用znFAT的数据重定向功能,而非通过缓存中转方式)。
int main(void)
{
//IO设置
UART_Init();
znFAT_Select_Device(0,&Init_Args); //选择设备
res=znFAT_Init(); //文件系统初始化
//输出文件系统相关信息
if(!znFAT_Open_File(&fileinfo,"/test.wav",0,1)) //打开wav文件
{
//输出文件相关信息
znFAT_ReadDataX(&fileinfo,0,fileinfo.File_Size); //数据读取,通过重定向直接送向TLC5615
}
znFAT_Close_File(&fileinfo);
znFAT_Flush_FS();
return 0;
}
硬件实验平台:
|