远书归梦两悠悠,只有空床敌素秋。
阶下青苔与红树,雨中寥落月中愁。
————《端居》 【唐】 李商隐
目录
通过网盘分享的文件:交通信号灯.zip链接: https://pan.baidu.com/s/1sA2fTJjQyzZZkVVl4b7XfA?pwd=b2vg 提取码: b2vg
交通信号灯
要点剖析:
1.设计两组信号灯,一组主干道,一组副干道,每组灯都有三种颜色(红黄绿)。
2.主干道:四十秒通行,副干道:二十秒通行;意味着主干道的绿灯亮起时间为40秒,红灯亮起时间为20秒;同样的副干道的绿灯亮起时间为20秒,红灯亮起时间为40秒。
3.每次变灯要有黄灯亮起3秒,每秒闪烁一次,共闪烁三次。
端口说明:
clk:时钟分配
a组的红黄绿灯
b组的红黄绿灯
这个实验相对简单,不需要太多端口。
代码展示:(VHDL)
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity traffic_light_controller is
Port (
clk : in STD_LOGIC; -- 时钟输入
reset : in STD_LOGIC; -- 复位信号
-- 主干道A(东西方向)信号灯
a_red : out STD_LOGIC; -- 红灯
a_yellow: out STD_LOGIC; -- 黄灯
a_green : out STD_LOGIC; -- 绿灯
-- 副干道B(南北方向)信号灯
b_red : out STD_LOGIC; -- 红灯
b_yellow: out STD_LOGIC; -- 黄灯
b_green : out STD_LOGIC -- 绿灯
);
end traffic_light_controller;
architecture Behavioral of traffic_light_controller is
-- 定义状态类型
type state_type is (
A_GREEN_B_RED, -- 主干道绿灯,副干道红灯
A_YELLOW_B_RED, -- 主干道黄灯,副干道红灯
A_RED_B_GREEN, -- 主干道红灯,副干道绿灯
A_RED_B_YELLOW -- 主干道红灯,副干道黄灯
);
signal current_state, next_state : state_type;
signal counter : integer range 0 to 40 := 0; -- 计时器,最大40秒
signal yellow_blink : STD_LOGIC := '0'; -- 黄灯闪烁控制信号
signal blink_counter : integer range 0 to 50000000 := 0; -- 用于黄灯闪烁的计数器
-- 时钟频率假设为50MHz(0.02us周期),1秒需要50000000个周期
constant BLINK_INTERVAL : integer := 50000000; -- 1秒闪烁一次
begin
-- 状态寄存器
process(clk, reset)
begin
if reset = '1' then
current_state <= A_GREEN_B_RED;
counter <= 0;
blink_counter <= 0;
yellow_blink <= '0';
elsif rising_edge(clk) then
current_state <= next_state;
-- 黄灯闪烁控制
if current_state = A_YELLOW_B_RED or current_state = A_RED_B_YELLOW then
if blink_counter < BLINK_INTERVAL then
blink_counter <= blink_counter + 1;
else
blink_counter <= 0;
yellow_blink <= not yellow_blink;
end if;
else
blink_counter <= 0;
yellow_blink <= '1'; -- 非黄灯状态时保持常亮(实际不会用到)
end if;
-- 主计数器
if counter > 0 then
counter <= counter - 1;
else
-- 根据当前状态设置下一个状态的计数器
case current_state is
when A_GREEN_B_RED =>
counter <= 3; -- 黄灯亮3秒
when A_YELLOW_B_RED =>
counter <= 20; -- 副干道绿灯20秒
when A_RED_B_GREEN =>
counter <= 3; -- 黄灯亮3秒
when A_RED_B_YELLOW =>
counter <= 40; -- 主干道绿灯40秒
when others =>
counter <= 0;
end case;
end if;
end if;
end process;
-- 状态转换逻辑
process(current_state, counter)
begin
case current_state is
when A_GREEN_B_RED =>
if counter = 0 then
next_state <= A_YELLOW_B_RED;
else
next_state <= A_GREEN_B_RED;
end if;
when A_YELLOW_B_RED =>
if counter = 0 then
next_state <= A_RED_B_GREEN;
else
next_state <= A_YELLOW_B_RED;
end if;
when A_RED_B_GREEN =>
if counter = 0 then
next_state <= A_RED_B_YELLOW;
else
next_state <= A_RED_B_GREEN;
end if;
when A_RED_B_YELLOW =>
if counter = 0 then
next_state <= A_GREEN_B_RED;
else
next_state <= A_RED_B_YELLOW;
end if;
when others =>
next_state <= A_GREEN_B_RED;
end case;
end process;
-- 输出逻辑
process(current_state, yellow_blink)
begin
-- 默认值
a_red <= '0'; a_yellow <= '0'; a_green <= '0';
b_red <= '0'; b_yellow <= '0'; b_green <= '0';
case current_state is
when A_GREEN_B_RED =>
a_green <= '1';
b_red <= '1';
when A_YELLOW_B_RED =>
a_yellow <= yellow_blink; -- 黄灯闪烁
b_red <= '1';
when A_RED_B_GREEN =>
a_red <= '1';
b_green <= '1';
when A_RED_B_YELLOW =>
a_red <= '1';
b_yellow <= yellow_blink; -- 黄灯闪烁
when others =>
a_red <= '1';
b_red <= '1';
end case;
end process;
end Behavioral;
重点部分解释:
process(clk, reset)
begin
if reset = '1' then
current_state <= A_GREEN_B_RED;
counter <= 0;
blink_counter <= 0;
yellow_blink <= '0';
elsif rising_edge(clk) then
current_state <= next_state;
-- 黄灯闪烁控制
if current_state = A_YELLOW_B_RED or current_state = A_RED_B_YELLOW then
if blink_counter < BLINK_INTERVAL then
blink_counter <= blink_counter + 1;
else
blink_counter <= 0;
yellow_blink <= not yellow_blink;
end if;
else
blink_counter <= 0;
yellow_blink <= '1';
end if;
-- 主计数器
if counter > 0 then
counter <= counter - 1;
else
-- 状态转换时重置计数器
case current_state is
when A_GREEN_B_RED => counter <= 3; -- 黄灯3秒
when A_YELLOW_B_RED => counter <= 20; -- 副干道绿灯20秒
when A_RED_B_GREEN => counter <= 3; -- 黄灯3秒
when A_RED_B_YELLOW => counter <= 40; -- 主干道绿灯40秒
when others => counter <= 0;
end case;
end if;
end if;
end process;
这个进程实现:
1. 复位功能
2. 状态寄存器更新
3. 黄灯闪烁控制(每秒翻转一次)
4. 主计数器控制,在不同状态转换时设置不同的计数值
process(current_state, counter)
begin
case current_state is
when A_GREEN_B_RED =>
if counter = 0 then
next_state <= A_YELLOW_B_RED;
else
next_state <= A_GREEN_B_RED;
end if;
when A_YELLOW_B_RED =>
if counter = 0 then
next_state <= A_RED_B_GREEN;
else
next_state <= A_YELLOW_B_RED;
end if;
when A_RED_B_GREEN =>
if counter = 0 then
next_state <= A_RED_B_YELLOW;
else
next_state <= A_RED_B_GREEN;
end if;
when A_RED_B_YELLOW =>
if counter = 0 then
next_state <= A_GREEN_B_RED;
else
next_state <= A_RED_B_YELLOW;
end if;
when others =>
next_state <= A_GREEN_B_RED;
end case;
end process;
这个组合逻辑进程根据当前状态和计数器值决定下一状态,实现状态机的转换。
process(current_state, yellow_blink)
begin
-- 默认值
a_red <= '0'; a_yellow <= '0'; a_green <= '0';
b_red <= '0'; b_yellow <= '0'; b_green <= '0';
case current_state is
when A_GREEN_B_RED =>
a_green <= '1';
b_red <= '1';
when A_YELLOW_B_RED =>
a_yellow <= yellow_blink; -- 黄灯闪烁
b_red <= '1';
when A_RED_B_GREEN =>
a_red <= '1';
b_green <= '1';
when A_RED_B_YELLOW =>
a_red <= '1';
b_yellow <= yellow_blink; -- 黄灯闪烁
when others =>
a_red <= '1';
b_red <= '1';
end case;
end process;
这个进程根据当前状态设置信号灯的输出,注意黄灯输出与闪烁信号相连实现闪烁效果。
代码工作流程:
1. 初始状态:`A_GREEN_B_RED`(主干道绿灯,副干道红灯),持续40秒
2. 第一次转换:40秒后转为`A_YELLOW_B_RED`(主干道黄灯闪烁,副干道红灯),持续3秒
3. 第二次转换:转为`A_RED_B_GREEN`(主干道红灯,副干道绿灯),持续20秒
4. 第三次转换:转为`A_RED_B_YELLOW`(主干道红灯,副干道黄灯闪烁),持续3秒
5. 循环:回到初始状态`A_GREEN_B_RED`,形成完整循环
编译结果:
通过网盘分享的文件:交通信号灯.zip
链接: https://pan.baidu.com/s/1sA2fTJjQyzZZkVVl4b7XfA?pwd=b2vg 提取码: b2vg