【STM32本科毕业设计】基于STM32的多功能MP3播放器设计

目录

一. 概述

本设计课题是一个软硬件相结合的设计类题目。要求设计一个基于STM32F103的多功能MP3。可以实现MP3播放的基本功能,同时拥有丰富并实用的外扩功能,整个系统的功能包括:\

  • MP3播放功能
  • 收音机功能
  • 图片播放功能
  • 温度计功能
  • 彩色台灯功能
  • 功率放大功能
  • 万历年功能
  • 闹钟功能
  • 游戏功能
  • 电子书功能

整个系统主要由音频解码部分、收音机部分、音效处理部分、SD卡部分、功率放大、电源部分、人机交互等几个部分组成,整个系统由一块MCU(STM32F103RBT6)控制运行,各个部分协调运作,人机交互部分采用LCD和触摸屏实现,输出部分采用2.4寸的240*320的彩色液晶实现,输入部分主要采用触摸屏实现。

整个系统涉及方面很多,颇具挑战性,主要难点在与FAT文件系统解析,JPEG/BMP数据格式解析,触摸屏控制等。针对本系统的特点,采用各个击破的方法,来一步步实现以上功能。最终实现整个系统的功能。

二. 系统硬件设计

2.1 整体设计思路

由于该多功能MP3要实现图片浏览和mp3播放这两大功能,对ram和处理速度的要求比较高,首先对图片的解压缩要用到的ram比较多,其次,对MP3的播放,处理起来速度是有要求的,尤其对320Kbps的MP3格式数据流的处理,必须非常快,才能实现MP3的流畅播放。可供选择的八位机有AVR,PIC等,可供选择的32位处理器有SAMSUNG,NXP,STM32,ATMEL等。

首先要有丰富的RAM,八位机主要靠扩展,内部RAM一般在4Kbyte以内,更多的RAM得靠外扩,32位机里面,SAMSUNG一般不内带RAM,也要外扩,对于这个设计,当然成本越低越好,外扩RAM,FLASH芯片必然加大成本。所以控制芯片最好拥有自带的FLASH和RAM。

其次,由于本系统要播放MP3音乐和JPEG图片等,而两种格式的文件往往比较大,所以存储媒介也就有要求了,可供选择的有FLASH芯片,如SAMSUNG公司的K9F系列,还有SD卡,U盘等。如果选择FLASH,则整个系统要求较多的IO口来读取,更重要的一点是,这样做的后果就是整个系统的容量就被固定了,扩容存在困难。而U盘和SD卡都是不错的选择,但是SD卡相对于U盘,读取容易,而且相同容量的U盘和SD卡,SD卡的价格较低。所以系统选择SD卡作为存储媒介。

第三,系统播放MP3要同时读取SD卡和VS1003,都要用到SPI口,所以控制芯片最好有两个SPI,这样不用复用,可以提高速度。

第四,彩色台灯的控制需要通过PWM调制,来实现调光,所以,控制芯片还要有至少3路的PWM输出。

通过以上分析,本系统选择STM32作为控制芯片,STM32是ST公司最新推出的基于Cortex-M3构架的STM32F103RBT6芯片。

采用STM32F103RBT6作为控制核心,该芯片具有6通道的16位PWM输出,RTC时钟,两个高速SPI,两个IIC,三个串口,自带USB和CAN接口。具有128K flash和20K 的SRAM,对本系统来说足够了,同时以后还有很大的升级空间。

2.2 硬件器件的选择

在系统实现的时候,硬件选择是很重要的一部分,上面已经选取了控制芯片,剩下的就是选择其他芯片,来实现相应的功能了。下面我们重点分析系统相关其他芯片的选型。

2.2.1 MP3解码芯片选择

由于使用了ARM处理器,MP3的解码可以有两种方法,一是通过ARM处理器软解码,通过对MP3数据格式的解析实现MP3播放,二是通过外部解码芯片直接解码。

第一种方法对处理器运算要求高,在解码高码率的MP3时,ARM7的处理能力吃紧,也就是说得不到好的解码效果,更重要的是STM32解码之后还需要外部的DAC来做音频输出。所以采用后者。

MP3解码芯片常见的有VS100X系列,和STA01X系列,VS系列自带DAC输出,而且能解码的格式也比较多,而STA系列要外加DAC,比较麻烦。

经过对比,本系统MP3解码选择VS1003,该芯片支持MP3、WMA、WAV、MIDI等格式的解码,自带DAC输出。同时还可以调节音量高低音等,更重要的是它还具有MIC功能,有需要的话,可以实现录音功能。这点可以作为以后扩展功能的一部分。

2.2.2 收音机芯片选择

本系统的收音机功能只针对FM收音,采用TEA5767芯片实现,TEA5767是飞利浦公司生产的一款低功耗电调谐调频立体声收音机芯片,其内部集成了中频选频和解调网络,可以做到完全免调,因此只需要很少量的小体积外围元件。TEA5767可以应用在欧洲、美国和日本不同的FM 波段环境。该芯片通过IIC总线控制该模块,就可以实现调频接收,频率覆盖范围从76~108MHz,而且是立体声接收,带信号强度指示。TEA5767在市场上占有率很高,一般的MP3机/手机的收音机功能都是用的这块芯片实现的。

但是由于芯片体积很小,焊接难度比较大,故直接采用模块,TEA5767模块的体积小,价格低,而且使用方便。这样不但可以节省时间和成本,而且效果也是相当好的。

2.2.3 温度传感器选择

该系统具有温度指示功能,用来指示当前温度,因为日常温度的范围一般是-20~50℃以内,所以,温度传感器要能在这个范围内给出正确的温度。

经过分析,选用美信公司的单总线数字温度传感器DS18B20,该数字温度传感器将检测的温度信息转化为相应的数字量,独特的一线接口,只需要一个IO口线就可以读写该器件了。简化了分布式温度传感应用,并且无需外部元件可用数据总线供电,电压范围为3.0 V至5.5 V,无需备用电源。该芯片的测量温度范围为-55℃至+125 ℃ 。在 -10 ℃至+85 ℃范围内精度为±0.5℃。

2.2.4 彩灯驱动芯片选择

本系统采用3W的共阳RGB三基色LED来作为彩色台灯的光源,红绿蓝每个灯芯功率为1W,因为这种LED的驱动电压一般为3.3V左右,然后以每个通道1W计算,则每个通道电流为300ma左右。同时由于系统采用STM32控制,其IO口的电压为3.3V,还要使用PWM调光,开关频率较高,对驱动芯片的选取比较严格。

经过分析采用AP2306来驱动,3.3V电压采用LM2576来获得。LM2576为美国国家半导体公司生产的3A电流输出降压开关型集成稳压电路,它内含固定频率振荡器(52kHz)和基准稳压器(1.23V),并具有完善的保护电路,包括电流限制及热关断电路等,利用该器件只需极少的外围器件便可构成高效稳压电路。

得到3.3V驱动电压之后,通过控制AP2306来调节LED亮度,AP2306为低压驱动的N型MOSFET,它具有极低的导通电阻和栅极电压,在Vgs=2.5V时,可以提供2.6A的输出电流,此时的导通电阻为50 mΩ。满足上面的要求,并且在AP2306上消耗的功耗非常低。

2.2.5 音效处理芯片选择

VS1003已经自带了音效处理,但是其效果不是很好,而且无法对外部音源经行音效处理,这样外部音源和收音机的音源就得不到处理,所以,本系统通过一块外部数字音效处理芯片来进行音效处理。

本系统总共有3个音源:MP3音源、收音机音源、外部输入音源。所以音效处理芯片最好有多个音源选择功能,否则又需要外扩音源选择芯片,通过选择,这里选择PT2314作为音效处理芯片。

PT2314是一个具有四组立体声输入的双声道数字音质处理器,PT2314将音量、音调(bass and treble)、声道平衡(left/right)、响度等处理及输入增益选择内建于单一芯片中。这些功能令PT2314仅需要少数外部组件即可实现高效能的音质处理系统。所有功能均由I2C总线来达成控制。当启动时的设定状态,音量为-78.75dB,输入声道为四通道立体声,所有扬声器输出皆为静音,输入增益、Bass、Treble皆为0dB。

2.2.6 EEPROM芯片选择

本系统需要保存部分用户数据,而STM32内部没有EEPROM,所以一旦掉电,系统数据会全部丢失,这就需要通过外扩EEPROM芯片来实现用户数据的保存了,EEPROM芯片有很多可供选择,比如ATMEL的24CXX系列,本系统选择美国Ramtron公司的新一代FRAM铁电存储器FM24C16,这个芯片为用户提供2Kbyte的用户数据存储空间。

美国Ramtron公司铁电存储器(FRAM)的核心技术是铁电晶体材料。这一特殊材料使铁电存储器同时拥有随机存取记忆体(RAM)和非易失性存储器的特性。铁电晶体的工作原理是:当在铁电晶体材料上加入电场,晶体中的中心原子会沿着电场方向运动,达到稳定状态。晶体中的每个自由浮动的中心原子只有2个稳定状态,一个记为逻辑中的0,另一个记为1。中心原子能在常温、没有电场的情况下,停留在此状态达100年以上。铁电存储器不需要定时刷新,能在断电情况下保存数据。由于整个物理过程中没有任何原子碰撞,铁电存储器有高速读写、超低功耗和几乎无限次写入等特性。铁电存储器和EEPROM比较起来,主要有以下优点:
(1)FRAM可以以总线速度写入数据,而且在写入后不需要任何延时等待,而EEPROM在写入后一般要5~10ms的等待数据写入时间;
(2)FRAM有近乎无限次写入寿命。一般EEPROM的寿命在十万到一百万次写入时,而新一代的铁电存储器已经达到一亿个亿次的写入寿命。
(3) EEPROM的慢速和大电流写入使其需要高出FRAM 2500倍的能量去写入每个字节。

2.2.7 功率放大芯片选择

本系统包括两块放大芯片,第一块用来放大从PT2314输出的音频信号,以驱动耳机,而另一块是功率放大,用来驱动喇叭。

第一级放大的选择有很多,比如TPA152,TDA2822等,但是前者对比后者有很多优势,TDA2822的音质失真较大,THD为10%左右,而TPA152在32Ω负载的情况下THD只有2%,在10KΩ负载的时候就只有不到0.01%了。而且TPA152的输出功率较TDA2822也较大,达到了1.5W的总输出。因此,这里选择音质较好的TPA152芯片,作为耳机驱动。

由于考虑到家用,又具有这么多功能,功率放大不宜做的很大,尤其作为台灯使用时候,摆设在床头比较合适,所以功率放大采用体积小巧,不需要散热的D类功放,TPA3100D2。

TPA3100D2是德州仪器生产的一款高效率的20W立体声D类音频功率放大器,工作电压10V-26V,每路能从18V电源向8欧姆负载提供20W,从12V电源向8欧姆负载提供10W, 从12V电源向4欧姆负载提供15W,效率高达92%,不需要散热器,有四个可选择固定的增益设定,增益可选择为20/26/32/36dB,差分输入,具有自动恢复生产功能的热关断和短路保护,时钟输出可用于对其它D类器件的同步,48引脚7x7mm HTQFP封装。输出功率大,体积小巧,因此,满足本系统要求。

2.2.8 电源芯片选择

本系统要求多个电压输入:2.5V,3.3V,5V,12V,所以对电源的处理需要多个芯片,对以上几个电源可以分为两组:功率电源和系统电源。

功率电源主要包括给彩色台灯供电的电源和给TPA3100D2供电的电源。TPA3100D02的功率电源采用外部电源(DC12V)直接输入,并不经过稳压芯片,而彩色台灯的电源必须是3.3V,所以要经过稳压芯片,这里选择LM2576-3.3V。对于LM2576上面已经有分析,这里不再介绍。

系统电源主要包括给数字芯片供电的电源包括2.5V,3.3V和5V,这些电源功率不大,采用REG1117-2.5和REG1117-3.3V稳压芯片提供2.5V和3.3V的电压。REG1117可以输出800ma的电流,足以满足要求。

对于5V输入,仍然采用LM2576,第一是因为整个系统的数字部分电源都是来自5V的,其上的电流比较大。更重要的是,直接从12V降为5V,如果采用一般的线性稳压芯片,则功耗会很大,采用LM2576开关型集成稳压电路,则可以显著降低功耗。

2.2.9 人机交互设备选择

人机交互设备包括输入设备和输出设备,对于输出设备,因为系统具有电子相册的功能,这就决定了,必须采用彩色液晶屏幕,这里选择一款2.4寸的TFT液晶屏,其分辨率为240*320,65K色,工作模式为8位数据模式,与MCU的通讯所需IO口较少,速度也较快。

输入设备为了使控制方便,人性化,采用触摸屏控制,触摸屏采用电阻式的4线模拟屏。控制简单,效果好。触摸屏的控制芯片选择ADS7846,ADS7846是TI(BB)公司生产的12位四线触摸屏控制芯片,因为该芯片是12Bit精度,所以可以提供的水平和垂直分辨率均为4096,而屏幕大小为240*320,所以,有很高的分辨率,有利于屏幕控制精度的提高。

2.3 硬件系统框图

经过上两节的分析可知,整个硬件系统由一个STM32F103RBT6控制器控制。各个模块电路在下面将有详细介绍,这里给出整个硬件系统框图,如图所示。

硬件系统框图:
图2.1  硬件系统框图
方框图给出了各个模块与MCU的连接关系,由于电源和功率放大器不受MCU的控制,故在方框图内没有画出。从上面的方框图可以看出,整个系统以STM32F103RBT6为核心,通过控制各个模块的工作,使整个系统达到预定的功能。

2.4 硬件模块化原理图设计

在本节中,将根据上一节的硬件系统框图进行具体的硬件设计。整个硬件系统可以分为若干个模块。下面对这些模块经行逐一介绍。

2.4.1 MCU和DS18B20模块电路设计

MCU为整个系统的核心,控制着整个系统的运行,让MCU稳定的运行是非常必须的,下图为MCU的原理图:
在这里插入图片描述

包括一个后备电源UPS1,一个主电源VCC3.3和一个模拟电源,模拟电源通过从VCC3.3加滤波电路得到。MCU外围的必须电路由滤波电容,下载电路(串口1)以及复位开关组成。同时,考虑到系统需要时钟功能,给时钟部分增加了后背电源电路,通过二极管连接到VBAT脚,给实时时钟供电。这里采用了双电源结构,即在电源有外部供电的时候,后备电池不给时钟供电,时钟的电源来自外部,只有当外部电源断开的时候,后备电源才给时钟供电,以保持时钟的计时,这样可以延长后备电池的使用时间。

同时,为了调试方便,下面电路还加了一个多余的按键和LED灯,方便在调试的时候使用。并且,考虑到某些模块对速度的要求,特意对MCU的IO口做了安排,这样虽然增加了布线难度,但是提高了执行速度,还是值得的。对多余IO口的安排,则是全部引出,方便以后扩展其他功能,比如:家电控制等。同时,对于STM32F103RBT6自带的USB接口,也已经引出,日后通过升级,可以实现USB控制的功能。

这里要注意一点:因为PT2314,TEA5767,FM24C16这三个器件都是使用IIC总线控制的,所以,把这三个器件挂在一个IIC总线上,节省了IO口。

温度传感器DS18B20的电路比较简单,通过一个简单的RC滤波给其供电再通过一个普通IO口连接到MCU上,实现MCU和DS18B20的连接。

2.4.2 MP3解码模块电路设计

MP3解码采用VS1003解码芯片,该芯片能解码MP3、WMA、MIDI、和WAV格式的音频文件,同时还支持录音功能,本系统中暂未用到这个功能,但是对其音频录音的电路保留了下来,方便日后升级。整个模块电路如图所示。

MP3解码模块电路:
在这里插入图片描述
对于VS1003,由于其既有模拟电源又有数字电源,且对音质有直接影响,所以,本模块中使用了大量滤波和去耦电容有的采用了LC滤波,为VS1003工作提供了稳定的外部条件。

2.4.3 收音机模块电路设计

由于本系统直接采用TEA5767的收音机模块来实现收音机功能,所以使得其外部电路大大简化,只要通过少数的几个元件就能实现收音机功能了。电路原理图如图所示:

收音机模块电路:
在这里插入图片描述

2.4.4 SD卡模块电路设计

由于MCU没有专门的SD卡模式接口,只能通过SPI模式访问SD卡,电路图如图所示:
在这里插入图片描述
因为SD卡使用的SPI模式,所以把SD卡挂接在MCU的SPI2上面。SD卡的SPI通信必须在每个IO口都用一个40K左右的上拉电阻,这里选择45K。SD卡的电路比较简单只要连接无误,一般都没有问题。STM32的SPI口在72M时钟的条件下,SPI时钟速度可以达到惊人的18M,也就是SD卡的读写速度最快可以达到2.25Mbyte/s。足够播放任何音频格式了。

2.4.5 音效处理模块电路设计

我们选择的是PT2314作为音效处理芯片,电路图如图2.6所示,PT2314支持最多四个输入通道,这里我们用了其中三个,通道2对应收音机音源,通道3对应外部音源,通道4对应MP3音源。通过IIC控制,可以实现这三个音源的切换。经过处理的音频信号从输出端输出到耳机放大器TPA152,通过放大驱动耳机,这样我们就能听到所要听的声音了。
在这里插入图片描述
PT2314的供电,这里也采用了RC滤波的形式,减少电源上的纹波对芯片工作影响,继而影响音质。图中对该芯片的数字地和模拟地也是进行了严格区分,坚持分开走线,减少了数字信号地对音质的影响。这么做的目的只有一个:让音质更好,更纯净。

2.4.6 FM24C16模块电路设计

铁电存储器FM24C16的电路也是很简单,只要通过简单的供电,然后连接IIC总线,就可以了。电路如图所示:
在这里插入图片描述

2.4.7 彩灯驱动模块电路设计

彩灯驱动采用MOS管AP2306,这款MOS管采用SOT23封装,占用PCB面积很少,因为有RGB三个通道,这里采用三个AP2306来驱动,电路结果如图所示:、
在这里插入图片描述
上图电路中对每个AP2306的栅极都通过了两个电阻连接,AP2306的栅极通过一个1K的电阻连接到MCU,再通过一个100K的电阻链接到地。这是非常有意义的。1K电阻在这里的作用是保证MOS管烧坏的情况下,通过电阻回流到MCU的电路不会太大,最多3.3mA,而MCU的IO最大能承受8mA的电流,这样,在这部分电路出问题的时候,不至于导致MCU烧坏。

100K电阻的作用主要是用来保证AP2306的可靠关断,因为AP2306是N型的MOS,所以,在栅极为高电压的时候,AP2306才会导通,在这里加一个下拉电阻到地,保证了MCU的IO在开漏输出或者出现干扰的时候,AP2306也不会误导通。

2.4.8 功放模块电路设计

因为本系统既有耳机输出,又有喇叭输出,所以有两个音频放大电路:(一)基于TPA152的立体声耳机放大电路;(二)基于TPA3100D02的功率放大电路。

耳机放大电路如图所示,耳机放大电路采用官方推荐的电路结构,对从PT2314送来的音频信号进行缓冲输出,推动耳机工作。耳机输出采用五针的专用耳机插座,这个插座具有开管功能,信号从1,4脚输入,从2,3脚输出,第五脚是地。如果没有耳机插上,则有音频信号从2,3脚输出,如果耳机插上了,则2,3脚不会有音频信号输出。这样通过连接2,3脚到D类功放上面,就可以实现耳机,功率输出同一时间只能有一个工作。
在这里插入图片描述

由于TPA152也是音频信号输出的一部分,对于这个芯片的供电,也是采用了LC滤波的形式,减少电源干扰对音质的影响。

功率放大电路如图所示:
在这里插入图片描述
该芯片提供的输出功率与负载电阻和输入电压有关。这里,我们采用12VDC供电,负载电阻为4欧姆,则能提供的输出功率为15W。从而根据其DATASHEET可以计算输出LC滤波环路的参数,电感取15mH,电容分别为1uF和0.22uF。

图中的功能选择部分可以有两种选择模式:(一)把MUTE接地,则会使芯片一直处于工作状态。(二)把MUTE和FAULT相接则可以实现短路检测,在没有出现输出短路的时候,芯片正常工作,在出现输出短路的时候,FAULT输出高电平,通过MUTE控制芯片停止输出,这样可以有效地保护芯片。

2.4.9 触摸屏控制电路和TFTLCD驱动电路设计

触摸屏控制芯片ADS7846的电路比较简单,电路如图所示:

在这里插入图片描述
TFTLCD驱动电路如图所示。
在这里插入图片描述
该部分电路也比较简单,不过要注意三个地方。

第一个地方是R2,这个是LCD背光的限流电阻,通过这个电阻限制流过LCD背光的电流,防止电流过大烧坏背光灯。第二个地方,为了节省IO口,LCD_BL这个控制信号,与ADS7846的CS是共用的,这里在软件编写的时候要注意。第三个地方是TOU_PEN信号在与MCU连接的地方,加入了RC滤波电路,因为这个信号连接到了MCU的中断上,而信号线在连接入MCU之前经过了较长的走线,上面的干扰比较多,而MCU不支持电平触发,所以必须加入滤波电路,使信号平稳。

滤波电路如图所示:
在这里插入图片描述

通过示波器观察,正常的中断信号在100HZ以下,而干扰信号则从几Khz到几百Khz不等,所以选取RC滤波电路的参数为R=1Khz,C=1uF,这样得到截止频率为159Hz左右,把干扰基本全部滤掉了。

2.4.10 电源电路设计

电源是整个电路的基础,好的电源能使整个系统更加稳定可靠。对于本系统,按电流大小,电源分为:功率电源和系统电源。功率电源部分如图所示:

在这里插入图片描述

功率电源一个给主控板供电,一个给彩灯提供电源。均采用LM2576作为稳压芯片,这款开关稳压芯片不但可以提供大电流,还能得到82%的变换效率,功率损耗较少使得电路不需要散热片,从而能有效降低电路的面积。对于外部电源输入加入了一个二极管,外部输入电源极性相反的时候,可以防止电源被烧坏。能有效的保护系统。

系统电源,通过REG117获得,电路简单,如图所示:
在这里插入图片描述
这个电路采用两块REG1117芯片给系统提供电源,一块提供3.3V的数字电源和模拟电源,它们通过电感连接,以减少数字电源对模拟电源的干扰。另外一块提供2.5V的电压,给VS1003的DSP提供核心电压。两者的输入电压均来自功率电源的5V输出。

2.5 硬件PCB设计

考虑到本系统的复杂性,为了使调试方便,把整个电路分为三个部分进行PCB的LAYOUT。分为电源板、显示板和系统板。电源板由三部分组成:电源、功率放大、彩灯驱动。显示板也有三个部分组成:TFTLCD、ADS7846和触摸屏。其他部分的电路都在系统板上,这样的设计有利于调试。

PCB的LAYOUT要注意8个问题:

  • 对于电流比较大的走线,必须使用较宽的线宽。
  • 对于功率放大,最好以单点接地的方式连接。这样可以使芯片工作时各个部分的相互干扰降低,从而获得较好的放大效果。
  • 对于走线,严禁走锐角的线,直角也最好少走,最佳的走线是弧形的。因为锐角和直角的走线会在尖端产生- MI,尤其在高频信号的时候。
  • 对于去耦电容,离芯片越近越好。
  • 对于信号线,不要长距离的平行走线,可以有效防止信号的相互耦合。
  • 对于高频部分,走线越短越好,如电路中的晶振,尽量把其安排在离芯片最近的地方,越近越好。这样可以有效减少干扰。
  • 对于数字地模拟地,必须严格区分,在其连接处通过磁珠或者电感或者电阻连接,可以减少数字部分对模拟部分的干扰。
  • 对于空白的区域,可以适当的覆铜并连接到地线来提高系统的抗干扰性,但是严禁构成回路,因为这样很容易使其他干扰耦合到上面。

三. 系统软件设计

3.1 设计思路

经过上一章,多功能MP3的的硬件系统已经设计出来了,但是没有软件的支持,硬件就不能正常工作,形同虚设。软件是硬件的灵魂,控制着整个硬件系统的运行。所以软件对整个系统的重要性从某种意义上说比硬件更加重要。

整个MP3的软件系统涉及到很多方面,是一个比较复杂的系统,不可能一次把所有的代码都写出来。这里对软件代码的编写采用模块化的设计思想,将整个软件系统逐步划分为子系统,再将子系统逐步细化为单一功能的模块来实现,最后再将所有的模块整合成一个大系统,实现预期的功能。

3.2 软件模块化设计

从整个系统来说,按其与硬件是否直接相关,可以把软件分为两大部分:(一)与硬件相关的底层驱动软件子系统。(二)与硬件无关的应用软件子系统。这两个子系统的软件又可以细化为许多模块。

对于底层驱动软件子系统包括如下模块程序:LCD驱动模块、触摸屏驱动模块、SD卡驱动模块、VS1003驱动模块、PT2314驱动模块、FM24C16驱动模块、TEA5767驱动模块、温度传感器驱动模块、彩灯驱动模块、实时时钟驱动模块。

对于应用软件子系统包括如下模块程序:JPEG/BMP解码模块、FAT文件系统管理模块、音乐播放模块、图片浏览模块、游戏模块、闹钟模块、时间模块、设置管理模块、电子书模块、收音机模块、彩灯控制模块。

当进行模块化程序设计时,我们首先要明确模块的功能作用,将其划分为一个个独立的功能模块,将其封装为函数,供给其他模块调用。底层驱动主要实现一些基本的底层功能,如硬件初始化、与硬件密切相关的时序函数等等。应用层实现整个软件系统的应用功能函数。

3.2.1 LCD模块驱动程序设计

本系统用到的LCD是八位数据模式,驱动IC型号是FMT0371,该芯片为松下合资厂生产的一个LCD驱动IC。最高支持26万色的TFT LCD,有6位、8位、16位和18位数据模式,可以方便选择。本系统配套的LCD使用的是八位数据模式,65K色。

根据该LCD的DATASHEET,每个像素点的GRAM实际上是一个18bit的数据寄存器。在16bit模式下与写入数据的对应关系如图所示:

在这里插入图片描述
从图中可以看出,RGB的有效位数分别为565,比如写入0XF800则显示纯红色,写入0X07E0则显示纯绿色,写入0X001F 则显示纯蓝色。在处理数据的时候要把像素值先变换为这样的结构,然后再写入LCD。LCD的显示状态都是由LCD的控制命令控制的,通过写入不同的控制命令和数据,就可以实现不同的现实功能和效果。分析DATASHEET得到几个重要的控制命令:
00H:这个命令用来控制内存操作模式,这里我们主要用它来改变LCD的扫描方向。
02H,03H:这两个命令用来分别设置X,Y方向的开始显示的点坐标。
04H,05H:这两个命令用来分别设置X,Y方向的结束显示的点坐标。
0EH,0FH:这两个命令用来写入和读取显存。
LCD驱动部分包括几个关键函数:LCD读写寄存器函数、LCD读写数据函数、LCD初始化函数和LCD画点函数。有了这几个基本函数,其他的画线、画面、甚至画图都比较容易了。LCD与MCU的连线包括D0~D7、CS、RS、RST、WR、RD、BL共14根线。
D0~D7:数据线
CS:LCD的片选线,低电平有效。
RS:LCD的地址/数据控制,高电平表示数据,低电平表示地址。
RST:复位线,低电平有效。
WR:写数据访问控制。
RD:读数据访问控制。
BL:LCD背光,高电平有效。

LCD读写寄存器

(1)对LCD寄存器的操作线设置RS为低,表示写入寄存器,然后拉低片选信号,给BL送入数据,然后通过一个WR的脉冲,就可以把数据写入到LCD了。最后释放RS,CS,完成此次操作。对LCD寄存器的读操作和写操作差不多,不同之处就是把WR脉冲改为RD脉冲。

(2) LCD读写数据
对于LCD数据的读写,和寄存器的读写差不多,只要把RS设置为高,就表示此次操作是对数据的读写,其他同寄存器的读写操作一样。对于以上两步,要注意在读写数据的时候必须先对寄存器写入0X0E/0X0F命令来表明是读还是写。

(3) LCD初始化
这部分是在前面两步成功的基础上才能进行的,LCD的初始化涉及到其内部很多寄存器的初始化。比较复杂,由void TFT_Init(void)函数实现,具体初始化过程请参考附件里面的代码。

(4) LCD画点
画点的实现,要先设置LCD开始显示和结束显示的范围,通过0X02H~0X04H这四个命令实现。之后写入0X0E命令,开始写入数据,就可以写入像素值(16bit)了,对于画点,我们只要写入一个像素点就可以了,这样就完成了在LCD上画一点。具体见附件里面的void TFT_DrawPoint(u8 x,u16 y)函数。

以上四个函数是LCD的主要函数,是最底层的。其他任何功能的函数都可以在这几个底层函数基础上实现。其他功能的LCD驱动函数均在tftlcd.c里面有定义和说明,具体见附件。

3.2.2 触摸屏模块驱动程序设计

本系统的输入系统采用的是四线电阻式触摸屏加ADS7846实现的,整个系统的控制都是由触摸屏控制的,所以,触摸屏控制算法的好坏直接影响着整个系统的使用,这里有必要认识触摸屏和ADS7846的工作原理。

触摸屏工作原理:触摸屏附着在显示器的表面,与显示器相配合使用,如果能测量出触摸点在屏幕上的坐标位置,则可根据显示屏上对应坐标点的显示内容或图符获知触摸者的意图。触摸屏按其技术原理可分为五类:矢量压力传感式、电阻式、电容式、红外线式、表面声波式,其中电阻式触摸屏在嵌入式系统中用的较多。电阻触摸屏是一块4层的透明的复合薄膜屏,如图:
在这里插入图片描述

最下面是玻璃或有机玻璃构成的基层,最上面是一层外表面经过硬化处理从而光滑防刮的塑料层,中间是两层金属导电层,分别在基层之上和塑料层内表面,在两导电层之间有许多细小的透明隔离点把它们隔开。当手指触摸屏幕时,两导电层在触摸点处接触。

触摸屏的两个金属导电层是触摸屏的两个工作面,在每个工作面的两端各涂有一条银胶,称为该工作面的一对电极,若在一个工作面的电极对上施加电压,则在该工作面上就会形成均匀连续的平行电压分布。如图所示:
在这里插入图片描述

当在X方向的电极对上施加一确定的电压,而Y方向电极对上不加电压时,在X平行电压场中,触点处的电压值可以在Y+(或Y -)电极上反映出来,通过测量Y+电极对地的电压大小,便可得知触点的X坐标值。同理,当在Y电极对上加电压,而X电极对上不加电压时,通过测量X+电极的电压,便可得知触点的Y坐标。电阻式触摸屏有四线和五线两种,我们这里用的是四线式的。四线式触摸屏的X工作面和Y工作面分别加在两个导电层上,共有四根引出线,分别连到触摸屏的X电极对和Y电极对上。

ADS7846工作原理:控制器的主要功能是分时向X、Y电极对施加电压,并把测量电极上的电压信号转换为相应触摸点的X、Y坐标。ADS7846 内部有一个由多个模拟开关组成的供电-测量电路网络和12位的A/D转换器,如图所示。
在这里插入图片描述

ADS7846根据微控制器发来的不同测量命令导通不同的模拟开关,以便向工作面电极对提供电压,并把相应测量电极上的触点坐标位置所对应的电压模拟量引入A/D转换器。在触摸点X、Y坐标的测量过程中,测量电压与测量点的等效电路如图所示,图中P为测量点。
在这里插入图片描述
ADS7846通过笔中断请求向MCU表示有触摸发生。如图所示:
在这里插入图片描述

当没有触摸时,MOSFET①和 ②打开、③关闭,则笔中断输出引脚通过外加的上拉电阻输出为高。当有触摸时,①和③打开、②关闭,则笔中断输出引脚通过③内部连接到地而输为低,从而向MCU发中断请求。MCU通过中断获取是否有按键按下,在得到中断以后读取ADS7846的数据,得到X,Y的坐标值。此时的坐标是在触摸屏上的绝对坐标(04096),并不是对应到LCD上的实际坐标(0320)。所以要把绝对坐标变换为实际坐标,这就需要校正了。

校正原理 :
我们传统的鼠标是一种相对定位系统,只和前一次鼠标的位置坐标有关。而触摸屏则是一种绝对坐标系统,要选哪就直接点哪,与相对定位系统有着本质的区别。绝对坐标系统的特点是每一次定位坐标与上一次定位坐标没有关系,每次触摸的数据通过校准转为屏幕上的坐标,不管在什么情况下,触摸屏这套坐标在同一点的输出数据是稳定的。不过由于技术原理的原因,并不能保证同一点触摸每一次采样数据相同,不能保证绝对坐标定位,点不准,这就是触摸屏最怕出现的问题:漂移。对于性能质量好的触摸屏来说,漂移的情况出现并不是很严重。所以很多应用触摸屏的系统启动后,进入应用程序前,先要执行校准程序。 通常应用程序中使用的LCD坐标是以像素为单位的。比如说:左上角的坐标是一组非0的数值,比如(20,20),而右下角的坐标为(220,260)。
这些点的坐标都是以像素为单位的,而从触摸屏中读出的是点的物理坐标,其坐标轴的方向、XY值的比例因子、偏移量、缩放因子都与LCD坐标不同,所以,可以在获取坐标的时候要首先把物理坐标转换为像素坐标,然后再赋给POS结构,达到坐标转换的目的。

触摸屏校正思路:
我们从触摸屏上采集到了4个角的物理坐标,假设是2.4英寸屏,240X320分辨率,则它们的像素坐标分别是(20,20)、(20,300)、(220,20)和(220,300)。这样,使用待定系数法就可以算出坐标系之间的平移关系。比如: Vx = xFactorPx + xOffset。 Vy = yFactorPy + yOffset 。那么,在读取触摸屏坐标的特定函数中就可以按照这个变换关系把物理坐标转换为像素坐标赋给POS结构了。 因此,应用程序中首先弹出一个有若干点的界面,然后让用户去点,一般采用了触摸屏四个角的四个点。根据像素坐标和物理坐标计算参数,并保存到一个文件中。那么以后只要这个文件的内容有效则不必再经历屏幕校准的过程。
根据以上原理就可以写出触摸屏的驱动和校准程序了,本系统的触摸屏坐标校准采用4点校准,具体算法同上,在void touch_adjust(void)函数中实现。ADS7843的初始化在void touch_init(void)函数里面实现,该函数能自动检测是否需要校准,还包括了对实时时钟中断的配置。其他触摸屏控制的函数均在touch.c文件里面。

3.2.3 SD卡模块驱动程序设计

SD卡有两个可选的通讯协议:SD模式和SPI模式。SD模式是SD卡标准的读写方式,但是在选用SD模式时,往往需要选择带有SD卡控制器接口的MCU,或者必须加入额外的SD卡控制单元以支持SD卡的读写。然而,STM32F103RBT6没有集成SD卡控制器接口,但是却拥有很强大的SPI接口,故选用SPI模式读取SD卡。

SD卡在上电初期自动进入SD总线模式,在此模式下向SD卡发送复位命令CMD0。如果SD卡在接收复位命令过程中CS低电平有效,则进入SPI模式,否则工作在SD总线模式。

SD卡初始化过程如图所示,具体的实现是通过u8 SD_Init(void)函数实现的,该函数还包括对MCU的SPI2的初始化。
在这里插入图片描述

3.2.4 VS1003模块驱动程序设计

VS1003也是采用SPI模式,不过是挂在SPI1上面,这里主要介绍VS1003的初始化操作。在对MCU相关IO口正确配置之后就可以对VS1003模块进行初始化了。VS1003通过7根线与MCU通信: XRST、XDCS、XCS、DREQ、SCK、SO、SI。
XRST:VS1003复位线,低电平有效。
XDCS:数据片选信号,低电平有效。
XCS:命令片选信号,低电平有效。
DREQ:数据请求,输入总线。
SCK、SI、SO:SPI接口线。

VS1003与MCU的通讯都是通过SPI总线来完成的,在默认情况下,数据将在SCLK的上升沿有效(被读入VS1003),一次需要在SCLK的下降沿更新数据,并且字节发送以MSB在先。注意VS1003的最大写入和读出时钟分别是CLKI/4和CLKI/6(CLKI为VS1003内部时钟)。
VS1003模块初始化步骤:

  • 硬复位,XRST =0;
  • 延时,XDCS、XCS、XRST置1;
  • 等待DREQ为高;
  • 软件复位:SPI_MODE=0X0804;
  • 等待DREQ为高(软件复位结束);
  • 设置VS1003的时钟:SCI_CLOCKF=0X9800,3倍频;
  • 设置VS1003的采样率:SPI_AUDATA=0XBB81,采样率48K,立体声;
  • 设置重音:SPI_BASS=0X0055;
  • 设置音量:SCI_VOL=0X2020;
  • 向VS1003发送四个字节无效数据,启动SPI发送;

3.2.5 PT2314模块驱动程序设计

PT2314采用IIC总线和MCU通信,IIC总线应用很多,这里就不在介绍。PT2314的控制寄存器如图所示:
在这里插入图片描述
MCU通过IIC总线写入相关的数据,就可以对音量等音效进行设置了。

3.2.6 FM24C16模块驱动程序设计

FM24C16也是采用IIC总线和MCU通信,通过标准的IIC操作,很容易实现对FM24C16的读写。FM24C16的器件地址与页地址是连在一起的,这里需要注意。FM24C16的高四位为固定的1010,而第四位用来表示页地址0~7,每页拥有256个字节,这样FM24C16的总大小为2048字节。

对FM24C16的读操作,先写入0XAx(x:0~7),再写入要写入的地址,紧跟着就可以写入数据了。而对于FM24C16的读操作,则稍微复杂一点在执行写操作的上述过程之后,再写入0XAx+1,代表执行读操作,紧接着就可以读数据了。

3.2.7 TEA5767模块驱动程序设计

TEA5767收音机模块支持IIC和三线模式,这里我们使用IIC来控制。TEA5767的器件地址是0XC0,在对TEA5767的读操作通过写入0XC1来执行。
TEA5767写操作:

  • 发送IIC起始信号
  • 发送器件地址0XC0
  • 等待应答
  • 发送一个字节,等待应答,再发送一个字节,等待应答,循环5次
  • 发送IIC停止信号
    TEA5767的读操作与写操作基本相同,只是IIC开始之后写入0XC1,将发送一个字节改为接收一个字节就可以了。

3.2.8 温度传感器驱动程序设计

温度传感器采用一线数字温度传感器DS18B20,读取DS18B20的温度读取操作过程如下:

  • 复位DS18B20
  • 检查DS18B20
  • 发送0XCC(跳过64bitROM地址)
  • 发送0X44启动一次转换
  • 复位DS18B20
  • 检查DS18B20
  • 发送0XCC(跳过64bitROM地址)
  • 发送0XBE(读暂存寄存器)
  • 获取温度的低字节
  • 获取温度的高字节

通过以上操作可以很方便的获取DS18B20的温度值。

3.2.9 RTC实时时钟驱动程序设计

RTC实时时钟是利用STM32F103RBT6内部的时钟模块实现的,根据STM32的DATASHEET,得到RTC实时时钟的初始化过程如下:

  • 使能电源时钟
  • 使能备份区域时钟
  • 取消备份区域写保护
  • 软复位备份区域
  • 开启外部低速晶振
  • 等待晶振就绪
  • 设置LSI作为RTC时钟
  • RTC时钟使能
  • 设置时钟分频系数
  • 等待RTC寄存器操作结束
  • 允许RTC配置
  • 配置秒钟寄存器
  • 配置更新
  • 等待RTC寄存器操作完成

到这里就结束了对RTC时钟的设置,RTC时钟在完成以上配置之后,就会每隔固定的时间,对秒钟寄存器(RTC->CNT)进行增1操作。此操作不需要软件参与,全部硬件执行。固定时间由时钟分频系数(RTC->PRL)确定,理论上由于外部低频晶振是32.768Khz,故只要在RTC->PRL内写入32768-1就可以得到精确的1秒了,但是由于晶振的误差,通常需要调整这个值,来得到比较准确的走时。

3.2.10 彩灯模块驱动程序设计

彩灯模块采用PWM控制,使用的是TIM4的CH1,CH2,CH3这三个通道来控制。因为要控制每个通道灯的亮度,故采用固定频率,调制脉宽的方式来实现,对应到STM32上则为PWM模式1:在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为无效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。通过设置TIM4的CCR1值,就可以调整输出的脉宽,从而控制LED的亮度。

TIM4的PWM初始化过程如下:

  • TIM4时钟使能
  • PORTB时钟使能
  • 设置PB6、7、8为复用功能输出
  • 设置TIM4计数器自动重装值
  • 设置TIM4与分频器值
  • 设置TIM4,CH1~3的工作模式
  • 设置TIM4,CH1~3的预装载使能
  • 使能TIM4预装载
  • 使能TIM4

通过以上过程就完成了对TIM4三个通道的初始化,只要在程序里面修改每个通道的比较寄存器(TIM4->CCRx)就可以实现不同占空比的输出了。在这里,我们设置TIM4的分频值为0,即不分频,这样TIM4的计数频率为系统时钟(72Mhz)。自动重装值为500,就可以得到72000/500=144Khz的PWM输出频率。

3.2.11 音乐播放模块程序设计

这是本系统的第一大功能,本系统的MP3播放功能是比较强大的:支持MP3、WMA、MIDI、WAV等格式的音频文件播放;支持歌词显示,歌词格式支持:
[XX:XX]/[XX:XX:XX]/[XX:XX.X]

并且支持多个并排的的歌词格式,如[XX:XX.XX][XX:XX.XX]也是支持的。支持歌曲当前播放进度显示;支持快进和快退操作;支持单曲循环,全部循环两种播放模式;支持频谱显示;支持音乐彩灯的控制;

MP3播放前的所有准备,在前面已经都做了,包括VS1003的初始化,从SD卡文件系统读取文件。这里,针对播放MP3,我们需要做的就是要管理文件和控制VS1003播放音乐文件。

对于文件浏览,要用到两个非常重要的函数:u16 File_Browse(u16 file_type),和u8 Get_File_Info(Cur_Dir_Cluster,FileInfo,T_FILE,&folder_cnt)。

第一个函数File_Browse,用来浏览指定类型的文件,参数:file_type为要浏览的文件类型,返回值为要打开的目标文件序号,返回0代表退出浏览。

第二个函数Get_File_Info,用来获取指定文件的详细信息或者获取当前目录下该类型文件的个数。参数:dir_clust:当前目录所在簇号;FileInfo,目标文件的实体对象(FileInfoStruct体);type,文件类型;count:为0时,得到的是整个目录下该类型文件的个数。不为0时,返回第count个文件的详细信息。

通过以上两个文件的组合就可以方便的实现任何文件浏览。对于音乐播放通过接口函数void Mus_Viewer(void) 来实现,对于播放音乐文件则是通过u8 Mus_Play(FileInfoStruct *FileName,u16 index,u16 total)函数来实现。其中FileName为要播放的MP3名字,index为该文件的编号,total为整个文件夹下面的文件数目。

到这里就实现了MP3播放功能了。但是还有其他功能,包括频谱显示,歌词显示,音乐彩灯的控制需要其他函数来执行。接下来介绍这些功能的实现方法。

频谱显示比较简单,主要频谱分析的工作不需要MCU来执行,是由VS1003执行的,通过在初始化VS1003后写入频谱分析的代码,就可以让其执行频谱分析的功能,MCU需要做的就是定时读出频谱分析后的结果,对其分析处理,并最终显示到液晶屏上,实现千千静听效果的频谱显示。频谱分析数据的获取通过void GetSpec(u8 p)实现,得到的频谱分析数据被存放在p里面,共十四个频点。

频谱显示主要通过void TFT_ShowFFT(u8* curv,u8* topv,u8 *flyv,u32 *toppos1,u32 *toppos2)函数来实现,curv为当前的频谱数据,topv为当前显示的最高点数据,flyv为当前悬浮在频柱上点的值,toppos1,toppos2用来寄存当前所有频点在空中停留时间的控制。topstay1:用来标记在06顶点是否需要停留,topstay2:用来标记在713顶点是否需要停留。每个顶点停留时间占用4bit。

歌词显示通过void LyricDisplayCtrl(void)来控制显示,但是最关键的却是开始对歌词的初始化处理过程,由函数u8 FindLrcFile(unsigned long dircluster,unsigned char *strName)实现。返回值,标记是否成功找到匹配歌词;dircluster为当前目录的簇号;strName为要查找与之匹配歌词的音乐的名字。该函数对歌词的处理过程为:第一步,获取歌词TAG(通过Get_Tag(void)实现);第二步,对得到的TAG排序;第三步,把歌词,按照排序后的TAG顺序,读入到SRAM里面。

音乐彩灯的实现就比较简单了,音乐彩灯是根据频谱变换得到的值来控制PWM的寄存器,达到控制彩灯不同颜色亮度的目的。所以在歌词显示模式的时候,音乐彩灯不工作。

3.2.12 图片浏览模块程序设计

图片浏览是本系统的第二大功能。本系统的图片浏览支持大多数JPEG/JPG图片的浏览,不论图片大小,都会自动调整实现图片的现实。同时,该系统还支持BMP格式图片的浏览,对16bit、24bit、32bit、的任意大小的BMP图片都能较好支持。图片还有多种浏览模式支持:手动浏览、顺序浏览、随机浏览。并且可以设置浏览间隔时间。满足各种情况下的需要。

图片文件浏览也是通过上面两个浏览函数浏览JPEG/JPG和BMP图片,在找到指定的JPEG/JPG和BMP文件之后调用BOOL AI_LoadPicFile(FileInfoStruct *FileName,u8 sx,u16 sy,u8 ex,u16 ey)函数,就可以实现JPEG/JPG /BMP图片的显示了。其中,FileName为图片名称,sx、sy为图片开始显示的地址,ex,ey为图片结束显示的地址,该函数根据这两个坐标自动调整图片大小,并显示出来。

这里介绍重点介绍AI_LoadPicFile函数,这个函数是一个智能的图片显示函数,支持对JPEG/JPG /BMP图片的智能显示,即我们的图片不可能都是240320大小的,比如常用的有1024768大小。这个函数会自动把不是240*320大小的图片进行缩小显示,从而使得其能够在本系统上正常显示。该函数的功能还不只如此,还可以根据你输入的坐标(sx,sy,ex,ey)范围,在指定的坐标范围(ex-sx,ey-sy)内,自动的显示图片。

3.2.13 游戏模块程序设计

闹钟是本系统的第三大功能,但是暂时只加入了一个游戏-拼图游戏,不过可以方便的加入其它游戏。拼图游戏游戏实现了三个难度等级的游戏难度,分别是33拼图、44拼图和5*5拼图,并具有保存当前游戏状态的功能,可以在下一次开机的时候继续上次未完成的游戏,有最佳排行显示功能。

游戏的界面控制要用到到一个关键函数u8 Load_Fun_Sel(const u8 * *list,const u8 *title,u8 *func,u8 len,u8 sel),这个函数可以方便的实现多级界面控制。list为目录项,你要显示的项目内容都存放在这个里面;title为标题内容,通过它可以方便的修改界面的标题;func为确定按钮的名称,有的时候,你要重定义确定按钮的名字通过它就可以实现;len为要显示的目录项的条数;sel为开始进入时要选中的目录项。

通过这个函数,可以方便的实现界面控制。拼图游戏的算法比较简单,这里不多说,不过对于初始化产生随机乱序的时候,需要注意判断游戏能否完成。游戏部分的功能接口通过函数:
void Game_Play(void)实现。

3.2.14 闹钟模块程序设计

闹钟是本系统的第四大功能,本系统的闹铃功能比较强大:具有8个闹铃,最多可以设置八个不同的闹钟;闹铃铃声支持MP3和FM收音;闹铃响铃可以设置为单次每天或者自定义(即周一到周日随意设置任意一天或几天闹铃)。

闹铃的设置在void Set_Alarm(u8 index)里面实现,包括闹铃时间,铃声等。参数index为闹钟的编号0~7。void Set_Alarm_Ring(void)函数负责对八个闹铃进行智能化管理,调用该函数,将会得到与当前时间最接近的闹钟时间,并把该时间写入闹钟寄存器里面。

还有一个比较重要的函数void Alarm_Process(void),该函数用来处理闹钟产生的时候,执行闹铃功能。包括播放闹钟,获取下一个闹钟时间并写入闹钟寄存器,保护当前音源,在播放完闹钟之后自动恢复到闹铃前的状态。执行该函数会弹出一个对话框,提示当前闹铃的时间,通过点击对话框终止闹铃。

3.2.17 时间模块程序设计

万年历时间是本系统的第五大功能,该系统的万年历功能也是很强大的:阳历日期显示、阴历日期显示、支持甲子年显示、24节气显示、星期功能、温度功能。温度功能支持从-55~125度内的温度检测。节气包括从2000年到2050年的节气显示。支持任意一天的周显示,阴阳历的查询范围从1900-2099年。

该部分的核心部分是RTC内时间和当前时间的转换。因为我们选择Linux时间1970年作为原始年。故RTC秒钟寄存器的范围为1970+136年,即约要到2100年左右才会溢出,足够用了。获取RTC时钟的操作时通过u8 rtc_get(void)完成。返回值用来标志此次操作是否成功。

通过u8 GetChinaCalendar(u16 year,u8 month,u8 day,u8 *p)函数,可以实现把当前的阳历日期转换为阴历日期。*p为阴历日期的存放空间;返回值用来标识此次操作的成功与否。

通过函数void GetWeek(u16 year,u8 month,u8 day,u8 *p),可以得到任意一个阳历日期所对应的周。*p,是周的存放地址。时间部分的功能接口通过函数void Time_Viewer(void)实现。

3.2.19 电子书模块程序设计

电子书是本系统的第六大功能,该系统的电子书支持的格式有:TXT文件、C文件、H文件、LRC歌词文件。电子书功能的实现比较简单,因为本系统已经支持了文件系统的浏览,支持了汉字和字符显示,所以电子书功能实现起来较方便。

电子书阅读主要通过void Read_Book(FileInfoStruct FileName)函数来实现,FileName为要打开的电子书文件。在该函数里面,实现了对中英文字体的识别,并有序的在LCD上,因为LCD大小为240320,使用的字体为16*16大小的宋体,如果全部用来显示汉字,则整个屏幕可以显示300个汉字。

本系统的字体文件保存在SD卡的SYSTEM文件夹下的FONT文件夹内,包括FONT16和FONT12两种大小的字体,字体文件是通过在电脑上用专门的软件,按特定格式生成的字体点阵数据。在读取字体点阵的时候,只要按照字体的GB2312码值,在字体文件里面偏移相应的位置,读取相应长度字节的数据,就可以得到这个字体的点阵码了,然后输出到LCD上,就可以显示文字了。

得到字体的点阵信息在void Get_HzMat(unsigned char *code,unsigned char *mat)函数里面实现。code为汉字的GB码,而mat则是得到的这个汉子的点阵数据。对于字库里面找不到的字体,则在mat里面返回全1。显示字体通过void show_font(u8 x,u16 y,u8 *font,u8 mode)函数实现。x,y为在LCD上显示的坐标;font为汉子的点阵数据;mode为显示模式(0,填充模式;1,叠加模式)。

通过以上几个函数的组合,再通过加入文件浏览函数和控制函数,则可以实现电子书阅读功能了,电子书模块的接口函数通过void Txt_Viewer(void)实现。

3.2.29 收音机模块程序设计

收音机功能是本系统的第七大功能,本系统的收音机功能包括:搜索模式选择,搜索级别设置,频段选择,后台播放等。

搜索模式包括:调频模式,即手动调节频率,实现收台;调台模式,即在自动搜索电台之后,所使用的模式,使用者可以用这个模式来轻松实现调台;全自动搜索模式,即系统根据设置,自动搜索满足条件的电台,并保存在FRAM里面。频段选择包括两个频段供选择,日本频段(76~91Mhz)和普通频段(87.5-108Mhz)。后台播放可以实现系统在做其他功能的时候还可以同时听收音机,收音机模块的接口函数通过void Radio_Play(void)实现。

3.2.20 彩灯控制模块程序设计

彩灯功能是本系统的第八大功能,通过该功能,可以实现彩色台灯的功能。由于采用了大功率的LED光源,该彩灯既可以做装饰用,也可以做照明用。彩灯模块程序实现的功能有:模式选择、时间间隔设置、后台执行、色彩调用和保存。

模式选择包括有普通模式、渐变模式和跳变模式。普通模式即全部手动调节,输出用户所想要的色彩和亮度。渐变模式即系统更具内部固定的算法,控制LED发出不同的颜色,颜色平稳过渡。跳变模式即系统自动调用用户保存的八个颜色,循环轮流显示。后台执行则是控制是否允许系统在执行其他功能的时候彩灯还正常工作。色彩保存和调用则是用户在看到自己中意的颜色之后可以方便地保存起来,或者调用。彩灯控制模块的接口函数通过void RGBLED_Play(void)实现。

四. 系统整合

系统整合在int main(void)函数里面实现,本系统的主控制程序通过调用各个模块的相关函数,实现了整个系统的功能整合,主控制程序的流程图如图所示:

在这里插入图片描述

系统开机之后,第一步进行的是对系统各个硬件模块的初始化;第二步是对FAT文件系统的初始化,这里要判断是否初始化成功,如果不成功,则系统会一直检索SD卡,直到检测到能被系统识别的卡和文件系统为止;第三步是查找系统文件,本系统的系统文件全部在SYSTEM文件夹下,该文件夹下又包括三个文件夹:FONT文件夹、SYSICO文件夹、GAME文件夹。FONT文件夹下包括FONT12.FON和FONT16.FON两个字体文件。SYSICO文件夹下则包括了所有的系统图标(BMP格式)。GAME文件夹下包括三个等级的游戏文件夹,这些文件夹里面又包括了相应的游戏图标,均为BMP格式。其中FONT文件夹和SYSICO文件夹在系统加载的时候是必须的,所以这里如果出现文件丢失,则也会一直检索,直到搜索到所有系统文件。GAME文件夹则是在游戏的时候才进行检索的,提高启动成功率和速度。

🚀 获取更多详细资料可点击链接进群领取,谢谢支持👇

点击免费领取更多资料

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值