VHDL 乐曲演奏电路设计
前言
无源蜂鸣器在直流信号下不会响,需要方波驱动。输入不同频率的方波会发出不同音调的声音,方波的幅值决定了声音的响度。
目标
乐曲发生电路在节拍(4Hz)的控制下根据乐谱产生合适的分频系数。分频器根据分频系数对时钟脉冲分频产生各种声调所需要的频率的信号。最后考虑到驱动蜂鸣器要足够的能量使用2分频器对信号进行二分频变为占空比50%的信号。
模块设计
分频器
上面的框图中预分频器、可预置数分频器都是分频器。可以采用上一个设计“数字时钟”设计的“数控N分频器”,不同之处是传入N的位宽(12位)要满足产生音调对应的频率所需分频系数大小(最大3822),通过给分频器传入数值N来对时钟信号进行N分频。得到的信号频率为原时钟信号的频率/N,占空比为1/N。
代码如下
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity ClkDiv is
port(
clk_i:IN STD_LOGIC;
N_i: IN STD_LOGIC_VECTOR(11 DOWNTO 0);
clk_o:OUT STD_LOGIC);
end ClkDiv;
architecture behavior of ClkDiv is
signal count:STD_LOGIC_VECTOR(11 DOWNTO 0):="000000000001";
signal clk_temp:STD_LOGIC:='0';
begin
process(clk_i)
begin
if(clk_i'EVENT and clk_i='1')then
if (count=N_i)then
count<="000000000001";
clk_temp<='1';
else
count<=count+1;
clk_temp<='0';
end if;
end if;
end process;
clk_o<=clk_temp;
end behavior;
仿真结果见“数字时钟设计”
乐曲发生器
乐曲发生电路在节拍(4Hz)的控制下根据乐谱产生合适的分频系数。在分频器输入为1Mhz的情况下,各个音调对应的声音的分频系数如下图所示。虽然我们设计的分频器输入为2Mhz,但是在驱动蜂鸣器前还进行了二分频,所以以下分频系数对我们的设计而言是合适的。
代码如下
--乐曲发生器Director 在4Hz的信号激励下,产生不同的预置数
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
entity Director is
port(
Director_i : IN STD_LOGIC;
Director_o: OUT STD_LOGIC_VECTOR(11 downto 0)
);
end Director;
architecture rtl of Director is
signal count :integer:=0;
signal s: STD_LOGIC_VECTOR(4 downto 0) :="00000";
signal Director_temp: STD_LOGIC_VECTOR(11 downto 0) :="000000000000";
begin
process(Director_i)
begin
if(Director_i'EVENT and Director_i='1')then
if(count>=47)then
count<=0;
else
count<=count+1;
end if;
if (count=0) then s<="00011"; --乐谱
elsif (count=1)then s<="00011";
elsif (count=2)then s<="00011";
elsif (count=3)then s<="00011";
elsif (count=4)then s<="00100";
elsif (count=5)then s<="00100";
elsif (count=6)then s<="00100";
elsif (count=7)then s<="00101";
elsif (count=8)then s<="00111";
elsif (count=9)then s<="00111";
elsif (count=10)then s<="00111";
elsif (count=11)then s<="01000";
elsif (count=12)then s<="00101";
elsif (count=13)then s<="00111";
elsif (count=14)then s<="00100";
elsif (count=15)then s<="00100";
elsif (count=16)then s<="01011";
elsif (count=17)then s<="01011";
elsif (count=18)then s<="01011";
elsif (count=19)then s<="01110";
elsif (count=20)then s<="01100";
elsif (count=21)then s<="01011";
elsif (count=22)then s<="01001";
elsif (count=23)then s<="01011";
elsif (count=24)then s<="01000";
elsif (count=25)then s<="01000";
elsif (count=26)then s<="01000";
elsif (count=27)then s<="01000";
elsif (count=28)then s<="01000";
elsif (count=29)then s<="01000";
elsif (count=30)then s<="01000";
elsif (count=31)then s<="01000";
elsif (count=32)then s<="01000";
elsif (count=33)then s<="01000";
elsif (count=34)then s<="01000";
elsif (count=35)then s<="01001";
elsif (count=36)then s<="00110";
elsif (count=37)then s<="00110";
elsif (count=38)then s<="00101";
elsif (count=39)then s<="00101";
elsif (count=40)then s<="00100";
elsif (count=41)then s<="00100";
elsif (count=42)then s<="00100";
elsif (count=43)then s<="00101";
elsif (count=44)then s<="00111";
elsif (count=45)then s<="00111";
elsif (count=46)then s<="01000";
elsif (count=47)then s<="01000";
end if;
end if;
end process;
-- process(Director_i)
-- begin
-- if(Director_i'EVENT and Director_i='1')then
-- if(count=9)then
-- count<=0;
-- else
-- count<=count+1;
-- end if;
-- if (count=0) then s<="00000"; --乐谱
-- elsif (count=1)then s<="00001";
-- elsif (count=2)then s<="00011";
-- elsif (count=3)then s<="00100";
-- elsif (count=4)then s<="00101";
-- elsif (count=5)then s<="00110";
-- elsif (count=6)then s<="00111";
-- elsif (count=7)then s<="01000";
-- elsif (count=8)then s<="01001";
-- elsif (count=9)then s<="01010";
-- end if;
-- end if;
-- end process;
process(s)
begin --预分频数
if (S="00000") then Director_temp<="111011101110";--低音1
elsif(S="00001") then Director_temp<="110101001101";--低音2
elsif(S="00010") then Director_temp<="101111011010";
elsif(S="00011") then Director_temp<="101100101111";
elsif(S="00100") then Director_temp<="100111110111";
elsif(S="00101") then Director_temp<="100011100001";
elsif(S="00110") then Director_temp<="011111101001";
elsif(S="00111") then Director_temp<="011101110111";--中音1
elsif(S="01000") then Director_temp<="011010100111";
elsif(S="01001") then Director_temp<="010111101101";
elsif(S="01010") then Director_temp<="010110011000";
elsif(S="01011") then Director_temp<="010011111100";
elsif(S="01100") then Director_temp<="010001110000";
elsif(S="01101") then Director_temp<="001111110100";
elsif(S="01110") then Director_temp<="001110111100";--高音1
elsif(S="01111") then Director_temp<="001101010011";
elsif(S="10000") then Director_temp<="001011110110";
elsif(S="10001") then Director_temp<="001011001100";
elsif(S="10010") then Director_temp<="001001111110";
elsif(S="10011") then Director_temp<="001000111000";
elsif(S="10100") then Director_temp<="000111111010";
end if;
end process;
Director_o<=Director_temp;
end rtl;
仿真结果如下,可以看到在4Hz输入信号的激励下,输出乐谱对应的分频系数
顶层模块
先对输入的时间脉冲33.8688MHz进行16分频得到2MHz的时间脉冲输入数控分频器。使用同样的方法得到4Hz脉冲输入乐曲发生电路得到音调对应的分频系数,把分频系数输入数控分频器得到音调对应的频率的信号,再对此信号二分频以增强驱动能力。
代码如下
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity TonePlayer is
port(
TonePlayerClk_i:IN STD_LOGIC;
TonePlayerBeep_o:OUT STD_LOGIC);
end TonePlayer;
architecture rtl of TonePlayer is
component ClkDiv is
port(
clk_i:IN STD_LOGIC;
N_i: IN STD_LOGIC_VECTOR(11 DOWNTO 0);
clk_o:OUT STD_LOGIC);
end component;
component Director is
port(
Director_i : IN STD_LOGIC;
Director_o: OUT STD_LOGIC_VECTOR(11 downto 0)
);
end component;
signal N1: STD_LOGIC_VECTOR(11 DOWNTO 0):="000000011001";
signal Clk2M: STD_LOGIC:='0';
signal N2: STD_LOGIC_VECTOR(11 DOWNTO 0):="001111101000";
signal Clk2K: STD_LOGIC:='0';
signal N3: STD_LOGIC_VECTOR(11 DOWNTO 0):="000111110100";
signal Clk4Hz: STD_LOGIC:='0';
signal DirectorTemp: STD_LOGIC_VECTOR(11 downto 0):="000000000000";
signal N4: STD_LOGIC_VECTOR(11 DOWNTO 0):="000000000010";
signal TonePlayerBeep_Temp: STD_LOGIC:='0';
begin
Clock_Map: ClkDiv port map(
clk_i=>TonePlayerClk_i,
N_i=>N1,
clk_o=>Clk2M);
Clock_Map2: ClkDiv port map(
clk_i=>Clk2M,
N_i=>N2,
clk_o=>Clk2K);
Clock_Map3: ClkDiv port map(
clk_i=>Clk2K,
N_i=>N3,
clk_o=>Clk4Hz);
Director_Map: Director port map(
Director_i =>Clk4Hz,
Director_o=>DirectorTemp);
CORE_Map4: ClkDiv port map(
clk_i=>Clk2M,
N_i=>DirectorTemp,
clk_o=>TonePlayerBeep_Temp);
Drive_Map: ClkDiv port map(
clk_i=>TonePlayerBeep_Temp,
N_i=>N4,
clk_o=>TonePlayerBeep_o);
end rtl;
仿真结果,DirectorTemp指示了当前输出的音调,可以看到在音调的分界线处,驱动蜂鸣器的TonePlayerBeep_o频率明显改变。而且占空比为50%具有较强的驱动能力
VHDL 乐曲演奏电路设计的更多相关文章
- c语言乐曲演奏——《千本樱》
这个程序着实花费了我好长的时间,我本身对音乐一窍不通,先是跟着girl friend学习了简谱,根据c调44拍的<千本樱>写下了下面的程序. #include<stdio.h> ...
- 基于VHDL的8255可编程并行接口电路设计
一.实验题目名称: 8255可编程并行接口电路设计 二.实验目的.任务和要求: 实验目的:学习掌握基本的数字系统设计方法,建立自顶向下的设计思维,能够使用VHDL语言编写简单的应用IP核,掌握基本的F ...
- [转]MIDI常识20条
原文链接:http://www.midifan.com/modulearticle-detailview-488.htm Keyboard杂志老资格编辑Jim Aikin在纪念MIDI诞生20的时候发 ...
- 详解树莓派Model B+控制蜂鸣器演奏乐曲
步进电机以及无源蜂鸣器这些都需要脉冲信号才能够驱动,这里将用GPIO的PWM接口驱动无源蜂鸣器弹奏乐曲,本文基于树莓派Mode B+,其他版本树莓派实现时需参照相关资料进行修改! 1 预备知识 1.1 ...
- 如何用C程序简单演奏乐曲
如何用C程序简单演奏乐曲 首先我们要介绍一个函数: Beep(Frequency,time) 如果我们在程序中运行这个函数 Int main(void) { Beep(Frequency,time); ...
- verilog实验1:基于FPGA蜂鸣器演奏乐曲并数码管显示
一.实验任务 利用FPGA进行代码开发,使蜂鸣器演奏出乐曲<生日快乐>,将音调显示在数码管.原理为蜂鸣器为交流源蜂鸣器,在引脚上加一定频率的方波就可以发声,而且发声的频率由所加方波决定.这 ...
- Raspberry Pi开发之旅-控制蜂鸣器演奏乐曲
一.无源蜂鸣器和有源蜂鸣器 步进电机以及无源蜂鸣器这些都需要脉冲信号才能够驱动,这次尝试用GPIO的PWM接口驱动无源蜂鸣器弹奏一曲<一闪一闪亮晶晶>. 无源蜂鸣器: 无源内部没有震荡源, ...
- 基于VHDL利用PS2键盘控制的电子密码锁设计
基于VHDL利用PS2键盘控制的密码锁设计 附件:下载地址 中文摘要 摘 要:现代社会,人们的安全意识正在不断提升.按键密码锁由于其具有方便性.低成本等特征,还是大有用武之地的.但是通常的按键密码锁开 ...
- 3. 戏说VHDL之入门游戏一:流水灯
一. 流水灯 1.1流水灯原理 流水灯是每个学电子的入门“游戏” ,示意图如图1,其原理极其简单,但是可玩性却极强,可以就8个LED写出不同花样的程序.在1.2中我们列出两个不同思路的代码作为VH ...
随机推荐
- neuFlow&CNP-卷积计算加速器&神经网络加速芯片生态系统
上周看到韩松毕业论文,扯出神经网络加速器EIE,刚好这周调研了一下neuFlow,扯出09年的一篇做卷积加速的文章,大牛Lecun Yan的学生做的,一晃眼,快十年了.也记录之. 这一套还没研究透,又 ...
- linux下卸载mysql(rpm)
linux下卸载mysql 查看是否安装了mysql的组件 rpm –qa |grep –I mysql 卸载前关闭mysql服务 service mysql status service mysql ...
- flask框架----flask基础
知识点回顾 1.flask依赖wsgi,实现wsgi的模块:wsgiref,werkzeug,uwsgi 2.实例化Flask对象,里面是有参数的 app = Flask(__name__,templ ...
- python之常量和变量
局部和全局变量: # name='lhf' # def change_name(): # # global name # name='帅了一比' # print('change_name',name) ...
- 【shell脚本】通过遍历文件的一种批量执行shell命令的方法。
在分析数据时,经常会有许多机械重复的命令带入,作为一个半路出家的程序猿,我曾经对这种工作束手无策.不像一个熟手那样举重若轻的分析,感觉自己的生信分析完全是个体力活.为了打开这样的局面,我开始学习如何批 ...
- Eloquent JavaScript #06# class
索引 Notes this Prototype 类 class符号 覆盖派生属性 Maps Symbols iterator接口 Getters, setters, and statics 继承 in ...
- Kivy之常用的小知识
1.设置标题 app.title = '测试' 2.设置屏幕长度 Window.size=1000,600 3.设置屏幕右上角icon app.title = r'C:\Users\Administr ...
- API网关性能比较:NGINX vs. ZUUL vs. Spring Cloud Gateway vs. Linkerd(转)
前几天拜读了 OpsGenie 公司(一家致力于 Dev & Ops 的公司)的资深工程师 Turgay Çelik 博士写的一篇文章(链接在文末),文中介绍了他们最初也是采用 Nginx 作 ...
- ReentrantLock$Sync.tryRelease java.lang.IllegalMonitorStateException
早上一来,例行性的看主要环境的运行情况,发现有个环境中有如下异常: 17-02-28 08:13:37.368 ERROR pool-2-thread-65 com.ld.net.spider.Spi ...
- ldap集成confluence
confluence ldap配置跟jira ldap集成一样,请参考:https://www.cnblogs.com/imcati/p/9378668.html