当前位置:文档之家› CPLD单片机定时器音乐播放器

CPLD单片机定时器音乐播放器

基于CPLD与51单片机的定时器与音乐播放器马大康 06007122万树 06007113覃朋 060071102009.12一、系统简介本系统利用CPLD 和51单片机联合实现了倒计时器和音乐播放器的功能。

作 为《电子系统设计》的课程设计,本系统充分利用了两块开发板上的资源,并实 现了可编程器件与单片机之间的串口异步通信,器件连接方便,并有良好的人机 交互界面。

二、系统结构框图与思路图2 CPLD 内部功能模块划分及连接经过对两块开发板板上资源的对比,我们发现,CPLD 板上的资源较为丰富, 尤其是其8个独立按键和1602液晶屏,十分适合人机交互,因此我们选择用CPLD 开发板作为主控板。

单片机板上拥有4个七段数码管,显示变化的数字十分方便, 可以构成1〜60分钟可变初值的倒计时器。

由于之前的实验中已经实现了在CPLD 中嵌入简易的UART,因此可以利用 CPLD 上的8个拨码开关设定倒计时器的初值,并通过异步串行通信传输给单片 机。

单片机上的拨码可以实现对倒计时器进行暂停、清零。

图1 系统结构框图除此之外,由于CPLD板上已有蜂鸣器,可以播放预先存入的歌曲,并通过板上的其他按键控制音斥的暂停与继续播放。

介于上述分析,设计的系统结构框图如图1所示,CPLD中功能模块的划分如图2所示。

操作流程:CPLD板上:Keyl->进入倒计时器模式,设定倒计时器初值(通过8个拨码),液晶屏上显示u D-counter Set time needed M。

Key2-〉发送倒计时器初值到单片机,单片机开始倒计时,液晶屏上显示“ D-counter D-countering nKey3->进入音乐盒模式,播放音乐《喀秋莎》。

Key4->暂停音圧播放单片机板上:在倒讣时过程中,将拨码开关1向上拨,倒计时暂停,向下拨后继续倒计时。

在倒计时过程中,按下CPLD板上的Keyl后(此时为设定初值模式),将拨码开关2向上拨,倒计时器清零,此时可对其重新置初值。

三、功能模块的实现1、异步串行发送模块想要在CPLD中嵌入异步吊行通信模块,就必须对异步吊行通信协议有深入的理解,由于系统中只用到了发送模块,这里仅对发送模块的设计做介绍。

在空闲时,发送1。

当发送使能WR为高电平且发送缓冲寄存器为高电平时, 向发送缓冲寄存器中写入待发送的数据。

当发送移位寄存器为空时,将发送缓冲寄存器中的值置入发送移位寄存器,并将TxDone变为低电平,表示发送一个字节的周期开始,此时不能向发送寄存器中置数。

发送周期开始首先发送一个低电平作为起始位,接着从数据的低位开始发送数据,发送结束后发送高电平作为结束位,并将TxDone变为高电平,表示发送一个字节结束。

整个模块的状态图如图3所示。

图3图4标准的UART设计是将系统时钟分频成16XBaudrate的频率,然后每个16 个这样的时钟周期发送一位数据。

我们这里的设计与标准设讣有些不同,我们直接把系统时钟分频成波特率时钟,然后每个周期发送一位数据,这样的效果与原先相同,但在编程上轻松了许多。

2、按键检测模块图5通过在每个时钟的上升沿检测引脚的值,经过延时再判断达到消抖的作用, 再将其转化为键值输岀。

3、液晶显示模块图6LCD_Top模块内部山时钟分频模块与LCD驱动模块构成,其中时钟分频模块负责将50M的系统时钟分频成500Hz的LCD驱动时钟。

LCD驱动模块主要负责产生控制信号并发送显示数据。

L C D驱动模块的状态流程图如下图所示。

4、蜂鸣器模块图8蜂鸣器演奏音乐模块较为简单,我们参考实验指导书中的代码,将《梁祝》的谱换成了《喀秋莎》。

5、定时器模块定时器模块在单片机中,其程序流程图如下:图10在这块单片机板上做倒讣时器有两个缺陷:第一,我们采用的是软件定时的方式,精确度不如硬件电路高;笫二,此开发板的按键和拨码没有直接接到单片机的I/O 口上,而是通过锁存器挂在总线上,这就决定了使用按键只有采取查询的方法,而不能釆用中断的方法。

因此在倒计时的过程中,每延时1秒前需要查询按键的值来实现暂停或停止的功能,指令也是需要执行时间的,这样会使延时时间超过1S,而且数码管略微有些闪烁。

不过,经过缩短延时Is程序的时间,我们将每秒钟的误差控制在了1/30秒。

四、系统调试过程本系统由三人共同合力完成,具体分工如下:马大康负责完成了串口通信模块、液晶显示模块和按键控制模块,并撰写了最终的设计文档。

万树负责完成了单片机上倒计时模块以及乐谱的输入,覃朋负责完成了蜂鸣器模块。

系统的调试是按照先单独模块测试,再组合拼接整体调试的步骤进行的,整个过程有条不紊,系统的总体设计也根据单独模块测试的情况与原先计划做岀了相应调整。

比如原先是汁划利用USB接口实现PC与CPLD板的通信,在PC上自行开发小软件以控制CPLD板上的资源。

但由于USB模块(FT245)没有在计划的时间内调试成功,我们就放弃了此方案,改用CPLD板上的按键来控制整个系统,这样并不影响系统的整体功能。

1、串口通信模块的调试山于考虑到在CPLD中实现UART并非易事,并且要实现我们系统的口标最好的方法就是利用串口通信,因此我们率先尝试了此模块。

该模块的调试时间表如下:12.9〜12. 13 深入学习了串口通信协议,编写了verilog代码,并在QuartusII 软件中仿真成功。

这里的仿真是指通过自行设计的发送模块TxUnit 向自行设计的接收模块RxUnit发送数据,接收到的数据无误。

12.21实现了CPLD板与PC机之间的通信,通过拨码设置发送数据,PC端的串口调试工具接收到数据无误。

12. 26实现了CPLD板与单片机板的通信。

在软件编写过程中,我们参考了很多资料,观摩了别人写的一些代码。

本想利用别人的代码加以改进,但未能成功。

我想原因有二:第一,从网上下载的代码可靠性值得怀疑,其本身有无经过验证还不清楚。

第二,自身阅读verilog 代码能力还需加强,不知是不是因为软件中不能写中文注释的原因,很多代码没有注释,阅读起来相当吃力。

由于接触verilog时间不长,面对长篇的代码常常抓不住重点,从头到尾都读完了,却弄不清每个状态都实现了什么功能。

在修改代码未果的情况下,我决定,与其花时间阅读那么冗长的代码,不如先花时间把吊口通信的协议(尤其是接收模块的操作)吃透,然后尝试自己编写代码,这样代码中的每一步自己都知道是什么意思,出了错解决起来也方便。

通过此次的串口模块程序的编写,我初步掌握了利用状态机编写时序的方法,摒弃了烦琐的条件判断语句(网上部分代码就是如此编写的,十分不规范),十分具有锻炼意义。

从软件调通到实现CPLD和PC机的通信没有花太长时间,于是便开始准备CPLD 和单片机间的通信。

山于两块开发板上的RS232 口均为母口,因此我在网上购买了一根公对公的串口线。

当我迫不及待地将两块板子连接起来时,什么反 应也没有。

我这时有些不知所措,因为CPLD 可以发送数据给PC, PC 也能发送数 据给单片机,波特率都是9600,为什么将两者直接连接就不行了呢?出问题的 值可能有一个地方,那就是我够买的那根公头对公头的串口线。

难道线是断的, 这商家也太不厚道了吧,应该不会。

这时在我脑海中突然浮现出串口通信最基本的那张示意图:认为TxD 与RxD 在传输线中完成 输线里没有完成 起万用表测量了公对公帘口线的两个2脚,发现这两个脚是导通的,也就是说吊口线中没有实现 信号的交义!再对着两块板子的原理图看了一下,TxD 都接的是各自的串口座2 脚,RxD 都接的是各自的串口座3脚,这样的话相当于把两个发送的TxD 管脚连 接在了一起,要实现通信是根本不可能的。

后来在网上一查,原来串口线有直连 线与交义线两种之分,(估讣直连线是单纯做延长用的),而公对公的线没有交 义线,需要定制。

不怕出问题,怕的是出了问题找不到问题的原因,既然找到了原因,就有方 法解决。

于是我来到了创新实验室,先用两根导线将RxD 与TxD 连接起来,并将 两块开发板共地。

打开电源后,按下按键,单片机成功接收到了 CFLD 发送的数据。

这证明了之前的不成功完全是因为硬件电路的问题。

为了使最后的作品方便展示,两根导线显然不够稳定。

于是我将那根公对公 的串口线从中间剪断,其中有10根线,我找到每根线对应是儿针,再将两边的 2针与3针交义连接起来。

山于CPLD 开发板上是将地与1针相连,而单片机开 发板上是将地与5针相连,这两根线需要缠在一起,因此这根线的两头并不等价, 一头固定接单片机,另一头固定接CPLDo这根自制的串口交义线完成后,经过检验无误,我们的串口通信模块算是成 功完成了。

2. 液晶模块、键盘模块的调试液晶模块的调试也并不轻松,起初和大家一样,我们花了很长时间阅读把实 验指导书中给的代码,并把其烧到了板子里进行测试,液晶屏并没有被点亮,于 是我们放弃了修改那冗长的代码,在另一份代码上进行修改。

12. 14〜12. 15学习了 1602液晶屏的控制方法,并修改了一份已有的 verilog代码,将其烧入板子后成功的在液晶屏上显示了u madakangisfromee n o12.27确定了整个程序的框架,编写了键盘模块(可以采集按键、消抖并输出键值),改进了之前编写的液晶模块,使其能够根据键值显示不同的文字。

在这一阶段其实也走了一段小小的弯路。

在我的液品模块中,需要显示的字 符是作为模块的参数的,因此最初我的想法是通过实例化时的参数传递将不同键 值对应的文字传递给液晶模块,因为verilog 中也有现成的参数传递语句,如defparamc但这种想法经实践检验既不可行也不科学:首先,如果你有5种字符串要显 示,你就必须实例化5个液晶显示模块,而这5个module 实例无法公用同样的 输岀,也就是说如果想要这样实现的话还必须在5个module 实例后加一个数据 选择器,这样确实非常的繁琐。

其次,即使实现了,也非常地耗费LEo 因此我 放弃了这样的方案。

后来我还是对module 本身做了修改,将要显示的文本存为不同的parameter, 然后在给显示数据寄存器赋值时,加一个case 语句判断,根据不同的键值选择 不同我之前一直 的交义应该是 的,但会不会传 呢?于是我拿的parameter,成功实现了通过按键改变屛幕显示的功能。

3.倒计时器的调试本来倒计时器的调试倒是一帆风顺,只是在添加暂停与停止功能时,无意中改动了一个变量的类型,将原先的int型改为了unsigned char,导致参数调用时不匹配,讣数减到0时会数码管就开始出现乱码了。

不过后来还是发现了这个问题。

4.蜂鸣器的调试采用6MHz作为基频,山于所选歌曲的最短的音符为四分音符,如果将全音符的持续时间设为Is的话,还需要一个4Hz的分频即可。

相关主题