📄 vhdl infrared receive.txt
字号:
接收解码部分
接收解码用VHDL语言编写程序,在EDA实验板上实现解码,要求具有以下功能:
(1)基本要求:
(a)将一体化红外接收解调器的输出信号解码(12个单击键、6个连续键,单击键编号为7-18,连续键编码为1-6),在EDA实验板上用七段数码管显示出来;
(b)当按下遥控器1—6号连续键时,在EDA实验板上用发光二极管点亮作为连续键按下的指示,要求遥控器上连续键接下时指示灯点亮,直到松开按键时才熄灭,用于区别单击键。
(c)EDA实验板上设置四个按键,其功能等同于遥控器上的1—4号按键,当按下此四个按键时七段数码管分别对应显示“1”、“2”、“3”、“4”。
(d)每当接收到有效按键时,蜂鸣器会发出提示音。
五、 源程序
library ieee;
use ieee.std_logic_1164.all;
--输入频率8kHz,对2048kHz256分频
--红外接收,解码,输出
entity p0 is
port (clock,reset,din:in std_logic; --时钟、复位、红外信号输入
led : out std_logic; --连续键、单击键指示灯
ring: out std_logic; --蜂鸣器
key : in std_logic_vector(0 to 3); --键盘输入
digit:buffer std_logic_vector(0 to 3); --数码管位扫描信号
dout4511: out std_logic_vector(0 to 3)); --数码管数值
end p0;
architecture behav of p0 is
signal user:std_logic_vector(0 to 3); --用户码
signal num:std_logic_vector(0 to 7); --按键码
begin
--红外接收,译码,键盘扫描
process(reset,clock)
type state_type is(WAIT0,WAIT1,COUNT,DECODE,CLEAR);
variable state:state_type;
variable dcnt:integer range 0 to 12; --位数
variable cnt :integer range 0 to 20; --低电平持续时间
variable LCnt:integer range 0 to 60; --LED延时
variable RCnt:integer range 0 to 60; --Ring延时
variable reg :std_logic_vector(0 to 11); --移位寄存器
begin
if (reset='1') then --复位设置
cnt:=0;
dcnt:=0;
reg:="000000000000";
state:=WAIT0;
ring<='0';
LCnt:=0;
RCnt:=0;
else
if (rising_edge(clock)) then
case state is
when WAIT0 => --等待低电平输入
cnt:=0;
if (key/="1111") then --键盘扫描
case key is
when "0111"=> num<="00000001";
when "1011"=> num<="00000010";
when "1101"=> num<="00000011";
when "1110"=> num<="00000100";
when others => num<="00000000";
end case;
LCnt:=60;
RCnt:=60;
end if;
if (LCnt>0) then --按LCnt开关LED
LCnt:=LCnt-1;
led<='0';
else
led<='1';
end if;
if (RCnt>0) then --按RCnt开关蜂鸣器
RCnt:=RCnt-1;
ring<='1';
else
ring<='0';
end if;
if (din='0') then
state:=WAIT1;
else
state:=WAIT0;
end if;
when WAIT1 => --对低电平的时间进行计数,等待高电平输入结束计数
cnt:=cnt+1;
if (din='0') then
state:=WAIT1;
else
if (cnt>5) then --根据低电平的持续时间,判断输入是0还是1,并记录
reg:=reg(1 to 11)&'1';
else
reg:=reg(1 to 11)&'0';
end if;
state:=COUNT;
end if;
when COUNT => --对已经输入的位数进行计数
if (dcnt>=11) then
dcnt:=0;
state:=DECODE;
else
dcnt:=dcnt+1;
state:=WAIT0;
end if;
when DECODE => --分离用户码和按键码,并译码
user<='0'®(2 downto 0);
case reg(3 to 11) is
when "100100000" => num<="00000001";
when "100010000" => num<="00000010";
when "100001000" => num<="00000011";
when "100000100" => num<="00000100";
when "100000010" => num<="00000101";
when "100000001" => num<="00000110";
when "010100000" => num<="00000111";
when "010010000" => num<="00001000";
when "010001000" => num<="00001001";
when "010000100" => num<="00010000";
when "010000010" => num<="00010001";
when "010000001" => num<="00010010";
when "001100000" => num<="00010011";
when "001010000" => num<="00010100";
when "001001000" => num<="00010101";
when "001000100" => num<="00010110";
when "001000010" => num<="00010111";
when "001000001" => num<="00011000";
when others => num<="00000000";
end case;
if (reg(3)='1') then
LCnt:=60; --启动LED的计数器
end if;
RCnt:=60; --启动Ring的计数器
state:=CLEAR;
when CLEAR => --清除移位寄存器的数据,准备下一组编码的输入
reg:="000000000000";
state:=WAIT0;
end case;
end if;
end if;
end process;
--显示
process(clock,reset)
variable dt:std_logic_vector(0 to 3);
begin
if (reset='1') then
dt:="0001";
else
if (rising_edge(clock)) then
dt:=dt(1 to 3)&dt(0);
digit<=dt;
case dt is
when "0001" => dout4511<=num(4 to 7); --显示按键码的各位
when "0010" => dout4511<=num(0 to 3); --显示按键码的十位
when "1000" => dout4511<=user; --显示用户码
when others => dout4511<="1111"; --空一位,不显示
end case;
end if;
end if;
end process;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -