1、 1 MP3 播放器说明文档 2 目录 一、实现过程 . 3 二、代码说明 . 5 2.1 设计代码 . 5 2.1.1 顶层模块:【 songer.vhd】 . 5 2.1.2 乐谱发生模块【 NoteTabs.vhd】 . 6 2.1.3 乐谱码查表模块【 ToneTaba.vhd】 . 8 2.1.4 时钟分频模块【 DCM_12MHZ.vhd】 . 9 2.1.5 数控分频模块【 Speakera.vhd】 . 10 2.2.测试代码: . 11 2.2.1 测试顶层模块 【 tb_songer.vhd】 . 11 2.2.2 测试 Speakera 模块 【 tb_spk.vhd】
2、. 12 2.2.3 测试 DCM_12MHZ 模块 【 tb_clk12mhz.vhd】 . 13 三、操作过程 . 14 3 一、实现过程 1. 制作乐谱查找表 :找出不同音符的发音频率,寻找最佳待分频频率,计算分频数和分频预置数,制作乐谱查找表。如何选择基准频率很关键。若基准频率比较小,用他除以音符频率得到的分频系数也就比较小,这样的话进行四舍五入后误差相对而言会比较大。若基准频率偏大,分频系数也就偏大,这会增加系统的负担。综合考虑分频系数的准确性和大小,基准频率为 750 khz 是比较合适的。 由于我们 从开发板的内部时钟分频 得到的 750 khz 的频率信号是脉宽极窄的尖脉冲信号
3、,为了提高扬声器有足够的功率发音,我们对尖脉冲信号再进行二分频,得到对称方波后再输出。因此,在表 1 中,就是以 375 khz 为基准频率计算了各个音符的分频 系 数和分频预置数。 选择 11 位二进制数表示分频系数和分频预置数(计数初值) ,因此最大值为 2047。 休止符不用进行分频,分频系数为 0,频率为 375000hz。 分频系数和分频预置数的计算方法: 分频系数 =375000/音符频率 分频预置数(计数初值) =2047-分频系数 表 1 各个音符的频率及其对应的分频系数(基准频率 375KHz) 音符名 频 率 (Hz) 分频 系数 计数 初值 音符名 频 率 (Hz) 分频
4、 系数 计数 初值 休止符 375000 0 2047 中音 4 698.456 537 1510 低音 1 261.525 1435 513 中音 5 783.990 478 1569 低音 2 293.664 1277 770 中音 6 880 426 1621 低音 3 329.627 1138 909 中音 7 987.766 380 1667 低音 4 349.228 1022 1025 高音 1 1046.502 358 1689 低音 5 391.995 957 1090 高音 2 1147.659 327 1720 低音 6 440 852 1195 高音 3 1318.510
5、 284 1763 低音 7 493.883 759 1288 高音 4 1396.919 268 1799 中音 1 523.251 717 1330 高音 5 1567.981 239 1808 中音 2 587.329 638 1409 高音 6 1760 213 1834 中音 3 656.255 571 1476 高音 7 1975.537 190 1857 2. 预置曲谱: 定义一个转换规则,将音乐音符转换为代码预置在程序里。我们称预置在程序里的代码为乐谱 代 码。音符转换为 乐谱 代 码的规则为: 休止符转换为代码 0,低音 1-低音 7 转换为代码 1-7,中音 1-中音 7
6、转换为代码 8-14,高音 1-高音 7 转换为 15-21。 现在一般乐曲中,最小的节拍为 1/4 拍。若定义 1 拍的持续时间为 1 秒,那4 么 1/4 拍的持续时间就为 1/4 秒,即 0.25 秒。其他的节拍数 为 1/4 拍 的 整数倍,因此他们的持续时间就为 0.25 秒的整数倍。将乐曲中每个音符 以及 持续 的 节拍数写进程序,定义一个 4hz 的时钟频率,每当时钟上升沿来临时就输出 1/4 拍音符,若是其他 1/4 拍整数倍的音符就连续输出整数倍的次数。这样,音符就源源不断的输出了。 3. 对预置的曲谱码在乐谱查表码里进行查找,找出相应音符对应频率的分频系数和分频预置数。 4
7、. 根据查找到的分频预置数对待分频频率( 750khz)进行分频并 把 输出 连接到 集成运放电路 Vin 实现音量调节。音量调节的原理图如图 1 所示。按图 1 所示电路图连接电路, Vout接扬 声器。通过调节滑动变阻器 R2 就调节音量。 图 1 音量控制电路 5 二、 代码说明 2.1 设计代码 2.1.1 顶层模块: 【 songer.vhd】 library IEEE; use IEEE.STD_LOGIC_1164.ALL;-加入函数库 ENTITY Songer IS PORT ( clock : in STD_LOGIC;-时钟信号输入 rst : in STD_LOGIC;
8、-复位信号输入 CODE1: OUT INTEGER RANGE 0 TO 7 ; -简谱码输出显示 HIGH1: OUT std_logic; -高八度音显示 SPKOUT: OUT STD_LOGIC ) ; -发音输出 END Songer; ARCHITECTURE Behavioral OF Songer IS COMPONENT NoteTabs添加 notetabs 元件 PORT ( clk : IN STD_LOGIC ; ToneIndex : OUT INTEGER RANGE 0 TO 15 ) ; END COMPONENT ; COMPONENT ToneTaba添
9、加 tonetaba 元件 PORT ( Index : IN INTEGER RANGE 0 TO 21 ; CODE : OUT INTEGER RANGE 0 TO 7 ; HIGH : OUT std_logic ; Tone : OUT INTEGER RANGE 0 TO 16#7FF# ); END COMPONENT ; COMPONENT Speakera添加 speakera 元件 PORT ( clk: IN STD_LOGIC ; Tone: IN INTEGER RANGE 0 TO 16#7FF# ; SpkS1: OUT STD_LOGIC ) ; END COM
10、PONENT ; SIGNAL Tone1 : INTEGER RANGE 0 TO 16#7FF# ; -定义 信号量,连接 ToneTaba 的输出 SIGNAL ToneIndex1 : INTEGER RANGE 0 TO 15 ; -定义 信号量,连接 NoteTabs 的输出 component DCM_12MHZ添加 dcm-12mhz 元件 port( clkin: in std_logic; rst: in std_logic; clk_750khz: out std_logic; clk_4hz: out std_logic); end component; 6 signa
11、l clkout_4hz: STD_LOGIC;-定义 信号量,连接 DCM_12MHZ 的 4hz 输出 signal clkout_750khz:std_logic;-定义 信号量,连接 DCM_12MHZ 的 750khz 输出 BEGIN -定义 映射关系 u1 : NoteTabs PORT MAP (clk=clkout_4hz , ToneIndex =ToneIndex1 ) ; u2 : ToneTaba PORT MAP (Index=ToneIndex1 , Tone=Tone1 ,CODE=CODE1, HIGH=HIGH1 ) ; u3 : DCM_12MHZ por
12、t map (clkin=clock,rst=rst,clk_750khz=clkout_750khz,clk_4hz=clkout_4hz); u4 : Speakera PORT MAP (clk=clkout_750khz,Tone=Tone1, SpkS1=SPKOUT ); END; 2.1.2 乐谱发生模块 【 NoteTabs.vhd】 library IEEE; use IEEE.STD_LOGIC_1164.ALL;-加入函数库 entity NoteTabs is-定义实体 Port ( clk : in STD_LOGIC;-音乐节拍时钟 ToneIndex : out
13、integer range 0 to 15);-乐谱码输出 end NoteTabs; architecture Behavioral of NoteTabs is signal Counter:integer range 0 to 2000;-乐谱码计数器 begin CNT8:process(clk) begin if Counter = 130 then counter ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex
14、ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex
15、ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex ToneIndex null; end case; end process; end Behavioral; 8 2.1.3 乐谱码查表模块 【 ToneTaba.vhd】 library IEEE; use IEEE.STD_LOGIC_1164.ALL;-加入函数库 entity ToneTaba is Port ( Index : in INTEGER RANGE 0 TO 21;-简谱代码
16、输入 CODE : out INTEGER RANGE 0 TO 7;-简谱代码输出 HIGH : out std_logic;-高八度音显示 Tone : out INTEGER RANGE 0 TO 16#7FF#);-输入的简谱码查表值 end ToneTaba; architecture Behavioral of ToneTaba i begin search:PROCESS(Index) begin case Index is -译码电路, tone 输出对应分频预置数, CODE 输出对应的简谱码,HIGH 输出对应的音调高低 when 0=ToneToneToneToneTon
17、eToneToneToneToneToneToneToneToneToneToneToneToneToneToneToneToneToneNULL; end case; end PROCESS; end Behavioral; 9 2.1.4 时钟分频模块 【 DCM_12MHZ.vhd】 library IEEE; use IEEE.STD_LOGIC_1164.ALL;-加入函数库 entity DCM_12MHZ is定义实体 port( clkin: in std_logic;-时钟信号输入 rst: in std_logic;-复位信号输入 clk_750khz: out std_l
18、ogic;-750khz 输出 clk_4hz: out std_logic);-4hz 输出 end DCM_12MHZ; architecture Behavioral of DCM_12MHZ is COMPONENT clk12mhz_dcm-语句结构对所要调用的元件作了声明 PORT( CLKIN_IN : IN std_logic; RST_IN : IN std_logic; CLKFX_OUT : OUT std_logic; CLKIN_IBUFG_OUT : OUT std_logic; LOCKED_OUT : OUT std_logic ); END COMPONENT
19、; signal clk_temp:std_logic;-类型为变量 signal counter750:integer range 0 to 15;-类型为变量 范围是 0 到 15 signal counter4:integer range 0 to 2999999;-范围是 0 到 29999999 begin Inst_CLK12MHZ: clk12mhz_dcm PORT MAP( CLKIN_IN = clkin, RST_IN =rst , CLKFX_OUT = clk_temp, CLKIN_IBUFG_OUT =open , LOCKED_OUT = open ); pro
20、cess(clk_temp,rst)-进程 begin if(rst=1) then counter750=0;-赋初值 clk_750khz=0;-赋初值 elsif rising_edge(clk_temp) then if (counter750=7) then-当变量等于 7 时,信号量为上升沿 clk_750khz=1; counter750=counter750+1;-计数器加 1 elsif(7counter750 and counter75015) then-当变量在 7 与 15 之间是,信号量处于下降沿 clk_750khz=0; 10 counter750=counter
21、750+1;-计数器加一 elsif (counter750=15) then counter750=0;-计数器为 15 时 再返回 继续为 0 end if; end if; end process; process(clk_temp,rst) begin if(rst=1) then counter4=0;-赋初值 clk_4hz=0;-赋初值 elsif rising_edge(clk_temp) then if (counter4=1499999) then-变量小于 1499999 时 信号量为上升沿 clk_4hz=1; counter4=counter4+1;-计数器加一 el
22、sif(1499999counter4 and counter42999999) then-变量在 1499999 与 299999之间时 clk_4hz=0;-信号量为下降沿 counter4=counter4+1;-计数器加一 elsif (counter4=2999999) then-计数器加到 2999999 时为 0 counter4=0; end if; end if; end process; end Behavioral; 2.1.5 数控分频模块 【 Speakera.vhd】 library IEEE; use IEEE.STD_LOGIC_1164.ALL;-加入函数库
23、entity Speakera is-数控分频与演奏发生器 Port ( clk : in STD_LOGIC;-待分频时钟 Tone : in integer range 0 to 16#7ff#;-分频预置数输入, 11 位二进制数 Spks1 : out STD_LOGIC);-发声输出 end Speakera; architecture Behavioral of Speakera is-结构体 begin GenSpks:process(clk,Tone)-进程 VARIABLE Count1:integer range 0 to 16#7FF#;-11 位 2 进制数 begin if clkevent and clk=1 then if Count1=2047 then - 11 位可预置计数器
Copyright © 2018-2021 Wenke99.com All rights reserved
工信部备案号:浙ICP备20026746号-2
公安局备案号:浙公网安备33038302330469号
本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。