怎样用FPGA实现FSK调制解调?

怎样用FPGA实现FSK调制解调?,第1张

library ieeeuse ieee.std_logic_arith.alluse ieee.std_logic_1164.--此进程完成对基带信号的FSK调制 begin if clk'event and clk='1' then

library ieee

use ieee.std_logic_arith.all

use ieee.std_logic_1164.all

use ieee.std_logic_unsigned.all

entity PL_FSK isport(clk :in std_logic--系统时钟

start :in std_logic--开始调制信号

x :in std_logic--基带信号

y :out std_logic)--调制信号

end PL_FSK

architecture behav of PL_FSK is

signal q1:integer range 0 to 11--载波信号f1的分频计数器

signal q2:integer range 0 to 3--载波信号f2的分频计数器

signal f1,f2:std_logic--载波信号

f1,f2beginprocess(clk) --此进程通过对系统时钟clk的分频,得到载波f1

begin

if clk'event and clk='1'

then if start='0' then q1<=0

elsif q1<=5 then f1<='1'

q1<=q1+1--改变q1后面的数字可以改变,载波f1的占空比

elsif q1=11 then f1<='0'

q1<=0--改变q1后面的数字可以改变,载波f1的频率

else f1<='0'

q1<=q1+1

end if

end if

end process

process(clk) --此进程通过对系统时钟clk的分频,得到载波f2beginif clk'event and clk='1'

then

if start='0'

then q2<=0

elsif q2<=0

then f2<='1'

q2<=q2+1--改变q2后面的数字可以改变,载波f2的占空比

elsif q2=1 then f2<='0'

q2<=0--改变q2后面的数字可以改变,载波f2的频率

else f2<='0'

q2<=q2+1

end if

end if

end process

process(clk,x) --此进程完成对基带信号的FSK调制

begin

if clk'event and clk='1' then

if x='0' then y<=f1--当输入的基带信号x=‘0’时,输出的调制信号y为f1

else y<=f2--当输入的基带信号x=‘1’时,输出的调制信号y为f2

end if

end if

end process

end behav

----------

----时钟:10MHZ

library ieee

use ieee.std_logic_1164.all

use ieee.std_logic_unsigned.all

entity lcd12864 is

generic(

divide_500k:integer:=20--20分频后:500KHZ:2us

cnt1_value:integer:=50

)

port(

clk,reset:in std_logic

rs,rw,en:out std_logic

data:out std_logic_vector(7 downto 0)

)

end entity

architecture behavior of lcd12864 is

type word is array(0 to 3) of std_logic_vector(7 downto 0)--因为大家的习惯,数组中的左起第1个数为数组中的最低位对应的数,所以设置为array(0 to 3),而不是array(3 downto 0)。此处若不注意,容易出错。

type state is(

set_dlnf1,set_dlnf2,set_cursor,set_dcb,set_shift,

set_ddram,

write_name,

over

)

constant name:word:=("11010110","11010000","10111001","11111010")--中D6D0 国B9FA

--constant name:word:=("11010000","11101100","10111110","10101001")--徐D6D0 京B9FA

signal pr_state:state

signal newclk:std_logic

begin

process(clk) is

variable num:integer range 0 to divide_500k

begin

if(clk'event and clk='1')then

num:=num+1

if(num=divide_500k) then

num:=0

end if

if(num<divide_500k/2) then--设置占空比

newclk<='0'

else newclk<='1'

end if

end if

end process

process(newclk,reset,pr_state) is

variable cnt1:integer range 0 to 100*cnt1_value:=0

variable cnt2:integer range 0 to 100:=0

begin

if(reset='0') then

pr_state<=set_dlnf1 --把状态set_dlnf1赋于pr_state

cnt1:=0

cnt2:=0

en<='0'

data<="ZZZZZZZZ"

elsif(newclk'event and newclk='1') then

case pr_state is

when set_dlnf1=>

cnt1:=cnt1+1

if(cnt1<cnt1_value) then

en<='0'

rs<='0' --命令

rw<='0' --写

elsif(cnt1<2*cnt1_value) then

data<="00110000"--选择8位数据基本指令集:0x30

elsif(cnt1<20*cnt1_value) then

en<='1'

elsif(cnt1=20*cnt1_value) then

en<='0'

cnt1:=0

pr_state<=set_dlnf2

end if

when set_dlnf2=>

cnt1:=cnt1+1

if(cnt1<cnt1_value) then

en<='0'

elsif(cnt1<2*cnt1_value) then

data<="00110000"--选择8位数据基本指令集:0x30

elsif(cnt1<20*cnt1_value) then

en<='1'

elsif(cnt1=20*cnt1_value) then

en<='0'

cnt1:=0

pr_state<=set_cursor

end if

when set_cursor=>

cnt1:=cnt1+1

if(cnt1<cnt1_value) then

en<='0'

elsif(cnt1<2*cnt1_value) then

data<="00001100"--整体显示设置:光标OFF 反光0FF:0x0c

elsif(cnt1<20*cnt1_value) then

en<='1'

elsif(cnt1=20*cnt1_value) then

en<='0'

cnt1:=0

pr_state<=set_dcb

end if

when set_dcb=>

cnt1:=cnt1+1

if(cnt1<cnt1_value) then

en<='0'

elsif(cnt1<2*cnt1_value) then

data<="00000001"--清除显示,并且认定地址指针为00h:0x01

elsif(cnt1<20*cnt1_value) then

en<='1'

elsif(cnt1=20*cnt1_value) then

en<='0'

cnt1:=0

pr_state<=set_shift

end if

when set_shift=>

cnt1:=cnt1+1

if(cnt1<cnt1_value) then

en<='0'

elsif(cnt1<2*cnt1_value) then

data<="00000110"--指定游标的移动方向及指定显示的移位:0x06

elsif(cnt1<20*cnt1_value) then

en<='1'

elsif(cnt1=20*cnt1_value) then

en<='0'

cnt1:=0

pr_state<=set_ddram

end if

when set_ddram=>

cnt1:=cnt1+1

if(cnt1<cnt1_value) then

en<='0'

elsif(cnt1<2*cnt1_value) then

data<="10000011"--从第一行的第一个字开始显示:0x80

--从第一行的第四个字开始显示:0x80+3

elsif(cnt1<20*cnt1_value) then

en<='1'

elsif(cnt1=20*cnt1_value) then

en<='0'

cnt1:=0

pr_state<=write_name

end if

when write_name=>

cnt1:=cnt1+1

if cnt1<1*cnt1_value then

en<='0'

rs<='1' ------------选择数据

rw<='0'

elsif cnt1<2*cnt1_value then

data<=name(cnt2) ------------送数据

elsif cnt1<20*cnt1_value then

en<='1'-----在上升沿时,数据才能写入液晶,所以要先送数据,再让使能端变高

elsif cnt1=20*cnt1_value then

en<='0' -----通过液晶的时序图知:使能端先低,送数据,使能端升高,再变低。

cnt1:=0

cnt2:=cnt2+1

if cnt2=4 then----倘若使能端的触发方式错误,此处也许要大于4的数才有显示

pr_state<=over

cnt2:=0

end if

end if

when over=>

null

when others=>

en<='Z'

rs<='Z'

rw<='Z'

data<=(others=>'Z')

cnt1:=0

cnt2:=0

end case

end if

end process

end architecture

这个液晶程序,花了十来天的时间,今天总算与它有了了结。程序中,之所以只在第一行的第四列起,显示了“中国”两个字,主要是简单,便于网友理解。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/12151859.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-21
下一篇2023-05-21

发表评论

登录后才能评论

评论列表(0条)

    保存