找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 950|回复: 0
收起左侧

mini51单片机交通灯程序,如何通过按键修改红绿灯的时间?

[复制链接]
ID:1026861 发表于 2022-5-17 18:53 | 显示全部楼层 |阅读模式
问一下,如何通过按键修改红绿灯的时间啊,如何添加程序求单片机大佬讲解

单片机源程序如下:
#include <reg51.h>
#define        uchar        unsigned char
#define        uint        unsigned int
/*****定义控制位**********************/
sbit        K4=P3^2;                        //恢复正常
sbit        K3=P3^3;                        //紧急(全部红灯)
sbit        K2=P3^4;                        //东西通行
sbit        K1=P3^5;                        //南北通行

sbit        EW_LED2=P2^3;        //EW_LED2控制位
sbit        EW_LED1=P2^2;        //EW_LED1控制位
sbit        SN_LED2=P2^1;        //SN_LED2控制位
sbit        SN_LED1=P2^0;        //SN_LED1控制位

sbit  SN_Yellow=P1^6; //SN黄灯
sbit  SN_Red=P1^7;    //SN红灯
sbit  SN_Green=P1^5;  //SN绿灯
sbit  EW_Yellow=P1^2; //EW黄灯
sbit  EW_Red=P1^3;    //EW红灯
sbit  EW_Green=P1^1;  //EW绿灯

bit          Restore_flag=0;                        //恢复正常标志位
bit   Flag_SN_Yellow;     //SN黄灯标志位
bit   Flag_EW_Yellow;     //EW黄灯标志位
char        Time_EW;  //东西方向倒计时单元
char        Time_SN;  //南北方向倒计时单元
uchar EW=25,SN=30;     //程序初始化赋值      
uchar EW1=30,SN1=25;   //用于存放修改值的变量
uchar KeyNumber=0;
uchar code table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0~~~~9段选码
uchar code S[9]={0X28,0X48,0X18,0X48,0X82,0X84,0X81,0X84,0x88};//交通信号灯控制代码

/**********************延时子程序************************/
void delay_ms(uint x) //延时ms
{
        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;
  P0=table[l];EW_LED2=0;delay_ms(1);EW_LED2=1;
  P0=table[h];EW_LED1=0;delay_ms(1);EW_LED1=1;                                //东西方向数码管显示
        
        h=Time_SN/10;
        l=Time_SN%10;
        P0=table[l];SN_LED2=0;delay_ms(1);SN_LED2=1;
  P0=table[h];SN_LED1=0;delay_ms(1);SN_LED1=1;                                //南北方向数码管显示        
}

/**********************INT0中断服务程序(按键扫描)*****************/
void int0_FXR() interrupt 0
{
        uchar FXR=P2;
        FXR=FXR&0Xf0;
        switch(FXR)
                {
                case 0x70 : KeyNumber = 1; break;
                case 0xb0 : KeyNumber = 2; break;
                case 0xd0 : KeyNumber = 3; break;
                case 0xe0 : KeyNumber = 4; break;
                default:KeyNumber = 0;
                }
}
/**********************T0中断服务程序*******************/
void timer0()  interrupt 1
{
        static uchar count;                         //count为静态变量初值为0
        TL0 = 0xB0;                                                          //重赋定时初值50ms
        TH0 = 0x3C;                                                         //重赋定时初值50ms
        count++;                                                                 //计数
        if(count==10)                                           //加快闪烁速度
        {
          if(Flag_SN_Yellow==1)  //测试南北黄灯标志位
          {SN_Yellow=~SN_Yellow;}//南北黄灯闪烁
          if(Flag_EW_Yellow==1)  //测试东西黄灯标志位
          {EW_Yellow=~EW_Yellow;}//东西黄灯闪烁
        }
        if(count==20)                                                                         //20*50=1000ms=1S        
        {
                Time_EW--;                                                                         //东西方向倒计时
                Time_SN--;                                                                   //南北方向倒计时
        if(Flag_SN_Yellow==1)                                        //测试南北黄灯标志位
            {SN_Yellow=~SN_Yellow;}                //南北黄灯闪烁
        if(Flag_EW_Yellow==1)                                        //测试东西黄灯标志位
            {EW_Yellow=~EW_Yellow;}                //东西黄灯闪烁
        count=0;
        }
}
void keyboard()
{
while(KeyNumber)
        {
        if(KeyNumber)
                {
                if(KeyNumber==1)
                        {
                                TR0=0;
                                Time_EW=0;                                                        //东西数码管赋值0s        
                                Time_SN=0;                                                        //南北数码管赋值0s                                                
                                while(KeyNumber==1)                        
                                {
                                  Flag_EW_Yellow=0;          //东西关黄灯显示信号
                                        P1=~S[0];                                                 //南北通行,东西红灯
                                        Display();                                  //调用显示函数                          
                                }
                  }
                if(KeyNumber==2)
                        {        
                                TR0=0;
                                Time_EW=0;                                                        //东西数码管赋值0s        
                                Time_SN=0;                                                        //南北数码管赋值0s
                                while(KeyNumber==2)                        
                                        {  
                                                Flag_SN_Yellow=0;          //东西关黄灯显示信号                          
                                                P1=~S[4];                                                         //东西通行,南北红灯
                                                Display();                                          //调用显示函数
                                        }
                        }
                if(KeyNumber==3)
                        {        
                                TR0=0;
                                Time_EW=0;                                                         //东西数码管赋值0s
                                Time_SN=0;                                                         //南北数码管赋值0s
                                while(KeyNumber==3)
                                        {
                                                P1=~S[8];                                                          //所有路口红灯
                                                Display();                                           //调用显示函数
                                        }
                        }
                if(KeyNumber==4)
                        {
                                TR0=1;
                                Time_EW=25;                                                        //东西数码管赋值25s        
                                Time_SN=30;                                                        //南北数码管赋值30s
                                Restore_flag=1;
                                break;
                        }
                }
        }
}
/*********************主程序开始**********************/
void main(void)
{
/*********************中断初始化**********************/
        IT0=1;                                                                         //设置外部中断0触发方式(下降沿触发)
        EX0=1;                                                                         //打开外部中断0的IE寄存器中断
        EA=1;                                                                           //CPU开中断总允许
        ET0=1;                                                                         //开定时中断
        TMOD=0x01;                                                         //定时器工作于方式1
        TL0 = 0xB0;                                                          //设置定时初值50ms
        TH0 = 0x3C;                           //设置定时初值50ms
        TF0 = 0;                             //清除TF0标志
        TR0 = 1;                             //定时器0开始计时
while(1)                                                                                
        {
                keyboard();
                if(Restore_flag)
                break;               
                /*******S1状态(东西直行状态)**********/
                Time_EW=EW;                                                        //东西数码管赋值25s        
                Time_SN=SN;                                                        //南北数码管赋值30s
          while(Time_SN>=6)                                //南北方向倒计时前25s循环体
           {  
                         Flag_SN_Yellow=0;          //东西关黄灯显示信号                          
                         P1=~S[4];                                                         //东西通行,南北红灯
                         Display();                                          //调用显示函数
                         keyboard();
                         if(Restore_flag)
                         break;
                 }
                /*******S2状态(东西直行黄灯闪烁状态)**********/
            P1=0xff;                                                        //所有路口红绿灯短时熄灭
                 if(Time_SN==5)                                        //当南北倒计时为5s时
                                Time_EW=5;                                        //东西重新从5s开始倒计时
          while(Time_SN>=1)                                //南北方向倒计时最后5s循环体
           {
                         Flag_EW_Yellow=1;                //东西开黄灯信号位
             SN_Red=0;                                                //东西黄灯开始闪烁,南北红灯亮        
             Display();                                                //调用显示函数
                         keyboard();
                         if(Restore_flag)
                         break;                        
           }
                /***********赋值(东西通行变南北通行)**********/
                EW=EW1;                                                                        //东西25s-->30s
                SN=SN1;                                                                        //南北30s-->25s         
                /*******S3状态(南北直行状态)**********/                        
                Time_EW=EW;                                                        //东西数码管赋值30s
                Time_SN=SN;                                                        //南北数码管赋值25s
           while(Time_EW>=6)                        //东西方向倒计时前25s循环体
            {
                                Flag_EW_Yellow=0;          //东西关黄灯显示信号
                                P1=~S[0];                                                 //南北通行,东西红灯
              Display();                                  //调用显示函数
                                keyboard();        
                                if(Restore_flag)
                          break;               
                  }
                /*******S4状态(南北直行黄灯闪烁状态)**********/
                        P1=0Xff;                                             //所有路口红绿灯短时熄灭
                        if(Time_EW==5)                                //当东西倒计时为5s时
                                Time_SN=5;                                        //南北重新从5s开始倒计时
                while(Time_EW>=1)                                //东西方向倒计时最后5s循环体
           {
             Flag_SN_Yellow=1;          //南北开黄灯信号位
                         EW_Red=0;            //南北黄灯开始闪烁,东西红灯亮
             Display();                                    //调用显示函数
                         keyboard();
                         if(Restore_flag)
                         break;                                 
           }
          /***********赋值(南北通行变东西通行)**********/
          EW=SN1;                                                                        //东西30s-->25s
                SN=EW1;                                                                        //南北25s-->30s         
        }
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表