51单片机,交通信号灯,keil程序要全,急

要求:
1、双向圆灯控制(没有左右拐的),带读秒倒计时显示
2、灯变换之间的时间必须可以修改,设计必要的按键和指示电路

img

可参考

#include <reg52.h>

#define uchar unsigned char
#define uint unsigned int

sbit red1 = P1^0; // 红灯1
sbit yellow1 = P1^1; // 黄灯1
sbit green1 = P1^2; // 绿灯1
sbit red2 = P1^3; // 红灯2
sbit yellow2 = P1^4; // 黄灯2
sbit green2 = P1^5; // 绿灯2
sbit key1 = P3^0; // 按键1
sbit key2 = P3^1; // 按键2
sbit key3 = P3^2; // 按键3
sbit key4 = P3^3; // 按键4
sbit beep = P3^7; // 蜂鸣器
sbit dula = P2^6; // 读秒倒计时器段选
sbit wela = P2^7; // 读秒倒计时器位选

uchar code table[] = { // 数码管显示表
    0x3f, // 0
    0x06, // 1
    0x5b, // 2
    0x4f, // 3
    0x66, // 4
    0x6d, // 5
    0x7d, // 6
    0x07, // 7
    0x7f, // 8
    0x6f, // 9
};

uint time1 = 0; //1计时器
uint time2 = 0; //2计时器
uchar sec = 0; // 读秒计时器

void delay(uint t) // 延时函数
{
    uint i, j;
    for (i = 0; i < t; i++)
    {
        for (j = 0; j < 125; j++);
    }
}

void display(uchar num) // 数码管显示函数
{
    dula = 1; // 关闭段选
    P0 = table[num]; // 显示数码
    dula = 0; // 打开段选
}

void timer0() interrupt 1 // 定时器0中断服务函数
{
    TH0 = 0xfc; // 重置定时器0初值
    TL0 = 0x18;
    time1++; //1计时器加1
    time2++; //2计时器加1
    if (sec > 0) // 如果读秒计时器大于0,继续计时
    {
        sec--;
    }
}

void main()
{
    uchar mode = 0; // 灯模式,0为绿灯亮,1为黄灯亮,2为红灯亮
    uchar time = 10; // 灯变换时间,单位为秒
    uchar i;

    TMOD = 0x01; // 定时器0工作在模式1
    TH0 = 0xfc; // 定时器0初值
    TL0 = 0x18;
    ET0 = 1; // 开启定时器0中断
    EA = 1; // 开启总中断
    TR0 = 1; // 启动定时器0

    while (1)
    {
        if (key1 == 0) // 按键1按下,切换到灯1模式
        {
            mode = 0;
            beep = 1; // 蜂鸣器响一声
            delay(10);
            beep = 0;
        }
        else if (key2 == 0) // 按键2按下,切换到灯2模式
        {
            mode = 0;
            beep = 1; // 蜂鸣器响一声
            delay(10);
            beep = 0;
        }
        else if (key3 == 0) // 按键3按下,增加灯变换时间
        {
            time++;
            if (time > 60)
            {
                time = 60;
            }
            beep = 1; // 蜂鸣器响一声
            delay(10);
            beep = 0;
        }
        else if (key4 == 0) // 按键4按下,减少灯变换时间
        {
            time--;
            if (time < 10)
            {
                time = 10;
            }
            beep = 1; // 蜂鸣器响一声
            delay(10);
            beep = 0;
        }
    }
}

双向十字路口应该是4个倒计时显示和4组红绿灯控制吧?

基于51单片机简易十字路口交通灯_5s全黄闪烁

#include<reg52.h>
#include<intrins.h>

//数据类型定义
typedef unsigned char uchar;
typedef unsigned int  uint;

void led_sacn();
void delay_ms(ms);
void seg_disp(uchar number,uchar wei);

#define ON   1    //LED给告电平亮灯
#define OFF  0    //LED给低电平灭灯


//通用IO引脚分配
sbit W0=P3^4;
sbit W1=P3^5;
sbit W2=P3^6;
sbit W3=P3^7;

sbit NS_G = P2^0;
sbit NS_Y = P2^1;
sbit NS_R = P2^2;
sbit WE_R = P2^3;
sbit WE_Y = P2^4;
sbit WE_G = P2^5;





bit flag1s;
bit half_1sflag;
uchar one_sec_flag,main_road_time,secondary_road_time,half_sec_flag;
//1秒定时标志位 南北方向显示时间 东西方向显示时间
uchar state=0;//正常模式不同状态
uchar code seg_du[]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};

uchar main_green_straight_cnt=5,yellow_cnt =5,sec_green_straight_cnt =5; 
//南北方向直行绿灯时间            _黄灯时间      _东西方向绿灯时间

void main()
{
    EA=1;    //开总中断
    TMOD=0X01;//T0的工作模式为模式1
    TH0=0X4C;
    TL0=0X00;//11.0592M晶振 50ms定时初值
    ET0=1; //允许定时器1中断
    TR0=1;//启动定时器0  
//    state=2;    
    while(1)
    {    
        led_sacn();                          //LED和数码管显示,时刻刷新

        if(flag1s)                        //一秒刷新一次
        {
            flag1s=0;
            main_road_time--;            //红绿灯倒计时时间减
            secondary_road_time--;
        }
        if (half_1sflag){
            half_1sflag = 0;
            if(state == 0||state == 2){//黄灯闪烁
                NS_Y =~NS_Y;
                WE_Y =~WE_Y;
            }
            
        }
    }
}
if(main_road_time==0 || secondary_road_time==0)//当南北方向或者东西方向倒数到0,切换状态。
        //这一段程序只有倒计时为0才执行一次,执行完一次等下一次倒计时为0才再执行一次
        {
            switch(state)//改变红绿灯的状态
            {
                case 0:
                {
                    state=1;//下次切换到下一个模式
                    main_road_time=main_green_straight_cnt;//南北方向直行绿灯通行时间
                    secondary_road_time=sec_green_straight_cnt;//东西方向红灯时间
                     NS_G = ON;
                     NS_Y = OFF;
                     NS_R = OFF;
                     WE_R = ON;
                     WE_Y = OFF;
                     WE_G = OFF;
                }break;
                case 1:
                {
                    state=2;
                    main_road_time = yellow_cnt;//南北方向直行黄灯时间
                    secondary_road_time =yellow_cnt;
                    
                     NS_G = OFF;
                     NS_Y = ON;
                     NS_R = OFF;
                     WE_R = OFF;
                     WE_Y = ON;
                     WE_G = OFF;    
                }break;
                case 2:
                {
                    state=3;
                    main_road_time=sec_green_straight_cnt;
                    secondary_road_time=sec_green_straight_cnt;
                    NS_G = OFF;
                    NS_Y = OFF;
                    NS_R = ON;
                    WE_R = OFF;
                    WE_Y = OFF;
                    WE_G = ON;

                }break;
                case 3:
                {
                    state=0;
                    secondary_road_time=yellow_cnt;//黄灯时间
                    main_road_time=yellow_cnt;
                    NS_G = OFF;
                    NS_Y = ON;
                    NS_R = OFF;
                    WE_R = OFF;
                    WE_Y = ON;
                    WE_G = OFF;

                }break;
                
                default:break;
            }
        }


keil程序实现的 基于51单片机的程序,其核心在于倒计时以及控制LED灯的亮和灭。其中,倒计时可以通过delay延时和定时器实现。具体的程序,网上开源的代码不少,这里给你找到一些,应该对你有用:
比如这个基于51单片机简易十字路口交通灯: https://blog.csdn.net/weixin_52733843/article/details/126684698
还有和这个:51单片机|keilc51|实例:https://blog.csdn.net/zzztutu/article/details/124722534

有多急?