基于51单片机的智能交通信号灯控制系统Protues仿真设计
目录一、设计背景二、实现功能三、仿真结果1正常运行——东西绿灯2正常运行——南北绿灯3紧急模式4东西优先通行5南北优先通行6时长切换四、代码实现五、状态机总览六、引脚分配一览七、关键参数八、总结源文件获取一、设计背景交通信号灯是城市交通管理的核心设备直接关系到道路通行效率和行车安全。传统的机械式定时信号灯功能单一无法应对紧急车辆通行、特殊事件管制等突发场景。随着嵌入式技术的发展基于单片机的智能交通信号灯控制系统逐渐成为主流方案。51单片机具有成本低、体积小、易于开发等优势能够为系统提供可靠的硬件支持。通过单片机控制LED信号灯和数码管倒计时显示结合按键输入实现多种运行模式的切换可以满足日常交通指挥和紧急场景的需求。该系统不仅实现了基本的红绿黄灯循环控制还加入了紧急模式、方向优先通行、通行时长切换等智能功能具有较高的实用价值和教学意义。二、实现功能1使用STC89C52单片机作为主控制器通过P1口控制东西/南北方向的6个LED信号灯红、黄、绿各2个高电平驱动。2使用6位共阳数码管P0段选、P2.0~P2.5位选显示东西和南北方向的倒计时单位为秒动态扫描刷新。34个独立按键P3.0~P3.3低电平有效实现以下功能K1紧急模式按下后四方向黄灯闪烁5秒 → 全红灯禁行再次按下恢复正常循环。K2东西优先按下后黄灯闪烁5秒过渡 → 东西绿灯长亮、南北红灯长亮再次按下退出。K3南北优先按下后黄灯闪烁5秒过渡 → 南北绿灯长亮、东西红灯长亮再次按下退出。K4时长切换切换绿灯通行时间 60秒 ↔ 120秒模式指示灯同步指示。4正常运行状态下4个状态自动循环东西绿灯 → 东西黄闪 → 南北绿灯 → 南北黄闪倒计时最后5秒自动切换到黄灯闪烁警示。5黄灯闪烁频率1Hz500ms亮/500ms灭由定时器T0中断精确控制。三、仿真结果1正常运行——东西绿灯上电后系统自动进入东西绿灯状态东西方向绿灯亮、南北方向红灯亮数码管从60秒开始倒计时。当倒计时进入最后5秒时东西黄灯开始闪烁提示即将变灯。2正常运行——南北绿灯东西黄灯闪烁结束后切换到南北绿灯状态南北方向绿灯亮、东西方向红灯亮数码管重新从60秒开始倒计时。最后5秒南北黄灯闪烁然后回到东西绿灯循环往复。3紧急模式按下K1键紧急模式四方向黄灯同时闪烁5秒紧急警示随后自动切换为四方向全红灯禁行。数码管显示关闭。再次按下K1键退出紧急模式恢复东西绿灯正常循环。4东西优先通行按下K2键东西优先通行四方向黄灯闪烁5秒过渡警示然后东西绿灯长亮、南北红灯长亮数码管显示关闭。此状态下再次按下K2键退出恢复正常循环。5南北优先通行按下K3键南北优先通行四方向黄灯闪烁5秒过渡警示然后东西红灯长亮、南北绿灯长亮数码管显示关闭。此状态下再次按下K3键退出恢复正常循环。6时长切换按下K4键60/120秒准行时间切换绿灯通行时间从60秒切换为120秒P1.6模式指示灯熄灭灭120s模式。再次按下K4键切回60秒指示灯亮起。切换在绿灯状态下立即生效。四、代码实现/* * 智能交通信号灯控制系统 * 单片机STC89C52 * 晶振12MHz * * 硬件配置 * - 数码管共阳(CA)段选P0低电平有效位选P2.0-P2.5高电平有效 * - 按键K1-K4P3.0-P3.3低电平有效 * - LED红黄绿P1.0-P1.5高电平有效 * - 模式指示灯P1.6低电平有效 */ #include reg52.h /* 包含51单片机寄存器定义头文件 */ /* IO口定义 */ #define SEG_PORT P0 /* 数码管段选端口定义共阳低电平点亮段 */ /* P2.0-P2.5 控制6位数码管位选高电平有效 */ /* P2.0东西百位, P2.1东西十位, P2.2东西个位 */ /* P2.3南北百位, P2.4南北十位, P2.5南北个位 */ sbit LED_EW_GREEN P1^0; /* 东西方向绿灯高电平有效 */ sbit LED_EW_YELLOW P1^1; /* 东西方向黄灯高电平有效 */ sbit LED_EW_RED P1^2; /* 东西方向红灯高电平有效 */ sbit LED_NS_GREEN P1^3; /* 南北方向绿灯高电平有效 */ sbit LED_NS_YELLOW P1^4; /* 南北方向黄灯高电平有效 */ sbit LED_NS_RED P1^5; /* 南北方向红灯高电平有效 */ sbit LED_MODE P1^6; /* 模式指示灯低电平有效亮60s灭120s */ sbit KEY_EMERGENCY P3^0; /* K1紧急模式按键低电平有效 */ sbit KEY_EW_FIRST P3^1; /* K2东西优先通行按键低电平有效 */ sbit KEY_NS_FIRST P3^2; /* K3南北优先通行按键低电平有效 */ sbit KEY_MODE P3^3; /* K460s/120s准行时间切换按键低电平有效 */ /* 共阳数码管段码表 0-9 */ /* 共阳数码管段选低电平点亮段码取反 */ /* 段顺序dp g f e d c b a 对应 P0.7~P0.0 */ code unsigned char seg_table[] { 0xC0, /* 0: a b c d e f 亮, g dp 灭 */ 0xF9, /* 1: b c 亮, 其余灭 */ 0xA4, /* 2: a b d e g 亮, c f dp 灭 */ 0xB0, /* 3: a b c d g 亮, e f dp 灭 */ 0x99, /* 4: b c f g 亮, a d e dp 灭 */ 0x92, /* 5: a c d f g 亮, b e dp 灭 */ 0x82, /* 6: a c d e f g 亮, b dp 灭 */ 0xF8, /* 7: a b c 亮, d e f g dp 灭 */ 0x80, /* 8: 全亮, dp 灭 */ 0x90 /* 9: a b c d f g 亮, e dp 灭 */ }; /* 状态定义 */ /* 正常运行状态4个状态循环 */ #define STATE_EW_GREEN 0 /* 东西绿灯/南北红灯正常通行 */ #define STATE_EW_YELLOW 1 /* 东西绿灯黄灯闪烁/南北红灯最后5秒警告 */ #define STATE_NS_GREEN 2 /* 南北绿灯/东西红灯正常通行 */ #define STATE_NS_YELLOW 3 /* 南北绿灯黄灯闪烁/东西红灯最后5秒警告 */ /* 特殊控制状态按键触发 */ #define STATE_EMERGENCY_BLINK 4 /* 紧急模式四路口黄灯闪烁5秒 */ #define STATE_EMERGENCY_ALL_RED 5 /* 紧急模式四路口全红灯禁行 */ #define STATE_EW_FIRST_BLINK 6 /* 东西优先黄灯闪烁5秒过渡 */ #define STATE_EW_FIRST_GO 7 /* 东西优先东西绿灯/南北红灯长亮 */ #define STATE_NS_FIRST_BLINK 8 /* 南北优先黄灯闪烁5秒过渡 */ #define STATE_NS_FIRST_GO 9 /* 南北优先南北绿灯/东西红灯长亮 */ /* 全局变量 */ unsigned char current_state STATE_EW_GREEN; /* 当前状态机状态初始为东西绿灯 */ unsigned char time_count 60; /* 当前倒计时值秒初始60 */ unsigned char pass_time 60; /* 准行时间设定值60秒或120秒 */ unsigned char count_50ms 0; /* 50ms中断计数器计满20次1秒 */ unsigned char blink_half_sec 0;/* 50ms中断计数器计满10次500ms用于黄灯闪烁 */ bit yellow_toggle 0; /* 黄灯亮灭切换标志0灭1亮 */ bit display_enable 1; /* 数码管显示使能1正常显示0关闭紧急模式用 */ unsigned char display_ew 0; /* 东西方向数码管显示值 */ unsigned char display_ns 0; /* 南北方向数码管显示值 */ unsigned char key1_cnt 0; /* K1按键消抖计数器 */ unsigned char key2_cnt 0; /* K2按键消抖计数器 */ unsigned char key3_cnt 0; /* K3按键消抖计数器 */ unsigned char key4_cnt 0; /* K4按键消抖计数器 */ bit key1_flag 0; /* K1按键已按下标志防止重复触发 */ bit key2_flag 0; /* K2按键已按下标志 */ bit key3_flag 0; /* K3按键已按下标志 */ bit key4_flag 0; /* K4按键已按下标志 */ /* 函数声明 */ void sys_init(void); /* 系统初始化 */ void timer0_init(void); /* 定时器0初始化 */ void state_machine(void); /* 状态机处理 */ void led_update(void); /* LED指示灯状态更新 */ void display_scan(void); /* 数码管动态扫描 */ void key_scan(void); /* 按键扫描与消抖 */ /* 主函数 */ void main(void) { sys_init(); /* 系统初始化IO口、定时器、中断 */ while(1) { /* 主循环无限循环 */ key_scan(); /* 扫描按键处理消抖和按键动作 */ state_machine(); /* 状态机处理更新状态和显示值 */ led_update(); /* 根据当前状态更新LED指示灯 */ display_scan(); /* 数码管动态扫描每次循环扫一位 */ } } /* 系统初始化 */ void sys_init(void) { SEG_PORT 0xFF; /* 段选全灭共阳0xFF全段不亮 */ P2 0xC0; /* 位选全关P2.0-P2.5置0关保留P2.6/P2.7不变 */ LED_EW_GREEN 0; /* 东西绿灯灭 */ LED_EW_YELLOW 0; /* 东西黄灯灭 */ LED_EW_RED 0; /* 东西红灯灭 */ LED_NS_GREEN 0; /* 南北绿灯灭 */ LED_NS_YELLOW 0; /* 南北黄灯灭 */ LED_NS_RED 0; /* 南北红灯灭 */ LED_MODE 0; /* 模式指示灯亮低电平有效默认60s模式 */ current_state STATE_EW_GREEN; /* 初始状态东西绿灯/南北红灯 */ time_count pass_time; /* 倒计时设为准行时间60秒 */ display_ew time_count; /* 东西数码管初始显示值 */ display_ns time_count; /* 南北数码管初始显示值 */ timer0_init(); /* 定时器0初始化 */ EA 1; /* 开启总中断 */ } /* 定时器0初始化 */ void timer0_init(void) { TMOD 0xF0; /* 清除T0低4位配置保留T1配置不变 */ TMOD | 0x01; /* T0工作方式116位定时器模式 */ TH0 0x3C; /* 定时器高8位初值12MHz下50ms */ TL0 0xB0; /* 定时器低8位初值3CB0H15536, 65536-1553650000us50ms */ ET0 1; /* 允许定时器0中断 */ TR0 1; /* 启动定时器0 */ } /* 状态机 */ void state_machine(void) { /* 所有状态下都更新显示值数码管显示当前倒计时 */ display_ew time_count; /* 东西方向显示当前倒计时 */ display_ns time_count; /* 南北方向显示当前倒计时 */ switch(current_state) { case STATE_EW_GREEN: /* 东西绿灯/南北红灯状态 */ if(time_count 5 time_count 0) { /* 倒计时进入最后5秒 */ current_state STATE_EW_YELLOW; /* 切换到东西黄灯闪烁状态 */ } break; case STATE_EW_YELLOW: /* 东西黄灯闪烁/南北红灯状态最后5秒 */ if(time_count 0) { /* 倒计时归零 */ current_state STATE_NS_GREEN; /* 切换到南北绿灯状态 */ time_count pass_time; /* 重置倒计时为准行时间 */ } break; case STATE_NS_GREEN: /* 南北绿灯/东西红灯状态 */ if(time_count 5 time_count 0) { /* 倒计时进入最后5秒 */ current_state STATE_NS_YELLOW; /* 切换到南北黄灯闪烁状态 */ } break; case STATE_NS_YELLOW: /* 南北黄灯闪烁/东西红灯状态最后5秒 */ if(time_count 0) { /* 倒计时归零 */ current_state STATE_EW_GREEN; /* 切换回东西绿灯状态 */ time_count pass_time; /* 重置倒计时为准行时间 */ } break; case STATE_EMERGENCY_BLINK: /* 紧急模式四路口黄灯闪烁5秒 */ if(time_count 0) { /* 5秒黄灯闪烁结束 */ current_state STATE_EMERGENCY_ALL_RED; /* 切换到全红灯禁行 */ } break; case STATE_EMERGENCY_ALL_RED: /* 紧急模式四路口全红灯等待K1再次按下退出 */ break; /* 无操作保持全红灯状态 */ case STATE_EW_FIRST_BLINK: /* 东西优先黄灯闪烁5秒过渡 */ if(time_count 0) { /* 5秒黄灯闪烁结束 */ current_state STATE_EW_FIRST_GO; /* 切换到东西绿灯长亮 */ } break; case STATE_EW_FIRST_GO: /* 东西优先东西绿灯/南北红灯长亮等待K2再次按下退出 */ break; /* 无操作保持东西通行状态 */ case STATE_NS_FIRST_BLINK: /* 南北优先黄灯闪烁5秒过渡 */ if(time_count 0) { /* 5秒黄灯闪烁结束 */ current_state STATE_NS_FIRST_GO; /* 切换到南北绿灯长亮 */ } break; case STATE_NS_FIRST_GO: /* 南北优先南北绿灯/东西红灯长亮等待K3再次按下退出 */ break; /* 无操作保持南北通行状态 */ } } /* LED更新 */ void led_update(void) { switch(current_state) { case STATE_EW_GREEN: /* 东西绿灯/南北红灯 */ LED_EW_GREEN1; /* 东西绿灯亮 */ LED_EW_YELLOW0; /* 东西黄灯灭 */ LED_EW_RED0; /* 东西红灯灭 */ LED_NS_GREEN0; /* 南北绿灯灭 */ LED_NS_YELLOW0; /* 南北黄灯灭 */ LED_NS_RED1; /* 南北红灯亮 */ break; case STATE_EW_YELLOW: /* 东西绿灯黄灯闪烁/南北红灯 */ LED_EW_GREEN1; /* 东西绿灯保持亮 */ LED_EW_YELLOWyellow_toggle; /* 东西黄灯闪烁由定时器控制亮灭 */ LED_EW_RED0; /* 东西红灯灭 */ LED_NS_GREEN0; /* 南北绿灯灭 */ LED_NS_YELLOW0; /* 南北黄灯灭 */ LED_NS_RED1; /* 南北红灯保持亮 */ break; case STATE_NS_GREEN: /* 南北绿灯/东西红灯 */ LED_EW_GREEN0; /* 东西绿灯灭 */ LED_EW_YELLOW0; /* 东西黄灯灭 */ LED_EW_RED1; /* 东西红灯亮 */ LED_NS_GREEN1; /* 南北绿灯亮 */ LED_NS_YELLOW0; /* 南北黄灯灭 */ LED_NS_RED0; /* 南北红灯灭 */ break; case STATE_NS_YELLOW: /* 南北绿灯黄灯闪烁/东西红灯 */ LED_EW_GREEN0; /* 东西绿灯灭 */ LED_EW_YELLOW0; /* 东西黄灯灭 */ LED_EW_RED1; /* 东西红灯保持亮 */ LED_NS_GREEN1; /* 南北绿灯保持亮 */ LED_NS_YELLOWyellow_toggle; /* 南北黄灯闪烁 */ LED_NS_RED0; /* 南北红灯灭 */ break; case STATE_EMERGENCY_BLINK: /* 紧急模式四路口黄灯同时闪烁 */ LED_EW_GREEN0; /* 东西绿灯灭 */ LED_EW_YELLOWyellow_toggle; /* 东西黄灯闪烁 */ LED_EW_RED0; /* 东西红灯灭 */ LED_NS_GREEN0; /* 南北绿灯灭 */ LED_NS_YELLOWyellow_toggle; /* 南北黄灯闪烁 */ LED_NS_RED0; /* 南北红灯灭 */ break; case STATE_EMERGENCY_ALL_RED: /* 紧急模式四路口全红灯 */ LED_EW_GREEN0; /* 东西绿灯灭 */ LED_EW_YELLOW0; /* 东西黄灯灭 */ LED_EW_RED1; /* 东西红灯亮 */ LED_NS_GREEN0; /* 南北绿灯灭 */ LED_NS_YELLOW0; /* 南北黄灯灭 */ LED_NS_RED1; /* 南北红灯亮 */ break; case STATE_EW_FIRST_BLINK: /* 东西优先过渡四路口黄灯闪烁 */ LED_EW_GREEN0; /* 东西绿灯灭 */ LED_EW_YELLOWyellow_toggle; /* 东西黄灯闪烁 */ LED_EW_RED0; /* 东西红灯灭 */ LED_NS_GREEN0; /* 南北绿灯灭 */ LED_NS_YELLOWyellow_toggle; /* 南北黄灯闪烁 */ LED_NS_RED0; /* 南北红灯灭 */ break; case STATE_EW_FIRST_GO: /* 东西优先通行东西绿灯/南北红灯 */ LED_EW_GREEN1; /* 东西绿灯亮 */ LED_EW_YELLOW0; /* 东西黄灯灭 */ LED_EW_RED0; /* 东西红灯灭 */ LED_NS_GREEN0; /* 南北绿灯灭 */ LED_NS_YELLOW0; /* 南北黄灯灭 */ LED_NS_RED1; /* 南北红灯亮 */ break; case STATE_NS_FIRST_BLINK: /* 南北优先过渡四路口黄灯闪烁 */ LED_EW_GREEN0; /* 东西绿灯灭 */ LED_EW_YELLOWyellow_toggle; /* 东西黄灯闪烁 */ LED_EW_RED0; /* 东西红灯灭 */ LED_NS_GREEN0; /* 南北绿灯灭 */ LED_NS_YELLOWyellow_toggle; /* 南北黄灯闪烁 */ LED_NS_RED0; /* 南北红灯灭 */ break; case STATE_NS_FIRST_GO: /* 南北优先通行南北绿灯/东西红灯 */ LED_EW_GREEN0; /* 东西绿灯灭 */ LED_EW_YELLOW0; /* 东西黄灯灭 */ LED_EW_RED1; /* 东西红灯亮 */ LED_NS_GREEN1; /* 南北绿灯亮 */ LED_NS_YELLOW0; /* 南北黄灯灭 */ LED_NS_RED0; /* 南北红灯灭 */ break; } } /* 数码管动态扫描 */ /* 6位数码管位选高电平有效段选低电平有效共阳 */ /* P2.0东西百位, P2.1东西十位, P2.2东西个位 */ /* P2.3南北百位, P2.4南北十位, P2.5南北个位 */ void display_scan(void) { static unsigned char pos 0; /* 当前扫描位0-5循环static保持值 */ unsigned char i; /* 延时循环变量 */ /* 第1步先关段选全灭防止切换位选时产生鬼影 */ SEG_PORT 0xFF; /* 段选全灭共阳0xFF不亮 */ /* 第2步关所有位选P2.0-P2.5全置0高电平有效所以0关 */ P2 0xC0; /* 清除P2低6位保留P2.6/P2.7不变 */ if(!display_enable) { /* 如果数码管显示被关闭紧急模式 */ return; /* 直接返回不显示任何内容 */ } /* 第3步送段码 → 第4步开对应位选(置1) → 第5步短暂延时保证亮度 */ switch(pos) { case 0: /* 东西百位 */ SEG_PORT seg_table[display_ew / 100]; /* 取百位数字对应的段码送P0 */ P2 | 0x01; /* P2.0置1选中东西百位数码管 */ for(i 0; i 100; i); /* 短暂延时让该位充分点亮 */ break; case 1: /* 东西十位 */ SEG_PORT seg_table[(display_ew / 10) % 10]; /* 取十位数字先除10再取余 */ P2 | 0x02; /* P2.1置1选中东西十位数码管 */ for(i 0; i 100; i); /* 短暂延时 */ break; case 2: /* 东西个位 */ SEG_PORT seg_table[display_ew % 10]; /* 取个位数字对10取余 */ P2 | 0x04; /* P2.2置1选中东西个位数码管 */ for(i 0; i 100; i); /* 短暂延时 */ break; case 3: /* 南北百位 */ SEG_PORT seg_table[display_ns / 100]; /* 取百位数字 */ P2 | 0x08; /* P2.3置1选中南北百位数码管 */ for(i 0; i 100; i); /* 短暂延时 */ break; case 4: /* 南北十位 */ SEG_PORT seg_table[(display_ns / 10) % 10]; /* 取十位数字 */ P2 | 0x10; /* P2.4置1选中南北十位数码管 */ for(i 0; i 100; i); /* 短暂延时 */ break; case 5: /* 南北个位 */ SEG_PORT seg_table[display_ns % 10]; /* 取个位数字 */ P2 | 0x20; /* P2.5置1选中南北个位数码管 */ for(i 0; i 100; i); /* 短暂延时 */ break; } pos; /* 扫描位指针加1 */ if(pos 6) pos 0; /* 扫完6位后回到第0位循环扫描 */ } /* 按键扫描带消抖 */ /* 消抖原理连续3次检测到低电平才确认按下防止机械抖动误触发 */ void key_scan(void) { /* K1 - 紧急模式按键 */ if(KEY_EMERGENCY 0) { /* 检测K1是否按下低电平有效 */ key1_cnt; /* 消抖计数器加1 */ if(key1_cnt 3 !key1_flag) { /* 连续3次检测到低电平且未处理过 */ key1_flag 1; /* 标记已处理防止重复触发 */ if(current_state STATE_EMERGENCY_ALL_RED) { /* 如果当前已在全红灯状态 */ current_state STATE_EW_GREEN; /* 退出紧急模式回到东西绿灯 */ time_count pass_time; /* 重置倒计时 */ display_enable 1; /* 恢复数码管显示 */ } else if(current_state ! STATE_EMERGENCY_BLINK) { /* 如果不在黄灯闪烁中 */ current_state STATE_EMERGENCY_BLINK; /* 进入紧急黄灯闪烁模式 */ time_count 5; /* 黄灯闪烁5秒 */ display_enable 0; /* 关闭数码管倒计时显示 */ } } } else { /* K1未按下高电平 */ key1_cnt 0; /* 消抖计数器清零 */ key1_flag 0; /* 按键标志清零允许下次触发 */ } /* K2 - 东西优先通行按键 */ if(KEY_EW_FIRST 0) { /* 检测K2是否按下 */ key2_cnt; /* 消抖计数器加1 */ if(key2_cnt 3 !key2_flag) { /* 连续3次确认按下 */ key2_flag 1; /* 标记已处理 */ if(current_state STATE_EW_FIRST_GO) { /* 如果当前已是东西优先通行 */ current_state STATE_EW_GREEN; /* 退出回到东西绿灯正常模式 */ time_count pass_time; /* 重置倒计时 */ display_enable 1; /* 恢复显示 */ } else if(current_state STATE_EW_GREEN || current_state STATE_EW_YELLOW || current_state STATE_NS_GREEN || current_state STATE_NS_YELLOW) { /* 仅在正常运行的4个状态下才能触发东西优先 */ current_state STATE_EW_FIRST_BLINK; /* 进入东西优先黄灯闪烁过渡 */ time_count 5; /* 黄灯闪烁5秒 */ display_enable 1; /* 保持数码管显示 */ } } } else { /* K2未按下 */ key2_cnt 0; /* 消抖计数器清零 */ key2_flag 0; /* 标志清零 */ } /* K3 - 南北优先通行按键 */ if(KEY_NS_FIRST 0) { /* 检测K3是否按下 */ key3_cnt; /* 消抖计数器加1 */ if(key3_cnt 3 !key3_flag) { /* 连续3次确认按下 */ key3_flag 1; /* 标记已处理 */ if(current_state STATE_NS_FIRST_GO) { /* 如果当前已是南北优先通行 */ current_state STATE_NS_GREEN; /* 退出回到南北绿灯正常模式 */ time_count pass_time; /* 重置倒计时 */ display_enable 1; /* 恢复显示 */ } else if(current_state STATE_EW_GREEN || current_state STATE_EW_YELLOW || current_state STATE_NS_GREEN || current_state STATE_NS_YELLOW) { /* 仅在正常运行的4个状态下才能触发南北优先 */ current_state STATE_NS_FIRST_BLINK; /* 进入南北优先黄灯闪烁过渡 */ time_count 5; /* 黄灯闪烁5秒 */ display_enable 1; /* 保持数码管显示 */ } } } else { /* K3未按下 */ key3_cnt 0; /* 消抖计数器清零 */ key3_flag 0; /* 标志清零 */ } /* K4 - 60s/120s准行时间切换按键 */ if(KEY_MODE 0) { /* 检测K4是否按下 */ key4_cnt; /* 消抖计数器加1 */ if(key4_cnt 3 !key4_flag) { /* 连续3次确认按下 */ key4_flag 1; /* 标记已处理 */ if(pass_time 60) { /* 当前是60秒模式 */ pass_time 120; /* 切换为120秒模式 */ LED_MODE 1; /* 模式指示灯灭低电平有效1灭表示120s */ } else { /* 当前是120秒模式 */ pass_time 60; /* 切换为60秒模式 */ LED_MODE 0; /* 模式指示灯亮0亮表示60s */ } /* 如果当前正在绿灯通行状态立即生效新的倒计时 */ if(current_state STATE_EW_GREEN || current_state STATE_NS_GREEN) { time_count pass_time; /* 更新当前倒计时为新设定值 */ } } } else { /* K4未按下 */ key4_cnt 0; /* 消抖计数器清零 */ key4_flag 0; /* 标志清零 */ } } /* 定时器0中断服务函数 */ /* 每50ms中断一次实现黄灯闪烁控制 1秒倒计时 */ void timer0_isr(void) interrupt 1 { TH0 0x3C; /* 重装定时器高8位初值50ms */ TL0 0xB0; /* 重装定时器低8位初值 */ /* 黄灯闪烁控制每500ms切换一次亮灭状态10次×50ms500ms */ blink_half_sec; /* 500ms计数器加1 */ if(blink_half_sec 10) { /* 计满10次500ms到 */ blink_half_sec 0; /* 计数器清零 */ yellow_toggle !yellow_toggle; /* 黄灯亮灭标志翻转1Hz闪烁 */ } /* 1秒倒计时20次×50ms1000ms1秒 */ count_50ms; /* 1秒计数器加1 */ if(count_50ms 20) { /* 计满20次1秒到 */ count_50ms 0; /* 计数器清零 */ if(time_count 0) { /* 如果倒计时未归零 */ time_count--; /* 倒计时减1秒 */ } } }五、状态机总览系统共10个状态4个正常循环 6个特殊控制状态六、引脚分配一览七、关键参数八、总结基于51单片机的智能交通信号灯控制系统通过合理的硬件接口设计和软件状态机架构实现了完整的交通灯控制功能。系统具有以下特点功能完善正常循环 紧急模式 方向优先 时长切换覆盖常见交通场景。状态机清晰10个状态分工明确正常4状态循环 特殊6状态按需触发互不干扰。人机交互友好6位数码管实时倒计时 LED信号灯直观指示 4键操作简单明了。可靠性高按键消抖防误触、防鬼影扫描、定时器精确计时Proteus仿真验证通过。该系统适用于课程设计、毕业设计等教学场景也可作为实际交通信号灯控制的原型参考。通过扩展串口通信、无线模块等功能可进一步实现远程控制和联网管理。源文件获取通过网盘分享的文件获取路径.zip链接: https://pan.baidu.com/s/1f_s7oypviG6oqhzVW85aUQ?pwdqauw 提取码: qauw