VHDL课程设计函数信号发生器Word文档格式.docx
《VHDL课程设计函数信号发生器Word文档格式.docx》由会员分享,可在线阅读,更多相关《VHDL课程设计函数信号发生器Word文档格式.docx(16页珍藏版)》请在冰豆网上搜索。
DEN
CHTFILT
RIGHTA
NMUA
按键信号
消抖模块
计数键模块
移复位键模块
选频模块
数码管模块
(动态扫描)
(频率计算)
PWM模块
(正弦波数据存储)
(分频比较)
信号发生器的原理框图
信号发生器的基本工作原理:
1、利用ROM、数组或使用CASE语句将计算的正弦波采样的占空比数据存储。
由分频器将FPGA上的晶振进行分频所得的时钟信号作为计数时钟。
最后进行利用比较的方式得到占空比可调的脉冲波。
同时,分频器的分频系数可由键盘和数码管配合的显示数值进行运算反馈回PWM模块,达到频率可调的目的。
此外,另设一输出接至LED2,无法测量波形的情况下,利用呼吸灯的效果可检测PWM模块的完成与频率可调的成功性。
2、键盘设移位复位键,数码管计数键与频率传送键。
同时设立消抖计数值,当按键按下以后进行计数,在按键退出后,停止计数,取最后一次计数作为按键信号完成按键消抖。
按下移位复位键,数码管位选下一位,同时示数复位清零,并且循环移位,当按完4次按键后,数码管全部清零。
按下数码管计数键,数码管计数,按一次计一次,采用十进制循环计数。
按下频率传送键,将数码管所显示的数值作为频率传送到PWM模块,设频率理论值范围10hz~99990hz。
3、用于按键显示的数码管计数的计数采用十进制。
设定的计数值由四位数码管动态显示,并且被设定的位选数码管‘.’点亮,表明该数码管被选中。
同时通电后,需利用移位复位功能将数码管清零。
五、系统分析:
1、根据原理图与原理框图:
系统电路可分成4个主干模块:
PWM模块、按键消抖模块、按键设定模块、数码管模块。
PWM:
通过对正弦波采样存储并利用时钟分频再进行比较获得PWM波,同时分频系数由按键与数码管陪和共同反馈运算结果进行分频。
按键消抖:
按键按下是会产生不稳定,设定何时的计数时间,再取按键拔起后获得的最后一次计数作为按键信号。
按键设定:
按键计数,按下后数码管进行计数。
移位复位,按下后数码管位选再移位与复位下一位数码管。
频率传送,将数码管示数作为频率传送到PWM模块。
数码管:
动态扫描,频率值显示在数码管上。
2、说明:
数码管显示不稳定,使用前先用移位复位键将示数清零。
测
六、程序设计:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
USEIEEE.NUMERIC_STD.ALL;
ENTITYzxb_maoIS
PORT(CLK:
INSTD_LOGIC;
RIGHTA:
--右移输入键
CNTFILT:
--频率选择键
RESTA:
--复位输入键
NUMA:
--按键计数输入键
PWM:
OUTSTD_LOGIC;
PWM_LED:
--LED亮灯
SMG:
OUTSTD_LOGIC_VECTOR(7DOWNTO0);
--数码管的段数据
DEN:
OUTSTD_LOGIC_VECTOR(3DOWNTO0));
--数码管的选通信号
ENDzxb_mao;
ARCHITECTUREsynOFzxb_maoIS
signala,b,c,d:
integerrange0to9;
--输入数
signalcnt:
integerrange0to50000000;
--调频频信号
signalnum:
--数码管显示计数
signalnum_1:
integerrange0to3;
--数码管位移数
signalcount:
--晶振分频计数
signalcount_key:
integerrange0to2499;
--键盘扫描分频
signalclkcnt:
std_logic;
--可调分频时钟
signalcout1:
integerrange0to255;
signalCOM:
--采样数据
signaltmp:
std_logic_vector(5downto0);
signalkey1filt:
std_logic;
--按键NUMA消抖后得到的信号
signalkey1cnt:
integerrange0to50000000;
--用于对NUMA按键输入有效时间进行计数
signalkey2filt:
--按键RIGHTA消抖后得到的信号
signalkey2cnt:
Integerrange0to50000000;
--用于对RIGHT_按键输入有效时间进行计数
signalkey3filt:
--按键CNTFILT消抖后得到的信号
signalkey3cnt:
--用于对LIFT_按键输入有效时间进行计数
signalcount1:
integerrange0to500000000;
signalcout2:
std_logic_vector(3downto0);
signalclk1hz:
signalclk100khz:
BEGIN
-----------------------------------PWM模块
PROCESS(CLK)
variabletmp:
integer;
--时钟分频实现频率可调
BEGIN
tmp:
=tmp;
IFrISing_edge(CLK)THEN
IFcount=cntthen
count<
=0;
CLKCNT<
='
1'
;
ELSE
count<
=count+1;
0'
ENDIF;
ENDIF;
ENDPROCESS;
PROCESS(CLKCNT)
IFrISing_edge(CLKCNT)THEN
IFcout1=255THEN
cout1<
tmp<
=tmp+1;
IFtmp="
111111"
then
tmp<
="
000000"
ENDIF;
ELSE
cout1<
=cout1+1;
ENDPROCESS;
process(tmp)--正弦波数据采样存储
begin
caseconv_integer(tmp)is
when00=>
COM<
=255;
when01=>
=254;
when02=>
=252;
when03=>
=249;
when04=>
=245;
when05=>
=239;
when06=>
=233;
when07=>
=225;
when08=>
=217;
when09=>
=207;
when10=>
=197;
when11=>
=186;
when12=>
=174;
when13=>
=162;
when14=>
=150;
when15=>
=137;
when16=>
=124;
when17=>
=112;
when18=>
=99;
when19=>
=87;
when20=>
=75;
when21=>
=64;
when22=>
=53;
when23=>
=43;
when24=>
=34;
when25=>
=26;
when26=>
=19;
when27=>
=13;
when28=>
=8;
when29=>
=4;
when30=>
=1;
when31=>
when63=>
when62=>
when61=>
when60=>
when59=>
when58=>
when57=>
when56=>
when55=>
when54=>
when53=>
when52=>
when51=>
when50=>
when49=>
when48=>
when47=>
when46=>
when45=>
=99;
when44=>
when43=>
when42=>
when41=>
=53;
when40=>
when39=>
when38=>
when37=>
=19;
when36=>
when35=>
when34=>
when33=>
=1;
when32=>
whenothers=>
null;
endcase;
IFcout1>
COMTHEN--比较计数采样PWM
PWM<
PWM_LED<
--LED实现PWM检测
PWM<
PWM_LED<
------------------------------------按键消抖模块
PROCESS(NUMA)--NUMA按键消抖
constantN:
integer:
=5000000;
--消抖时间,对于50Mhz的基准时钟,这相当于0.1S
BEGIN
IFCLK'
eventandCLK='
THEN
IFNUMA='
THEN--当key1输入低电平,即按键按下
IFkey1cnt/=NTHEN--一直计数到N
key1cnt<
=key1cnt+1;
ENDIF;
IFkey1cnt=N-1THEN--最后一个计数时输出key1filt脉冲
key1filt<
='
ELSE--若key1输入高电平,表明按键被释放
key1cnt<
=0;
PROCESS(RIGHTA)--RIGHTA按键消抖
IFRIGHTA='
THEN
IFkey2cnt/=NTHEN
key2cnt<
=key2cnt+1;
IFkey2cnt=N-1THEN
key2filt<
ELSE
key2cnt<
PROCESS(CNTFILT)--CNTFILT按键消抖
IFCNTFILT='
IFkey3cnt/=NTHEN
key3cnt<
=key3cnt+1;
IFkey3cnt=N-1THEN
key3filt<
key3cnt<
------------------------------------四进制计数移动模块RIGHTA
PROCESS(key2filt)
IF(key2filt='
)THEN--按键RIGHTA经消抖处理后
IFnum_1=3THEN
num_1<
ELSE
=num_1+1;
----------------------------------------十进制计数模块NUMA,RIGHT_,LIFT_
IFcount_key=249THEN
count_key<
clk100khz<
count_key<
=count_key+1;
PROCESS(clk100khz,key1filt,key2filt)
IFkey2filt='
THEN--复位与移位复位
num<
=0after50ns;
IF(key1filt='
)THEN--按键NUMA经消抖处理后
IFnum=9THEN
num<
=num+1;
---------------------------------------输入寄存模块
PROCESS(num,num_1)
CASEnum_1IS
WHEN0=>
a<
=num;
WHEN1=>
b<
WHEN2=>
c<
WHEN3=>
d<
WHENothers=>
NULL;
ENDCASE;
------------------------------------------------按键选定频率模块
PROCESS(key3filt)
IFkey3filt='
THEN
cnt<
=50000000/(((a*1000+1)+(b*100+1)+(c*10+1)+(d*1+1))*256*64);
--实现频率可调
------------------------------------------------数码管动态扫描频率及显示模块
PROCESS(CLK)
IFcount1=24999THEN
count1<
clk1hz<
count1<
=count1+1;
PROCESS(clk1hz)
IFrISing_edge(clk1hz)THEN
IFcout2="
1000"
THEN
cout2<
0000"
cout2<
=cout2+1;
IFcout2="
DEN<
0111"
CASEaIS
SMG<
="
11000000"
--0
11111001"
--1
10100100"
--2
10110000"
--3
WHEN4=>
10011001"
--4
WHEN5=>
10010010"
--5
WHEN6=>
10000010"
--6
WHEN7=>
11111000"
--7
WHEN8=>
10000000"
--8
WHEN9=>
10010000"
--9
IFnum_1=0andcout2="
0001"
SMG<
01111111"
DEN<
IFcout2="
0010"
1011"
CASEbIS
IFnum_1=1andcout2="
0011"
0100"
1101"
CASEcIS
ENDCASE;
IFnum_1=2andcout2="
0101"
SMG<
DEN<
0110"
1110"
CASE