使用单片机写的交通灯,但是没办法正常使用

想做一个可以根据红外感应来改变红绿灯的程序,现在的问题是,亮了一轮之后4个黄灯还是会亮,程序里的q又被置1了,但是看不出是哪里有问题

#include<reg51.h>   //头函数
#define T_GREEN 5        //绿灯时间
#define T_YELLOW 2        //黄灯时间
#include "Timer0.h"

sbit led_A=P0^0;   //数码管位
sbit led_B=P0^1;   //数码管位

//***************led指示灯引脚定义*****************//
sbit dx_R=P0^2;
sbit dx_Y=P0^3;
sbit dx_G=P0^4;
sbit nb_R=P0^7;
sbit nb_Y=P0^6;
sbit nb_G=P0^5;

bit flag=0;
sbit key_stop=P3^3;

//**************红外传感器引脚定义*****************//
sbit d_R=P1^0;
sbit x_R=P1^1;
sbit n_R=P1^2;
sbit b_R=P1^3;



char N=T_GREEN;     //初始时间是T_GREEN
char tab_disp[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//共阳极码表
char i,q=1,u=1;//计次使用


/*延时子函数*/
void delay(int t ){while(t--);}
/*显示子函数*/
void display(char dat)
{
    led_A=led_B=0;     //先位灭显
    P2=0XFF;   //再段灭显
    P2=tab_disp[dat/10]; //赋显示的数
    if(dat/10)led_A=1;     
    delay(1000);    //延时
    
    P2=0XFF;led_A=led_B=0; //段灭显    位灭显
    P2=tab_disp[dat%10]; //赋显示的数
    led_B=1;      
    delay(1000);   //延时
}
//这个是循环显示60遍显示的函数
void deal(char m)
{
    int t=60;
    while(t--)display(m);  //循环显示60遍显示的函数
}

void KEY()                                      //按键函数
{
    unsigned char save;                          //定义保存灯状态的变量
    if(key_stop==0)                              //按键是否按下
    {
        delay(20);                              //延时去抖
        if(key_stop==0)                          //再次判断按键是否按下
        {
            flag=1;                              //紧急状态标志位置1,进入紧急通行状态
            save=P0;                          //保存灯的状态
            P0=0x84;                          //全部亮红灯
            while(key_stop==0);                  //按键释放,当按键一直按下的时候,程序就会一直执行这里,直到按键按下
            while(flag==1)                      //如果是紧急状态就一直执行下面的程序
            {
                if(key_stop==0)                  //在紧急状态时判断按键是否按下
                {
                    delay(50);                  //延时去抖
                    if(key_stop==0)              //再次判断按键是否按下
                    {
                        flag=0;                  //紧急状态标志位清零,退出紧急状态
                        P0=save;              //LED灯恢复到之前状态
                        while(key_stop==0);      //按键释放
                    }
                }
            }
        }
    }
}


void dx()
{   
        
          if(q==1)
            {
                N=T_YELLOW;   //初始时间是T_YELLOW    东西南北都是黄灯 让周边的车辆注意
                dx_R=0;dx_Y=1;dx_G=0;    //南北亮黄灯 
                nb_R=0;nb_Y=1;nb_G=0;    //东西亮黄灯
                q=0;
                for(i=N;i>0;i--)     //一秒一秒的减
              {
                deal(i);
                KEY();
              }
            }
                        
            dx_R=0;dx_Y=0;dx_G=1;    //东西亮绿灯
            nb_R=1;nb_Y=0;nb_G=0;    //南北亮红灯
            N=T_GREEN;                    //时间变成T_GREEN
            for(i=N;i>0;i--)     //一秒一秒的减
            {
                deal(i);
                KEY();
            }
    
            dx_R=0;dx_Y=1;dx_G=0;    //东西亮黄灯
            nb_R=1;nb_Y=0;nb_G=0;    //南北亮红灯
            N=T_YELLOW;                   //时间变成T_YELLOW
            for(i=N;i>0;i--)      //一秒一秒的减
            {
                deal(i);
                KEY();
            }
    
            dx_R=1;dx_Y=0;dx_G=0;    //东西亮红灯
            nb_R=0;nb_Y=0;nb_G=1;    //南北亮绿灯
            N=T_GREEN;                    //时间变成T_GREEN
            for(i=N;i>0;i--)          //一秒一秒的减
            {
                deal(i);
                KEY();
            }
            dx_R=1;dx_Y=0;dx_G=0;    //东西亮红灯
            nb_R=0;nb_Y=1;nb_G=0;  //南北亮黄灯
            N=T_YELLOW;                   //时间变成T_YELLOW
            for(i=N;i>0;i--)       //一秒一秒的减
            {
                deal(i);
                KEY();
            }    
    
}
void nb()
{   
        
          if(q==1)
            {
                N=T_YELLOW;   //初始时间是T_YELLOW    东西南北都是黄灯 让周边的车辆注意
                dx_R=0;dx_Y=1;dx_G=0;    //南北亮黄灯 
                nb_R=0;nb_Y=1;nb_G=0;    //东西亮黄灯
                q=0;
                for(i=N;i>0;i--)     //一秒一秒的减
              {
                deal(i);
                KEY();
              }
            }
                    
        dx_R=1;dx_Y=0;dx_G=0;    //东西亮红灯
            nb_R=0;nb_Y=0;nb_G=1;    //南北亮绿灯
            N=T_GREEN;                    //时间变成T_GREEN
            for(i=N;i>0;i--)          //一秒一秒的减
            {
                deal(i);
                KEY();
            }
            dx_R=1;dx_Y=0;dx_G=0;    //东西亮红灯
            nb_R=0;nb_Y=1;nb_G=0;  //南北亮黄灯
            N=T_YELLOW;                   //时间变成T_YELLOW
            for(i=N;i>0;i--)       //一秒一秒的减
            {
                deal(i);
                KEY();
            }                
            dx_R=0;dx_Y=0;dx_G=1;    //东西亮绿灯
            nb_R=1;nb_Y=0;nb_G=0;    //南北亮红灯
            N=T_GREEN;                    //时间变成T_GREEN
            for(i=N;i>0;i--)     //一秒一秒的减
            {
                deal(i);
                KEY();
            }
    
            dx_R=0;dx_Y=1;dx_G=0;    //东西亮黄灯
            nb_R=1;nb_Y=0;nb_G=0;    //南北亮红灯
            N=T_YELLOW;                   //时间变成T_YELLOW
            for(i=N;i>0;i--)      //一秒一秒的减
            {
                deal(i);
                KEY();
            }
    
        
    
}


/*主函数*/
void main(void)
{
    
    //EA=1;      //全局中断开关        
    //IT1=1;       //外部中断下降沿有效
    //EX1=1;
    Timer0Init();   //中断定义
    while(1)
    {        
            switch(u)
            {
                case 1: dx();break;
              case 2: nb();break;
            }
    }    
        
}
void Timer0_Routine()  interrupt 1
{
     static unsigned int T0Count;
     TL0 = 0x18;        
     TH0 = 0xFC;
     T0Count++;
     if(T0Count>=10000)
     {
         if(d_R||x_R)
         {
             q=1;
             u=1;
           T0Count=0;
         }
          else if(n_R||b_R)
         {
             q=1;
             u=2;
           T0Count=0;
         }
     }
}


​没有报错,现象是循环做常规红绿灯,且q会被置1

想让q不被置1 程序正常运转

中断里用到的全局变量,定义的时候加个volatile修饰符
顺便吐槽一下,你这个程序里的函数和变量命名都太随意了。