zoukankan      html  css  js  c++  java
  • miniSTM32开发板使用LCD12864模块并播放wav音乐

       最近忽然想起了前几年学习51单片机时有一个大名鼎鼎的12864模块没有使用,原因是当时使用的程序模块驱动有问题,也没有深究。然而我买的这个模块是V2.0版,带有中文字库,还是很实用的,因此我打算在STM32开发板上试一下看看效果如何。首先我找出了《新概念51单片机C语言教程——入门、提高、开发、拓展全攻略》这本书,参考里面的12864模块驱动程序,结果很顺利,除了端口初始化外,几乎不用做任何改动就可以在miniSTM32开发板上使用。

           然后我打算做一个试验,参考正点原子的例程识别SD卡,读出第一个扇区的内容并通过串口输出。

            12864模块的接线方式(管脚1为正面右起第一个引脚,采用串行接线方式):

                引脚1     VSS  --  GND                        模块电源

        引脚2     VDD --  +5V                          模块电源

                引脚4     RS(CS)   --  PB8                   串行片选

                引脚5     R/W(SID)   --  PB9                串行数据

                引脚6     E(CLK)   --  PB10                  串行时钟

                引脚15    PSB   --  GND                      高电平为6800通信,低电平为3线SPI通信

                引脚19    BLA    --   +5V                       背光电源

                引脚20    BLK   --    GND                     背光电源

    SD卡模块的接线方式:

    引脚1 CD/DAT3 (SPI模式CS) -- PA3

    引脚2 CMD(SPI模式MOSI) -- PA7

    引脚3 VSS

    引脚4 VCC

    引脚5 CLK(SPI模式CLK) -- PA5

    引脚6 VSS

    引脚7 DAT0(SPI模式MISO) -- PA6

    引脚8 DAT1

    引脚9 DAT2

         要点和注意事项:

    1)由于液晶模块对电压的波动很敏感,为了保证显示效果,这里的引脚大部分都是焊接的,杜邦线的效果就和面包板上的引线一样连接不太可靠。

    2)由于使用SPI1外设读取SD卡时使用了PA3,PA5,PA6,PA7引脚,其他外设就不能再使用这几个引脚了。 

          下面的图片是试验结果 :

     

         

    这是从SD卡0扇区读出的内容,最后两个字节是55AA


     

    很多从51单片机开始学习的新手估计对文件系统有一种神秘感,通过正点原子的例程我也是首次接触到FatFS文件系统,这个文件系统已经在嵌入式领域广泛使用,主要包括ff.c, ff.h, ffconf.h, diskio.c, diskio.h等文件,初学者先仔细看看ffconf.h,ff.h和diskio.h三个头文件就能对FatFS文件系统有一个初步印象以便消除陌生感。这里的试验内容是使用FatFS读出SD卡中的所有文件,并以目录名/文件名的形式通过串口打印出来,同时找出其中的歌曲并显示到12864模块上。

     

         要点和注意事项:

    1)要找出SD卡中的所有文件,首先要为SD卡工作区申请内存,然后挂载SD卡磁盘到0:分区。接着使用f_opendir()和f_readdir()函数从根目录开始递归扫描,

     通过分析FILINFO中的fattrib属性,如果是目录则切换目录继续扫描,如果是文件则输出路径+文件名,如果使用f_typetell()函数发现文件是音乐则输出文件名到12864屏幕。

    2)由于Fatfs文件系统默认的长文件名长度为255,如果递归扫描磁盘的文件会消耗较多的内存,为了节约内存,长文件名默认长度可以改为30左右。

     

          下面的图片是试验结果 :

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     


     

     

    接下来我打算使用SPI1和Fatfs文件系统读取SD卡中的歌曲,然后通过定时器TIM3的通道1和通道2以PWM波形的方式播放wav音乐,定时器TIM3的比较值就是读取到的wav的数据,由定时器TIM2的中断来更新。歌曲的采样率决定了预装载值arr和预分频系数psc的乘积,即psc X arr = 72000000/采样率,如果是8bit音乐要保证arr>=256,如果是16bit音乐要保证arr>=2048(11bit)。由于网上关于使用PWM方式播放wav文件的相关信息不太多,因此有很多细节需要自己摸索排查。经过几天的努力也参考了网上不少文章(比如DAC方式播放wav的文章),终于播放出音乐,目前采样率为11025的8位wav音乐播放的效果一般,杂音也比较明显。

     

    要点和注意事项:

    1)歌曲缓冲区buffer的使用分为前后两个半段,具体来说假设buffer长度为4096,当前半段的数据写入CCR1到2048位时,则读文件标志ready置1,前后段标志位flag则取反,当读取到4096位时也是ready置1和flag取反。while循环中如果ready为1,说明需要读文件了,如果flag为1则将读到的数据放入buffer前半段,如果flag为0则将读到的数据放入buffer后半段。总之buffer读操作和写操作总是前后两个半段错开。

    2)要想播放wav歌曲,首先需要熟悉WAV文件的格式,我在网上找到了一个使用ALSA音频库播放WAV的程序alsa_play.c,可以先在pc上用此程序播放wav音乐,以便熟悉WAV文件头。另外为了熟悉使用TIM3定时器的PWM功能,可以先做一个呼吸灯。 

     3)由于SPI1读取SD卡用到了PA5,PA6,PA7引脚,而TIM3通道1和通道2的默认输出引脚是PA6,PA7,如果采用半重映射到PB4PB5,需要禁用JTAG/SWD,故采用完全重映射到PC6PC7,并且在端口配置时需要使能AFIO时钟。

    4)在播放WAV音乐时发现采样率是音质的关键,如果使用16bit数据,由于需要截断到12bit或11bit效果并不好,对于STM32如果使用单声道8bit,可以使用44100Hz的采样率。

    5)在调试过程中发现像LED0=1这类使用宏的语句容易出问题,我这里引起的问题是中断服务程序卡死,另外一开始我想把buffer定义为u8 *buffer[2],使用时也可能出问题,希望自己在嵌入式领域要注意C语言用法的规范。

    6) 最后切记对于8bit(包括单声道和双声道)wav文件,读取到的音频数据要减去0x80,如果觉得音量太大,可以再除以2以降低音量。

     

    以下是采用PWM方式播放的《我和我的祖国》百度云链接(在尝试采用DAC方式播放后发现音质更好但要接有源音箱):

    链接: https://pan.baidu.com/s/10nap5aZC1IEWXQD_UoGu3g 提取码: zmc6

    以下是DAC方式播放WAV音乐的项目源码: 

    链接: https://pan.baidu.com/s/1QlucA0IVGA8iHdaa7vOt0g 提取码: 7pgn

  • 相关阅读:
    httpclient用法
    JS逻辑运算符&&与||的妙用
    jackson详解
    MVC +EF+linq 多表联查
    Log4net 集成到MVC+EF框架
    Asp.net中的页面跳转及post数据
    字符串的分割操作
    线程的信号机制
    事件的标准模式
    Java网络编程
  • 原文地址:https://www.cnblogs.com/yangjd/p/13832179.html
Copyright © 2011-2022 走看看