龟儿子苓膏 2024-02-27 02:02 采纳率: 81.3%
浏览 49
已结题

C51单片机设计交通灯时出现的问题


#include<reg52.h> 
#define uchar unsigned char 
#define uint unsigned int 
#define ON 0 
#define OFF 1 
sbit B_G=P2^3; // B??? 
sbit B_R=P2^2; // B???

sbit A_G=P2^1; // A???
sbit A_R=P2^0; // A???
sbit LED_B2=P3^7;
sbit LED_B1=P3^6; // B???????
sbit LED_A2=P3^1;
sbit LED_A1=P3^0; // A???????

sbit key1=P3^2;                //?????
sbit key2=P3^3;
sbit key3=P3^4;

/********* ?????? *************/ 
uchar AG=45,AR=5,BG=25,BR=5,ABR=20,AK=30,BK=30;
uchar count; 
void keyscan1()        //k1???? 
{
    if(!key1)
    {
        while(!key1);        //????
    }
}
void keyscan2()        //k2???? 
{
    if(!key2)
    {
        while(!key2);        //????
    }
}
void keyscan3()        //k2???? 
{
    if(!key3)
    {
        while(!key3);        //????
    }
}

void init(void) 
    { 
    TMOD |= 0x01;  //???,???,???,16???
 TH0=(65536-40000)/256; 
    TL0=(65536-40000)%256; 
    EA=1; 
    ET0=1; 
    TR0=1;    
    } 
void timer1(void) interrupt 1 
    { 
    TMOD |= 0x01;  //???,???,???,16???
 TH0=(65536-40000)/256; 
    TL0=(65536-40000)%256; 
    EA=1; 
    ET0=1; 
    TR0=1; 
            count++; 
    if(count>44) 
            { 
            AG--; 
            AR--; 
            BG--; 
            BR--; 
            ABR--; 
            AK--; 
            count=0; 
            } 
    }
 
/****************** ?? **********************/ 
void delay(uchar z) 
        { 
        uchar x,y; 
        for(x=z;x>0;x--) 
        for(y=110;y>0;y--); 
        }

/******************led ?? *******************/ 
unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// ????????
void display1(uchar num1,uchar num2) //??A?? led ??
{ 

    P0=table[num1]; 
    LED_A1=ON; 
    delay(1); 
    LED_A1=OFF; 

    P0=table[num2]; 
    LED_A2=ON; 
    delay(1); 
    LED_A2=OFF; 
} 
void display2(uchar num3,uchar num4) // ??B??led ??
{ 
 
    P0=table[num3]; 
    LED_B1=ON; 
    delay(1); 
    LED_B1=OFF; 

    P0=table[num4]; 
    LED_B2=ON; 
    delay(1); 
    LED_B2=OFF; 
}
void main() 
{ 
    int i;
/************ ????************/ 
    A_R=ON; //A?????
    B_R=ON; //B?????
    for(i=0;i<210;i++) 
        { 
        delay(10); 
        } 
    A_R=OFF;//A????? 
    B_R=OFF;// B?????    
    
        /************** ??1:A???? (45s),?? (5s)************/ 
        /************** ??2:B???? (25s),?? (5s)***************/
            while(1) 
            { 
                init(); // ?????? 
        
                A_G=ON; //A????? 
                while(AG!=0) 
                { 
                    display1(AG/10,AG%10);// A??? (45s)  
                    A_G=OFF;
                    A_R=ON;
                    while(AG==0) 
                    { 
                        while(AR!=0) 
                        { 
                                 if(!key1)//??k1
    {
                  display2(20/10,20%10);
    } 
                if(!key2)
  {
                display2(30/10,30%10);
  }
                  if(!key3)
  {
                    display2(30/10,30%30);
    }
              else{
                        display2(AR/10,AR%10);//A??? (5s)  
                        A_R=OFF;
                        B_G=ON;
                        } }
                    } 
                 }
             while(BG!=0)
 {
   display1(BG/10,BG%10);//B???(25s)
               B_G=OFF;
               B_R=ON;
   while(BG==0)
{
  while(BR!=0)
{
        if(!key1)//??k1
    {
                  display2(AR/20,AR%20);
    } 
                if(!key2)
  {
                display2(AR/30,AR%30);
  }
                  if(!key3)
  {
                    display2(BR/30,BR%30);
    }
              else{
   display2(BR/10,BR%10);//B???(5s)
     B_R=OFF;
}}
}
 }     
           AG=45,AR=5,BG=25,BR=5,ABR=20,AK=30,BK=30;// ????            
            }    
        }

img


以MCS-51系统为核心,设计交通灯控制器。十字路口交通灯由红、绿两色LED显示器(两位8段LED显示器)组成,LED显示器显示切换倒计时,以秒为单位,每秒更新一次;为确保安全,绿LED计数到0转红,经5秒延时(显示红色0)后,另一道开始绿色倒计时。基本要求:主干道(A道)先通行且通行时间为45 s(加5秒红灯延时,共50秒);支道(B道)通行时间为25 s(加5秒红灯延时,共30秒);主道与支道的车辆交错通行;若遇紧急情况,按开关K1时,主道与支道都为红灯20 s;根据实时交通堵塞情况人为控制时,按K2时,主道延时30 s通行,按K3时,支道延时30 s通行

为什么我这个45s倒计时的时候还正常,到了5s倒计时的时候不是从5s开始而是从6s开始,并且往后一直在09重复倒计时

  • 写回答

29条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-02-27 08:31
    关注
    获得2.00元问题酬金

    引自免费微信小程序:皆我百晓生

    在分析您提供的代码片段时,注意到一个关键问题可能与倒计时从5s开始时异常有关。您在timer1中断服务程序中更新了全局变量count和各个交通灯时间变量(如AG, AR, BG, BR等),但并未正确处理交通灯状态切换的逻辑。

    问题在于:

    1. timer1中断中,每当count超过44(即每过大约1秒钟)时,所有的倒计时变量都会递减,而不是仅递减当前应该递减的交通灯计数器。这将导致所有计数器同时减少,并非按照预期独立控制A、B两个方向的交通灯。

    2. 对于按键扫描函数(keyscan1、keyscan2、keyscan3),它们没有明确地跳出循环以检测下一次按键状态变化,这可能导致按键响应不及时或无法正常工作。

    为了修复这个问题,您需要重新设计逻辑,使得每个方向的绿灯和红灯分别有自己的倒计时,并且在达到特定条件时进行正确的切换。以下是一个改进后的示例代码结构(注:由于篇幅限制,此处仅提供逻辑框架,具体实现请根据实际需求调整):

    void timer1(void) interrupt 1 
    {
        count++; 
    
        if(A_G && AG > 0) // 当A方向绿灯亮着并且计数未到零
        {
            AG--;
            if(AG == 0) // A方向绿灯结束,开启红灯
            {
                AG = ABR; // 重置下一个绿灯周期
                AR--; // 减少红灯计数
                if(AR == 0) // 红灯计数结束,准备切换至B方向
                {
                    AR = AK;
                    // 开启B方向绿灯逻辑...
                }
            }
        }
        else if(B_G && BG > 0) // 类似地处理B方向的绿灯和红灯
        {
            ...
        }
    }
    
    // 对按键的处理应确保能够快速响应并立即退出扫描循环
    void keyscan(key_number)
    {
        if(!key[number])
        {
            while(!key[number]);
            // 这里应处理按键事件并立即返回
        }
    }
    

    此外,请注意检查定时器初始化部分是否正确配置,以确保定时器1(T1)而非定时器0(T0)被使用,并且TH1和TL1寄存器被正确装载初值以产生每秒中断一次的频率。另外,在主循环中调用init()函数只应在系统启动时执行一次,而不是在每次循环开始时都执行。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 3月6日
  • 创建了问题 2月27日

悬赏问题

  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
  • ¥15 Windows11, backspace, enter, space键失灵