• 已解决 73482 个问题
  • 已帮助 5993 位优秀工程师

求助,这个交通灯代码秒表走的很快,应该怎么修改

qiuqiu 2020-11-20 浏览量:556
#include <reg51.h>
#define uchar unsigned char
#define uint  unsigned int

uchar data DirectVal[4];                                        //秒显示的变量
uchar data DefaultVal_DX=60;                          //东西数默认
uchar data DefaultVal_NB=90;                        //南北默认值
uchar data setTime_DX=60;                //设置东西方向的时间
uchar data setTime_NB=90;                //设置南北方向的时间
int n;
uchar data CountCount1;
sbit  k4=P3^1;                //禁止
sbit  k1=P3^5;                //时间加
sbit  k2=P3^6;                //时间减
sbit  k3=P3^7;     //切换方向
sbit  SPEAKER = P3^2;

sbit RED_NB=P2^6;                //南北红灯标志
sbit YELLOW_NB=P2^5;        //南北黄灯标志
sbit GREEN_NB=P2^4;     //南北绿灯标志

sbit RED_DX=P2^3;                //东西红灯标志
sbit YELLOW_DX=P2^2;        //东西黄灯标志
sbit GREEN_DX=P2^1;                //东西绿灯标志
               
bit set=0;                                //调时方向切换键标志 =1时,南北,=0时,东西
bit dx_nb=0;                        //东西南北控制位
bit Shanshuo=0;                        //闪烁标志位

uchar code TABLE[11]={        //共阴极字型码
        0x3f  //--0
        0x06  //--1
        0x5b  //--2
        0x4f  //--3
        0x66  //--4
        0x6d  //--5
        0x7d  //--6
        0x07  //--7
        0x7f  //--8
        0x6f  //--9
        0x00   //--NULL
};

void key();                                        //按键扫描子程序
void SegmentDisplay();                                //显示子程序
void Buzzer();


void delaylms(int ms)                //延时子程序
{
        uint jk;
        for(j=0;j<ms;j++)                        //延时ms
           for(k=0;k<124;k++);                //大约1毫秒的延时
}

/@@*定时器0初始化*/
void Timer0Init(){
        TMOD |= 0X01;
        TH0 = 0X4B;
        TL0 = 0XFC;
        ET0 = 1;
        EA = 1;
        TR0 = 1;
}
/@@*定时器1初始化*/
void Timer1Init(){
        TMOD |= 0X10;
        TH1 = 0X4B;
        TL1 = 0XFC;
        ET1 = 1;
        EA = 1;
        TR1 = 1;
}

/@@*主程序*/
void main()
{
        Timer0Init();
        Timer1Init();
        TR1 = 0;
        P2=0Xc3;                                        // 默认东西绿灯,南北红灯灯   
  DefaultVal_NB=DefaultVal_DX+5; //设置南北通行时间比东西多5秒
        while(1)               
        {         
                key();
                SegmentDisplay();
        }       
}
/@@*按键扫描子程序*/
void key(void){
        if(k1!=1)        {
                delaylms(10);
                if(k1!=1){
                  TR0=0;
                        Shanshuo=0;
                        P2=0x00;
                        TR1=0;
                        if(set==0)//设置键按下
                                setTime_DX++;//南北加1
                        else
                                setTime_NB++;//东西加1
                        if(setTime_NB==100)
                                setTime_NB=1;
                        if(        setTime_DX==100)
                                setTime_DX=1;//加到100置1
                        DefaultVal_NB=setTime_NB ;//设置的数值赋给东西南北
                        DefaultVal_DX=setTime_DX;                       
                  do        {
                                SegmentDisplay();
                        }while(k1!=1);//松手检测
                }
        }

        if(k2!=1)        {                                                        //当K2(时间减)按键按下时
                delaylms(10);
                if(k2!=1){
                         TR0=0;
                        Shanshuo=0;
                        P2=0x00;
                        TR1=0;
                        if(set==0)
                                setTime_DX--;
                        else
                                setTime_NB--;
                        if(setTime_NB==0)
                                setTime_NB=99;       
                        if(        setTime_DX==0 )
                                setTime_DX=99;
                        DefaultVal_NB=setTime_NB ;
                        DefaultVal_DX=setTime_DX;
                  do{         
                                SegmentDisplay();
                        }
                        while(k2!=1);
                }
        }
        if(k3!=1) {
                delaylms(10);
                if(k3!=1){
                  
                         TR0=0;
                        set=!set;
                        TR1=0;
                        dx_nb=set;
                        do{
                                SegmentDisplay();
                        }                               
                        while(k3!=1);
                }
        }       

        if(k4!=1){
                delaylms(10);
                if(k4!=1){
                        TR0=0;
                        P2=0x00;
                        RED_DX=1;
                        RED_NB=1;
                        TR1=0;
                        DefaultVal_DX=30;
                        DefaultVal_NB=30;
                        TR0 = 1;
                        do{
                                SegmentDisplay();
                                SPEAKER = !SPEAKER;
                                if((DefaultVal_DX == 0)&&(DefaultVal_NB==0)){
                                        SPEAKER = 1;
                                }
                        }       
                        while(k4!=1);
                }
        }
}
/@@*数码管显示程序*/
void SegmentDisplay(void)
{               
        DirectVal[1]=DefaultVal_NB/10;                 // 东西秒十位
        DirectVal[2]=DefaultVal_NB%10;                 // 东西秒个位
        DirectVal[3]=DefaultVal_DX/10;                 // 南北秒十位
        DirectVal[0]=DefaultVal_DX%10;                 // 南北秒个位               
        P1=0xff;
        P0=0x00;
        P1=0xfe;
        P0=TABLE[DirectVal[1]];       
        delaylms(1);
        P1=0xff;
        P0=0x00;
                                                  
        P1=0xfd;
        P0=TABLE[DirectVal[2]];
        delaylms(1);
        P1=0xff;
        P0=0x00;
        P1=0Xfb;
        P0=TABLE[DirectVal[3]];
        delaylms(1);
        P1=0xff;
        P0=0x00;
        P1=0Xf7;
        P0=TABLE[DirectVal[0]];
        delaylms(1);
}

void time0(void) interrupt 1 using 1
{
        TH0=0X4b;
        TL0=0Xfc;
        TR0=1;
        Count++;
        if(Count==10){
                if((DefaultVal_NB<=5)&&(dx_nb==0)&&(Shanshuo==1)){//东西黄灯闪               
                        GREEN_DX=0;
                        YELLOW_DX=0;
                }                                                  
          if((DefaultVal_DX<=5)&&(dx_nb==1)&&(Shanshuo==1)){//南北黄灯闪               
                        GREEN_NB=0;
                        YELLOW_NB=0;
                }       
        }       
        if(Count==20){
                Count=0;
                DefaultVal_DX--;                                                //东西时间减1
                DefaultVal_NB--;                                                //南北时间减1
                if((DefaultVal_NB<=5)&&(dx_nb==0)&&(Shanshuo==1)){//东西黄灯闪               
                        GREEN_DX=0;
                        YELLOW_DX=1;
                }                                                  
          if((DefaultVal_DX<=5)&&(dx_nb==1)&&(Shanshuo==1)){//南北黄灯闪               
                        GREEN_NB=0;
                        YELLOW_NB=1;
                }                                                                
                if(DefaultVal_DX==0&&DefaultVal_NB==5){//当东西倒计时到0时,重置5秒,用于黄灯闪烁时间   
                        DefaultVal_DX=5;
                        Shanshuo=1;
                }
                if(DefaultVal_NB==0&&DefaultVal_DX==5){//当南北倒计时到0时,重置5秒,用于黄灯闪烁时间   
                        DefaultVal_NB=5;
                        Shanshuo=1;
                }
                if(dx_nb==0&&DefaultVal_NB==0){//当黄灯闪烁时间倒计时到0时,
                        P2=0x00;//重置东西南背方向的红绿灯
                        GREEN_NB=1;
                        RED_DX=1;
                        dx_nb=!dx_nb;
                        Shanshuo=0;
                        DefaultVal_NB=setTime_NB;        //重赋南北方向的起始值
                        DefaultVal_DX=setTime_NB+5;//重赋东西方向的起始值
                }               
                if(dx_nb==1&&DefaultVal_DX==0){        //当黄灯闪烁时间到
                        P2=0X00;                                        //重置东西南北的红绿灯状态
                        GREEN_DX=1;                                //东西绿灯亮
                        RED_NB=1;                                        //南北红灯亮
                        dx_nb=!dx_nb;
                        Shanshuo=0;
                        DefaultVal_DX=setTime_DX;                        //重赋东西方向的起始值
                        DefaultVal_NB=setTime_DX+5;                //重赋南北方向的起始值
                }
        }       
}
void time1(void) interrupt 3{
        TH1=0X4b;
        TL1=0Xfc;
        Count1++;
        if(Count1==10)
        {
                YELLOW_NB=0;//南北黄灯灭
                YELLOW_DX=0;//东西黄灯灭
        }
        if(Count1==20){
                Count1=0;
                YELLOW_NB=1;//南北黄灯亮
                YELLOW_DX=1;//东西黄灯亮
        }       
}

0 0 收起

我来回答

上传资料:
选择文件 文件大小不超过15M(格式支持:doc、ppt、xls、pdf、zip、rar、txt)
最佳答案
  • 我认为有两种可能导致,不知道你指的不准是哪种,需要你再进行详细的描述

    1.固有的误差,采用定时器本来就有误差,再加上晶振选择不当的话,误差会更大,这个可以通过选择合适的晶振即可解决。因为你设计的是交通灯,最大定时也就100多秒,不大可能是固定误差累计导致的不准。

    2.程序设计不合理导致的,倾向于这个。由于按键和显示的延时放在while循环中,按键扫描或显示中的delay延时导致产生了误差。


    • 发布于 2020-11-20
    • 举报
    • 评论 0
    • 0
    • 0

其他答案 数量:1
  • 如果整体偏快,应该是时基计算不准确,或者是时基源不准确(比如该用5M晶振,结果是用的8M晶振)
    • 发布于2020-11-20
    • 举报
    • 评论 0
    • 0
    • 0

相关问题

问题达人换一批

求助,这个交通灯代码秒表走的很快,应该怎么修改