【M3设计心得】+简易LCD1602频谱显示

Other Parts Discussed in Thread: LM3S811, LM3S6965

前言

把之前用在STM32F103RCT6芯片中的代码修改了一翻移植到了LM3S811中,删减了一些功能,主要实现的功能,就是频谱功率显示。在STM32F103RCT6上的项目是大型的频谱显示点阵屏。因为收到了LM3S811的评估版,马上修改了一翻代码,弄成了在LCD1602上显示频谱,虽然只有十六段的区间显示,但是用来测试的话,已经足够了。测试两者之间的对比。所用的开发工具为Keil Realview MDK4.14同时LM3S811的评估版中安装了最新版的调试驱动,自带驱动设备被计算机识别为Stellaris ICDI串口设备,所以要对它更新为CooCox Stellaris ICDI ND USB设备的驱动,具体的更新方法可以上网查找或到官网去下载。

第一点,在引脚方面,STM32做得比较好,一个端口有16个之多,LM3S811的却只有8个,同样是采用Cortex-M3的内核,IO口方面明显是缩水了。价格还要比STM32的要贵上一点,但是LM3S811STM32的芯片在质量上是否会强上一些呢?这点我还不清楚,不过TI的芯片在驱动能力、耐压等确实很强。STM32很多外设的IO口功能是复用的,例如你想要用到硬件串口和SPI功能时却发现这两者只能两选一,对比LM3S811的外设功能专用的端口来说这点是非常好的。以及STM32的芯片动不动就烧了(有时只坏了一两个外设,但其它功能还能用,但是你也要把它给换掉,因为不换的话,可能会带来安全隐患)所以才会申请这款芯片的评估版来对两者进行一下比较。

第二点,LM3S811库功能各参数细节说明、例程较少,有时需要猜测其意义和用法。

第三点,位操作功能有所缺欠,同STM32相比,同样使用库函数操作的话,STM32要比它在设置端口方面容易很多。

第四点,调试功能不是很完美,调试状态下用软件复位重新开始后程序有时会跑飞。

第五点,库函数还有所改进,有些函数根本用不了(库函数是评估版资料碟片中Domo项目中的库revision 5228),如我所用到的IO端口外部中断的初始化时,使用库函数的“GPIO端口中断注册”函数配PC4的中断。

GPIOPortIntRegister(GPIO_PORTC_BASE,PortCIntHandler);  //注册PortC中断

GPIOIntTypeSet(GPIO_PORTC_BASE, GPIO_PIN_4,GPIO_FALLING_EDGE);//PC4下降沿中断

GPIOPinIntEnable(GPIO_PORTC_BASE, GPIO_PIN_4); //开启PC4中断

IntMasterEnable();

配置完成后,当产生中断时,中断进入IntDefaultHandler中,不进入正确的中断函数中。但是把代码改为如下函数,同时在Startup.s文件中里自己修改中断向量的入口地址即没问题,同时定时中断也存在这个问题,即不能用注册函数来使用它,其它的几个中断,还没进行测试过,效果如何还不知道。

GPIOIntTypeSet(GPIO_PORTC_BASE, GPIO_PIN_4,GPIO_FALLING_EDGE);//PC4下降沿中断

GPIOPinIntEnable(GPIO_PORTC_BASE, GPIO_PIN_4); //开启PC4中断

IntEnable(INT_GPIOC); /开启PortC端口的中断

IntMasterEnable();

以上这五点是本人在移植过程中所遇到的一些问题,希望TI方面能够加大这方面的关注,毕竟现在的MCU寄存器越来越多,功能也越来越强大,明显再通过使用寄存器的操作来实现具体功能的时代已经快要过去了(除了那些对代码大小和指令速度有着非常高要求的人)。现在已经是越来越多的芯片厂商使用库函数来进行操作了。一来操作方便,移植相对简单,最重要的还是易上手,代码结构清晰明了,对日后的更新修改便于维护以及缩短开发周期减少研发经费。

好了,上面所描述的是本人在使用LM3S811过程中遇到的一些问题以及本人的一些设计心得,如不赞同的朋友请不要喷,本人能力有限,有些不足之处请谅解。下面就是细解用LM3S811LCD1602显示频谱功率的实现过程。

由于前面都说了LM3S811STM32都是使用ARM Cortex-M3的内核,所以STM32DSP库中的快速傅立叶变换函数同样适合用在LM3S811上面。STM32DSP库中的快速傅立叶变换函数采用的是汇编代码,在执行速度上有非常高的效率。关于快速傅立叶变换实现过程的数学原理这里就不细说了,不明白之处请上网自行查找。具体使用的库函数是64点的FFT变换函数。

1 系统模型


一个完善的系统从功能上大体上可划分成3部分:

(1)音频采集电路实现模拟音频信号的采样保持和量化处理,包括音频采样电路和加转换电路;

(2)主控制器在完成系统其他控制任务的前提下,充分利用单片机剩余计算资源,采用FFT算法计算音频信号频谱,并将计算结果输出到频谱显示电路。

(3)频谱显示电路实现模拟音频信号频谱的分段显示,它将音频信号频谱划分成16段,每段按照16级量化,由LCD1602显示器件显示;

1.1软件流程图

但实际是本人是测试使用,所以在系统模型上去除了音频采样电路部份,直接使用ADC口接音频信号。因为LM3S811AD10ADC,采样电压范围为0~3.3V,理论上,最小分辨率为3.22mV。音频信号电压Vpp范围标准为-1V~+1V,有些能达到-2V~+2V。所以在结构上完全可以胜任,不过因为ADC不能测量负电压,所以一定要加一个电平提升电路。把电压提升上去。如果不加也可以,只不过在软件算法方面要进行上下对称处理。因为此时所采样得到的信号为正常信号的一半,因为另一半信号已经丢失了。不过因为这也只是一个显示音乐信号小玩具,所以很多时候能省则省,不一定要做到很精确,总起码能显示出来就行了。所以本人也本着这一原则,直接测量它的信号。

2 信号的采样和预处理

21 采样频率

根据采样定理,采样频率至少应为所采样音频信号最高频率的2倍。由于人耳能够感受的频率为20 Hz~20 KHz,同时音频信号广泛所采用的采样频率为44KHz,所以在LM3S811上用定时器进行定时采样,采样频率为40 KHz

22 样本大小

采样频率确定后,还需确定样本值,即完成一次FFT运算所需的采样点数。根据数字信号处理的基本原理,假设采样频率为Fs,采样点数为N,则FFT运算后,第n点所表示的频率为:Fn=[(n-1)×Fs]N(1≤n≤N)Fn若要精确到Hz,则需采样长度为(1/f)s的信号。提高频率分辨率,需增加采样点数,但这在一些实际应用中是不现实的,则采用有频率细分法,即采样比较短时间的信号,然后在后面补充一定数量的0,使其长度达到所需的点数,再作FFT,这在一定程度上能够提高频率分辨率。由于该系统是将音频信号频谱划分成16段显示,因此采用18FFT运算去掉第1点和第18点的结果的算法应为最佳算法,但是FFT运算的最佳采样点是基于2的整数指数倍,即为23次方,或24次方等。所18点的FFT是一个不佳的采样点。同样STM32DSP库的FFT运算后的频率显示是对称型,即你采样16点真正有用到的也就是前8个点的数据,后8个点的数据是前8个点左右对称的,所以最佳采样点应为64点。同时显示段为16个,64点的FFT运算后的频率柱有用的为32个,明显多了,但是去掉第一个和最后一个的频率,仍剩下30个,即采用相邻频率隔一个的方法来选择要显示的频率时刚好符合了16段的显示器,虽然每段所间隔的频率范围较大。

23 频谱功率值在LCD1602上的显示

系统要求将音频信号频谱划分成16段,每段按16级量化,再使用LCD1602液晶显示,为了使显示的效果能像千千静听或其它音频播放软件的频率柱具有渐低高升和不同的模式显示效果,因此对于LCD1602的显示还要做一些特殊的算法处理。即当FFT运算后得到的幅度值低于前一次显示的幅度值时,不采用该幅度值,继续使用前一次的幅度值并自减一定的数据后显示。如果FFT运算后得到的幅度值高于前一次显示的幅度值时,立即采用此幅度显示。在LCD1602上也使用了自己写显存方式的字体库来显示,因为LCD1602上面没有各个电平的字体,有的也只有标准的5*8ASCII码字体。同时为了更加的美观,因此编写了两个不同的音频条形柱显示模式,通过切换键即可切换,当在一段时间内仍无音频信号输入时,该LCD1602自动进入温度显示模式,显示当时的温度。如有音频输入时立即从温度显示模式自动切换到音频显示模式。关于温度传感器使用的是LM3S811自带的温度传感器,不过有个问题就是自带的温度传感器采集到的温度值比当前环境正常温度高了45度。原因为温度传感芯片采集到的温度值实际上是芯片在当前环境下工作时的芯片温度。当把芯片关机一段时间后重新上电时所测量到的温度值才是实际的环境温度。不过加上去总比不加好,起码了胜于无。

3 硬件电路图

 

主要的电路图就如上,实际上个人感觉也是真的太简便过头了,不过一切为了简单,所以有多简单就多简单了。本想用4线来控制LCD1602的,不过怕操作起来速度过慢,所以采用标准的80时序来操作。

按键还是评估版上的User按键,图就略了,也就是PC4脚,按键的两个引脚中一脚直接接地,一脚接PC4脚并接10K上拉电阻。不过如果真正想要做好的话,滤波电路放大电路,电平提升电路等等这些都是需要添加上去的,如果想显示更好一点的话,还需要添加一个AGC电路。

4 实际效果图

评估版上标号为D3LED灯会一灭一亮。说明MCU正常工作,当按User键时,频谱的显示效果会进行变换,一共有两种显示效果。一种是分段式另一种是未分段的显示,当标号为D4LED灯亮时说明显示效果为未分段的效果,灭时为分段的显示效果。当无音频信号输入时,隔一段时间后自动进入温度显示模式。显示当前的芯片温度。当有音频信号输入时,则从温度显示模式转为频谱显示模式。软件里人为的增加了自动增益功能。不过软件的自动增益效果不是很好,最好的话还是加硬件AGC电路。

之前在移植STM32FFT库到LM3S811上的时候在编译时提示内部RAM空间不足。在Keil属性中设置为

同时在STM32库中的cr4_fft_64_stm32.s文件中的ALIGN=2改为ALIGN=3再编译即没问题,接着再把ALIGN=3改回ALIGN=2编译也没问题,不清楚这是什么问题,既然这样神奇。同时查了一下这部份代码的意义,发现是程序代码对齐格式。但具体原因还没找到。

 

5 总结

LCD1602音乐频谱功率显示主要涉及到了LM3S811的中断,IO口控制,ADC采集,定时器这四部份。

 上面的附件是源代码。

Demo_EK-LM3S811.rar