from machine import Pin
import time
# ---------- 引脚定义 ----------
LED_RED = Pin(2, Pin.OUT) # 红灯
LED_YELLOW = Pin(0, Pin.OUT) # 黄灯
LED_GREEN = Pin(4, Pin.OUT) # 绿灯
BUTTON = Pin(12, Pin.IN, Pin.PULL_UP) # 按键,内部上拉
# ---------- 全局变量 ----------
running = False # 交通灯是否运行
state = 0 # 当前状态:0-红灯,1-绿灯,2-黄灯亮,3-黄灯灭
flash_count = 0 # 黄灯闪烁已完成的次数(一对亮灭算1次)
state_start = 0 # 进入当前状态时的 ticks_ms
last_button = 1 # 上一次读取的按键电平(1=未按)
DEBOUNCE_MS = 20 # 消抖时间(毫秒)
last_press_time = 0 # 上次有效按下的时间
# 时间参数(毫秒)
RED_TIME = 5000 # 红灯亮 5 秒
GREEN_TIME = 4000 # 绿灯亮 4 秒
YELLOW_ON = 500 # 黄灯亮 0.5 秒
YELLOW_OFF = 500 # 黄灯灭 0.5 秒
FLASH_TIMES = 3 # 闪烁次数
# 所有 LED 初始熄灭
LED_RED.value(0)
LED_YELLOW.value(0)
LED_GREEN.value(0)
def all_leds_off():
"""熄灭所有灯"""
LED_RED.value(0)
LED_YELLOW.value(0)
LED_GREEN.value(0)
def set_leds(red, yellow, green):
"""便捷设置三灯状态"""
LED_RED.value(red)
LED_YELLOW.value(yellow)
LED_GREEN.value(green)
def start_new_cycle():
"""开始一个新的交通灯循环,从红灯开始"""
global state, flash_count, state_start
state = 0
flash_count = 0
state_start = time.ticks_ms()
set_leds(1, 0, 0) # 红灯亮
# ---------- 主循环 ----------
while True:
now = time.ticks_ms()
# ----- 按键检测(下降沿触发,带消抖) -----
btn_val = BUTTON.value()
if btn_val == 0 and last_button == 1: # 下降沿:从未按到按下
if time.ticks_diff(now, last_press_time) > DEBOUNCE_MS:
last_press_time = now
running = not running # 切换运行状态
if running:
start_new_cycle() # 启动循环
else:
all_leds_off() # 停止:熄灭所有灯
last_button = btn_val
# ----- 交通灯状态机(仅在 running 状态下执行) -----
if running:
elapsed = time.ticks_diff(now, state_start)
if state == 0: # 红灯亮
if elapsed >= RED_TIME:
# 切换到绿灯
state = 1
state_start = now
set_leds(0, 0, 1) # 绿灯亮
elif state == 1: # 绿灯亮
if elapsed >= GREEN_TIME:
# 切换到黄灯闪烁序列,先进入黄灯亮状态
state = 2
flash_count = 0
state_start = now
set_leds(0, 1, 0) # 黄灯亮
elif state == 2: # 黄灯亮
if elapsed >= YELLOW_ON:
# 黄灯灭
state = 3
state_start = now
set_leds(0, 0, 0) # 黄灯灭
elif state == 3: # 黄灯灭
if elapsed >= YELLOW_OFF:
flash_count += 1
if flash_count < FLASH_TIMES:
# 继续下一次闪烁:黄灯亮
state = 2
state_start = now
set_leds(0, 1, 0)
else:
# 闪烁完成,回到红灯,开始新循环
state = 0
flash_count = 0
state_start = now
set_leds(1, 0, 0) # 红灯亮
# 稍作休眠,降低 CPU 占用,同时不影响按键响应
time.sleep_ms(10)