求一个51单片机交通灯程序?

img

img
仿真硬件要求如上两图
程序要求如下:
1.利用定时器中断产生倒计时,用数码显示机动车交通灯每个灯次的倒计时。
2.每个路口交通变化顺序为:机动车用交通灯:绿灯亮,绿灯闪烁3次,1秒/次, 黄灯闪烁3次,1秒/次,红灯亮;行人用交通灯:绿灯亮,绿灯闪烁3次,1 秒/次(与机动车交通灯同步),红灯亮(无黄灯闪烁过程),绿灯闪烁的同 时用蜂鸣器对行人进行提示。
3.设置三个按键,分别是"设置"、"增大〃、"减小"。用外部中断对第一 次按下"设置"进行响应,东西方向的数码管闪烁显示该方向绿灯时间,再 次按下设置,则东西、南北方向的数码管闪烁切换。按下增大、减小,则使 相应方向的绿灯时间做出调整,并在数码管上显示。再次按下设置完成调整。
4.绿灯时间范围为10秒〜20秒。
希望得到一个完整的程序

#include<reg52.h>
#define              uint unsigned int;
#define  uchar unsigned char;

void  DigitalTube();   //数码管显示函数
void  InterruptT0();              //内部中断0

sbit  P10 = P1^0;                            //红绿灯引脚的初始化
sbit  P11 = P1^1;
sbit  P12 = P1^2;
sbit  P13 = P1^3;
sbit  P14 = P1^4;
sbit  P15 = P1^5;

sbit  P16 = P1^6;                            //数码管使能控制
sbit  P17 = P1^7;
sbit  P20 = P2^0;
sbit  P21 = P2^1;

sbit  K22 = P2^2;                 //按键22
sbit  K23 = P2^3;
sbit  K24 = P2^4;
sbit dula = P2^5;

uint LedBuf[10] = {
                              0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
                            0x80,0x90
};                            //0~9的数字显示共阳

uint Kflag = 1;                              //按键24的标志
uint LedNumNS = 27;                 //南北的数字显示
uint LedNumEW = 30;                 //东西的数字显示
uint i = 0;
uint j = 0;
uint j1 = 0;
uint k = 0;
uint g = 0;
uint z = 0;                                          //计数及状态的变量

uint LedTime1 = 30;
uint LedTime2 = 27;
uint LedTime3 = 30;
uint LedTime4 = 27;

uint Kf22 = 1;              //按键前一个状态的值
uint Kf23 = 1;
uint Kf24 = 1;
uint KSta24 = 1;              //按键的当前值
uint KSta23 = 1;
uint KSta22 = 1;  
uchar Kflag22 = 0;              //按键22的switch函数参数

void main()
{
              EA = 1;                                          //开总中断
              ET0 = 1;                            //开内部中断0
              TR0 = 1;
              TMOD = 0x01;                 //方式1
              TH0 = 0xFC;
              TL0= 0x67; //1ms中断
              P1 = 0xEE;                            //

              while(1)
              {
                            DigitalTube();              //数码管显示
              }

}


void InterruptT0() interrupt 1
{
                                                        TH0 = 0xFC;
                                                        TL0 = 0x67; //1ms中断            
                                                        i++;            
                                                        k++;
                                         
                                                        KSta24 = K24;                                //按键K24  夜间模式
                                                        if(Kf24 != KSta24)                            //按键有动作
                                                        {
                                                                      if(Kf24 == 1)                            //按键按下
                                                                      {
                                                                                    Kflag = !Kflag;                           
                                                                      }
                                                                      Kf24 = KSta24;
                                                        }
                                         


                                          KSta23 = K23;                                //按键K23  增减时长
                                          if(Kf23 != KSta23)                            //按键有动作
                                          {
                                                        if(Kf23 == 1)                            //按键按下
                                                        {
                                                        //              LedTime = LedTime +2;
                                                                      LedTime1 = LedTime1 +5;              //32  34 36 38 30
                                                                      LedTime2 = LedTime2 +5;              //25  23 21  19 17
                                                                      LedTime3 = LedTime3 +5;
                                                                      LedTime4 = LedTime4 +5;
                                                                      if(LedTime1 >=60)
                                                                                    {
                                                                                                  LedTime1 = 10;
                                                                                                  LedTime2 = 7;
                                                                                                  LedTime3 = 10;
                                                                                                  LedTime4 = 7;
                                                                                    }            
                                                                      LedNumEW = LedTime1;
                                                                      LedNumNS = LedTime2;
                                                        }
                                                        Kf23= KSta23;
                                          }
                           


                                          KSta22 = K22;                                //按键K22  某方向长时间红灯
                                          if(Kf22 != KSta22)                            //按键有动作
                                          {
                                                        if(Kf22 == 1)                            //按键按下
                                                        {
                                                                      Kflag22 ++;            
                                                                      if(Kflag22>= 3)            
                                                                                    {
                                                                                    Kflag22 = 0;
                                                                                    }

                                                                      switch(Kflag22)
                                                                      {
                                                                                    case 1:
                                                                                                  LedTime1 = 50;
                                                                              LedTime2 = 47;              //case2
                                                                                                  LedTime3 = 20;
                                                                                                  LedTime4 = 17; //case1

                                                                                                  LedNumEW = LedTime1;
                                                                                                  LedNumNS = LedTime2;


                                                                                        break;
                                                                                    case 2:            
                                                                                                  LedTime1 = 20;
                                                                              LedTime2 = 17;                //case2
                                                                                                  LedTime3 = 50;
                                                                                                  LedTime4 = 47;              //case1

                                                                                                  LedNumEW = LedTime1;
                                                                                                  LedNumNS = LedTime2;
                                                                                                  break;
                                                                                    case 0:            
                                                                     
                                                                                                  LedTime1 = 30;
                                                                              LedTime2 = 27;
                                                                                                  LedTime3 = 30;
                                                                                                  LedTime4 = 27;
                                                                                                  LedNumEW = LedTime1;
                                                                                                  LedNumNS = LedTime2;
                                                                                    break;
                                                                      }

                                                        }
                                                        Kf22 = KSta22;
                                          }
                                         

              if(j >= 200)
                            {
                                          j  = 0;
                                          j1++;
                            }


              if(i >= 1000)
              {
                            i = 0;
                            LedNumNS--;              //27
                            LedNumEW--;              //30
                            switch(g)
                            {                                            //刚开始东西红  南北绿
                                          case 0:                                                                                                                   //********2
                                                        if(LedNumEW == 3)                                                           //*****3
                                                        {
                                                                                    P14 = ! P14;   //绿灯灭
                                                        if(Kf24 == Kflag)                            P15 = ! P15;   //黄灯亮
                                                                                    LedNumNS = 3;
                                                        }            
                                                        if(LedNumEW == 0)
                                                        {
                                                                      LedNumNS =  LedTime3;              //   30东西绿南北红的时间
                                                                      LedNumEW =               LedTime4;              //  27
                                                                      P12 = ! P12;                 //东西绿灯亮
                                                                      P10 = ! P10;                //东西红灯灭
                                                                      P13 = ! P13;                              //nanbei红灯亮
                                                            if(Kf24 == Kflag)
                                                                      P15 = ! P15;                //南北黄灯灭
                                                                      g = 1;
                                                        }            
                                                        break;

                                          case 1:                                                                                                                              //******4
                                                        if(LedNumNS == 3)                 //黄灯亮
                                                                      {
                                                                   P12 = !P12;
                                                                                       P11 = !P11;            
                                                                                       LedNumEW = 3;
                                                                      }
                                                        if(LedNumNS == 0)                                                                         //********5
                                                        {
                                                                      LedNumEW = LedTime1;//重新赋值
                                                                      LedNumNS = LedTime2;
                                                        if(Kf24 == Kflag)              P11 = !P11;                 //南北黄灯灭
                                                                      P10 = !P10;                //dongxi红灯亮
                                                                      P14 = !P14;
                                                                      P13 = !P13;
                                                                      g = 0;
                                                        }
                                                        break;
                               }
                           

                  if(Kf24 != Kflag)                                                        //夜间模式
                            {
                                          if(j1 % 2 == 0)
                                          {
                                                        P11 = ! P11;            
                                                        P15 = ! P15;
                                }                                                          //所有方向黄灯闪烁
                            }                             
              }                                                                       
}




void  DigitalTube()                            //数码管

{                    
              switch(z)
              {
                                          case 0:                                                                      //第一个数码管显示数字
                                         
                                              P0 =0xFF;                            //防止数字显示混乱
                                                        dula = 1;
                                                        P0 = LedBuf[LedNumEW / 10];              //十位
                                                        P20 = 0;
                                                        P17 = 0;
                                                        P21 = 0;
                                                        P16 = 1;
                                                        dula = 0;
                                                        z++;            
                                                        break;                             
            
                                          case 1:                                                          //第二个数码管亮
                                                           P0 =0xFF;
                                                        dula = 1;
                                                        P0 = LedBuf[LedNumEW % 10];              //个位
                                                        P16 = 0;
                                                        P20 = 0;
                                                        P21 = 0;
                                                        P17 = 1;
                                                        dula = 0;
                                              z++;
                                                        break;
                           
                                          case 2:                                                        //第三个数码管亮
                                              P0 =0xFF;
                                                        dula = 1;
                                                        P0 = LedBuf[LedNumNS / 10]; //十位
                                                        P21 = 0;
                                                        P16 = 0;
                                                        P17 = 0;                                            //关闭2
                                                        P20 = 1;                                            //使能第3个数码管
                                                        dula = 0;
                                                        z++;                                                        //进入3
                                                        break;
                                         
                                          case 3:                                                          //第四个数码管亮

                                              P0 =0xFF;
                                                        dula = 1;
                                                        P0 = LedBuf[LedNumNS % 10];              //个位
                                                        P20 = 0;                                          //第三个关闭
                                                        P16 = 0;
                                                        P17 = 0;
                                                        P21 = 1;                                          //使能第四个数码管
                                                        dula = 0;
                                                        z = 0;                                                          //进入0
                                                        break;

                                          default:break;                                                                                                   
              }
}

代码如下,如有帮助,请采纳一下,谢谢。

 #include<reg52.h>
 #include<bstv51.h>
 #define uchar unsigned char
 #define uint  unsigned int
 
 sbit nbp1=P0^4;//南北方向数码管第一位;
 sbit nbp2=P0^5;//南北方向数码管第二位;
 sbit dxp1=P0^6;//东西方向数码管第一位;
 sbit dxp2=P0^7;//东西方向数码管第二位;

 sbit hdnb=P0^2;//南北方向红灯;
 sbit hddx=P0^0;//东西方向红灯;
 sbit ldnb=P0^3;//南北方向绿灯;
 sbit lddx=P0^1;//东西方向绿灯;
 uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,
                      0x6d,0x7d,0x07,0x7f,0x6f};        //0-9
 uchar num=30;num2,shi,ge;



 void delayms(xms)           //延时函数x毫秒函数
 {
   uint i,j;
   for(i=xms;i>0;i--)
     for(j=110;j>0;j--);
 }

void display(uchar shi,uchar ge) //南北数码管显示函数
{ 
 
 

 P1=table[shi];
 nbp1=0;                                                        //选中南北方向数码管第一位
 delayms(3);
 nbp1=1;                                                //关闭南北方向数码管第一位
 P1=table[ge];
 nbp2=0;                                                //选中南北第二位
 delayms(3);
 nbp2=1;                                                //关闭南北方向数码管第二位


 P2=table[shi];
 dxp1=0;                                                //选中南北方向数码管第一位
 delayms(3);
 dxp1=1;                                                //关闭南北方向数码管第一位
 P2=table[ge];
 dxp2=0;                                                //选中南北第二位
 delayms(3);
 dxp2=1;                
}

void T1_time()interrupt 3                        //定时器1中断函数
{ 
  TH1=(65536-45872)/256;
  TL1=(65536-45872)%256;
  num2++;      
  if(num2==20)
  {
   num2=0;                                                   //说明计时够一秒
   num--;
   if(num==0)
    {  
       lddx=~lddx;                                                
       hdnb=~hdnb;                                            
       ldnb=~ldnb;
       hddx=~hddx;
           num=30;
     }

  }
        shi=num/10;
        ge=num%10;
}


void main()                                           //主函数
 {
   TMOD=0x10;
   TH1=(65536-45872)/256;
   TL1=(65536-45872)%256;
   EA=1;
   ET1=1;
   TR1=1;
   lddx=0;                                                //东西方向绿灯亮
   hdnb=0;                                            //南北方向红灯亮
   ldnb=1;
   hddx=1;

 P1=0x00;
 P2=0x00;
 nbp1=1;
 dxp1=1;
 dxp2=1;
 nbp2=1;

   while(1)
   {
   display(shi,ge);
    }
 }



不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^