离知梦 2023-12-22 09:30 采纳率: 0%
浏览 41

keil4中编写的51单片机十字路口交通灯

仿真看着没问题,实际硬件开发板上红灯和黄灯是一闪一闪的,我们老师说可能是代码的逻辑问题


#include <reg51.h>
#define    uchar    unsigned char            //变量类型定义
#define    uint    unsigned int

sbit    EW_LED2=P0^3;        //东西数码管十位
sbit    EW_LED1=P0^2;        //东西数码管个位
sbit    SN_LED2=P0^1;        //南北数码管十位
sbit    SN_LED1=P0^0;        //南北数码管个位

sbit  SN_Red=P1^2;      //南北红灯
sbit  SN_Yellow=P1^3;   //南北黄灯
sbit  SN_Green=P1^4;    //南北绿灯
sbit  EW_Red=P1^5;      //东西红灯
sbit  EW_Yellow=P1^6;   //东西黄灯
sbit  EW_Green=P1^7;    //东西绿灯


char    Time_EW;          //东西数码管的显示时间
char    Time_SN;          //南北数码管的显示时间
uchar EW=20,SN=23;      //东西通行状态数码管初始化时间      
uchar EW1=18,SN1=15;    //南北通行状态数码管初始化时间 
uchar code table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0~9数码管段码(共阳极)


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

//数码管显示函数
void Display(void)
{
    char h,l;
    h=Time_EW/10;
    l=Time_EW%10;
  P3=table[l];EW_LED2=1;delay_ms(1);EW_LED2=0;
  P3=table[h];EW_LED1=1;delay_ms(1);EW_LED1=0;                //东西方向数码管秒数显示
    
    h=Time_SN/10;
    l=Time_SN%10;
  P2=table[l];SN_LED2=1;delay_ms(1);SN_LED2=0;
  P2=table[h];SN_LED1=1;delay_ms(1);SN_LED1=0;                //南北方向数码管秒数显示
} 






//主函数
void main(void)
{
    EA=1;                                  //定时器T0,方式1初始化    
    ET0=1;                                    
    TMOD=0x01;                             
    TL0 = 0xB0;                             
    TH0 = 0x3C;                   
    TR0 = 1;                     
  while(1)                                        
    {
    
        /*******状态1:东西方向绿灯80秒,南北方向红灯83秒*******/
        Time_EW=EW;                            //数码管赋初始值
        Time_SN=SN;                            
      while(Time_SN>=4)                
       {  
     
             SN_Yellow=0; //南北黄灯灭
             SN_Red=1;    //南北红灯亮
             SN_Green=0;  //南北绿灯灭
             EW_Yellow=0; //东西黄灯灭
             EW_Red=0;    //东西红灯灭
             EW_Green=1;  //东西绿灯亮
             Display();   //数码管显示
         }
         
        /*******状态2:东西方向黄灯3秒,南北方向红灯3秒*******/
       P1=0x00;            //清除灯的显示
         if(Time_SN==3)                    
                Time_EW=3;                    
      while(Time_SN>=1)                
       {
             SN_Yellow=0; //南北黄灯灭
             SN_Red=1;    //南北红灯亮
             SN_Green=0;  //南北绿灯灭
             EW_Yellow=1; //东西黄灯亮
             EW_Red=0;    //东西红灯灭
             EW_Green=0;  //东西绿灯灭
         Display();        //数码管显示     
       }
        /*******状态3:东西方向红灯60秒,南北方向绿灯60秒*******/        
        Time_EW=EW1;        //数码管赋初始值
        Time_SN=SN1;                            
       while(Time_EW>=4)            
        { 
             SN_Yellow=0; //南北黄灯灭
             SN_Red=0;    //南北红灯灭
             SN_Green=1;  //南北绿灯亮
             EW_Yellow=0; //东西黄灯灭
             EW_Red=1;    //东西红灯亮
             EW_Green=0;  //东西绿灯灭
         Display();        //数码管显示    
          }
        /*******状态4:东西方向红灯3秒,南北方向黄灯3秒*******/
            P1=0X00;           //清除灯的显示
            if(Time_EW==3)                
                Time_SN=3;                    
        while(Time_EW>=1)                
       {
            SN_Yellow=1; //南北黄灯亮
            SN_Red=0;    //南北红灯灭
            SN_Green=0;  //南北绿灯灭
            EW_Yellow=0; //东西黄灯灭
            EW_Red=1;    //东西红灯亮
            EW_Green=0;  //东西绿灯灭
        Display();     //数码管显示                 
       }
    } 
}


void timer0()  interrupt 1 
{
  uchar count;             
    TL0 = 0xB0;                              
    TH0 = 0x3C;                            
    count++;                            
    if(count==15)                                     
    {
        Time_EW--;                                     
        Time_SN--;                                   
      count=0;
    }
}
  • 写回答

2条回答 默认 最新

  • 小孟多 2023-12-22 14:52
    关注

    根据你提供的代码,很可能是定时器中断处理函数没有正确初始化计数器变量 count 的问题导致实际硬件上红灯和黄灯一闪一闪。在你的 timer0() 中断处理函数中,count 变量应该在函数外部声明并初始化为 0。修改后的代码如下:

    uchar count = 0; // 在函数外部声明并初始化计数器变量
    
    void timer0() interrupt 1 
    {
        TL0 = 0xB0;
        TH0 = 0x3C;
        count++;
        if(count == 15) // 满 15 次为 1 秒
        {
            Time_EW--;
            Time_SN--;
            count = 0; // 计数器清零
        }
    }
    
    
    

    请将这些更改应用于你的代码,然后重新编译和烧录到硬件开发板上进行测试。希望这能解决你遇到的问题!

    评论

报告相同问题?

问题事件

  • 创建了问题 12月22日