⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vhdl infrared receive.txt

📁 VHDL程序
💻 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'&reg(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 + -