找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5001|回复: 3
打印 上一主题 下一主题
收起左侧

89C51控制交通灯系统程序

[复制链接]
跳转到指定楼层
楼主
#include <reg52.h>          //调用单片机头文件
#define uchar unsigned char   //宏定义"uchar"代替"unsigned char"。
#define uint  unsigned int   //宏定义"uint"用来定义无符号整型数。

uchar a_a;
////数码管段选定义  0   1    2    3    4    5  6  7   8    9
uchar smg_du[]={0x6f,0x03,0x3d,0x4b,0x53,0x75,0x7e,0x28,0x7f,0x7b,
//        A B  C   D    E   F 不显示
             0x77,0x5e,0x4a,0x05,0x0a,0x2a,0xff};  //断码
uchar dis_smg[8] = {0};
uchar smg_i = 4;    //显示数码管的个位数
//数码管位选定义
sbit smg_we1 = P2^1; //数码管位选定义
sbit smg_we2 = P2^0;
sbit smg_we3 = P3^6;
sbit smg_we4 = P3^7;
uint dx_zong   = 0;
uint nb_zong   = 0;
int dx_s = 0,nb_s = 0; //东西  南北 倒计时变量
sbit dx_red    = P2^7;     //东西红灯
sbit dx_yellow = P2^6;  //东西黄灯
sbit dx_green  = P2^5;  //东西绿灯
sbit nb_red    = P2^4;  //南北红灯
sbit nb_yellow = P2^3;  //南北黄灯
sbit nb_green  = P2^2;  //南北绿灯
sbit nb_green_ll  = P1^6;  //南北绿灯
sbit dx_green_ll  = P1^7;  //东西绿灯
sbit dx_h_red = P3^5;        //东西人行横道红灯
sbit dx_h_green = P3^4;      //东西人行横道红灯
sbit nb_h_red = P3^2;        //南北人行横道红灯
sbit nb_h_green = P3^3;      //南北人行横道红灯
sbit nb_che = P1^4;         //南北车计流量
sbit dx_che = P1^5;         //东西车计流量
uint nb_che_value;
uint dx_che_value;
uchar  nb[20];
uchar xdata dx[20];
uchar flag_che,miao;   //本看车流量
uchar flag_jtd_mode;  //交通灯的模式 根据时间
bit flag_1s = 0;
bit flag_500ms;
bit flag_dx_nb = 0;   //东西南北模式
uchar flag_5m_value;
uchar i;
uchar dx_time = 30,nb_time = 20;   //东西、南北的时间
uchar nb_time_ll = 20,dx_time_ll = 20;   //东西、南北左转的时间
uchar yellow_time = 5;
uchar flag_jdgz ;     //交通管制
uchar nb_ll,dx_ll;   //南北 东西加的时间
/***********************数码位选函数*****************************/
void smg_we_switch(uchar i)
{
switch(i)
{
  case 0: smg_we1 = 0;  smg_we2 = 1; smg_we3 = 1;  smg_we4 = 1; break;
  case 1: smg_we1 = 1;  smg_we2 = 1; smg_we3 = 0;  smg_we4 = 1; break;
  case 2: smg_we1 = 1;  smg_we2 = 0; smg_we3 = 1;  smg_we4 = 1; break;
  case 3: smg_we1 = 1;  smg_we2 = 1; smg_we3 = 1;  smg_we4 = 0; break;
}
}
/********************************************************************
* 名称 : delay_1ms()
* 功能 : 延时1ms函数
* 输入 : q
* 输出 : 无
***********************************************************************/
void delay_1ms(uint q)
{
uint i,j;
for(i=0;i<q;i++)
  for(j=0;j<110;j++);
}
/********************************************************************
* 名称 : display()
* 功能 : 数码管显示
* 输入 : 无
* 输出 : 无
***********************************************************************/
void display()
{
uchar i;
for(i=0;i<smg_i;i++)
{  
  smg_we_switch(i);     //位选
  P0 = dis_smg[i];   //段选   
}
}
/*********************定时器0、定时器1初始化******************/
void time0_init()   
{
EA  = 1;     //开总中断
TMOD = 0X11;   //定时器0、定时器1工作方式1
ET0 = 1;    //开定时器0中断
TR0 = 1;    //允许定时器0定时
}
uchar flag_csf=1;
uchar f_value=0;

/*********************交通灯处理函数*********************************/
void jiaotongdeng_dis()
{
/***********************南北时间*********************************/
  if(f_value < nb_ll + nb_time) //南北绿灯时间
  {
   if(flag_csf == 1)   //意思是只初始化一次
   {
    flag_csf = 2;   
    dx_zong = dx_s = nb_ll + nb_time_ll + yellow_time; //是显示南北的总时间      
    nb_s = nb_ll + nb_time; //给南北倒计时显示初始化值
   }
   dx_red    = 0;     
   dx_green  = 1;//灭
   dx_yellow = 1;//灭
   nb_red    = 1;     
   nb_green  = 0;   
   nb_yellow = 1;    //灭

   nb_green_ll = 1;
   dx_green_ll = 1;
   flag_5m_value = 0;
  }
  else if(f_value < nb_ll + nb_time + yellow_time)   //当小于5秒时  黄灯要闪了
  {
   if(flag_csf == 2)   //意思是只初始化一次
   {
    flag_csf = 3;
    dx_s = nb_time_ll + 2*yellow_time; //是显示南北的总时间      
    nb_s = yellow_time; //给南北倒计时显示初始化值
   }   
   dx_red    = 0;     
   dx_green  = 1;    //灭
   dx_yellow = 1;    //灭
   nb_red    = 1;     
   nb_green  = 1;    //灭
   if(flag_500ms == 0)    //黄灯闪烁
   {
    nb_yellow = 0;  
   }
   else
   {
    nb_yellow = 1;  
   }
   dx_h_green = 1;
   dx_h_red = 0;
   nb_h_green = 0;
   nb_h_red = 1;
  }
  else if(f_value < nb_ll + nb_time + nb_time_ll)   //当左转的绿灯闪
  {
   if(flag_csf == 3)   //意思是只初始化一次
   {
    flag_csf = 4;
    dx_s = nb_time_ll + yellow_time; //是显示南北的总时间      
    nb_s = nb_time_ll; //给南北倒计时显示初始化值
   }   
   dx_red    = 0;     
   dx_green  = 1;    //灭
   dx_yellow = 1;    //灭
   nb_green  = 1;    //灭
   nb_yellow = 1;    //灭
   dx_h_green = 1;
   dx_h_red = 0;
   nb_h_green = 1;

  }
  else if(f_value < nb_ll + nb_time +  nb_time_ll)   //当小于5秒时  黄灯要闪了
  {
   if(flag_csf == 4)   //意思是只初始化一次
   {
    flag_csf = 1;
    dx_s = nb_s = yellow_time; //给南北倒计时显示初始化值
   }   
   dx_red    = 0;     
   dx_green  = 1;    //灭
   dx_yellow = 1;    //灭
   if(flag_500ms == 0)    //黄灯闪烁
   {
    nb_yellow = 0;  
   }
   else
   {
    nb_yellow = 1;    //灭  
   }
   dx_h_green = 1;     //灭
   nb_h_green = 1;     //灭
   nb_h_red = 0;
  
   nb_green_ll = 1;    //灭
   dx_green_ll = 1;    //灭
  }  
/***********************东西时间*********************************/
  if(flag_dx_nb == 1)  
  {
   if(f_value < dx_ll + dx_time) //东西绿灯时间
   {
    if(flag_csf == 1)   //意思是只初始化一次
    {
     flag_csf = 2;   
     nb_zong = nb_s = dx_ll +  dx_time_ll + 2*yellow_time; //是显示南北的总时间      
     dx_s = dx_ll + dx_time; //给南北倒计时显示初始化值
    }
    dx_red    = 1;    //灭   
    dx_green  = 0;
    dx_yellow = 1;    //灭
    nb_red    = 0;  
    nb_green  = 1;    //灭
    nb_yellow = 1;    //灭
    dx_h_green = 0;
    dx_h_red = 1;    //灭
    nb_h_green = 1;    //灭
    nb_h_red = 0;
    nb_green_ll = 1;    //灭
    dx_green_ll = 1;    //灭
    flag_5m_value = 0;
   }
   else if(f_value < dx_ll + dx_time+ yellow_time)   //当小于5秒时  黄灯要闪了
   {
    if(flag_csf == 2)   //意思是只初始化一次
    {
     flag_csf = 3;
     nb_s = dx_time_ll + 2*yellow_time; //是显示南北的总时间        
     dx_s = yellow_time; //给南北倒计时显示初始化值
//     while(1);
    }   
    dx_red    = 1;    //灭   
    dx_green  = 1;    //灭   
    nb_red    = 0;   
    nb_green  = 1;    //灭   
    nb_yellow = 1;    //灭   
    if(flag_500ms == 0)
    {
     dx_yellow = 0;
    }
    else
    {
     dx_yellow = 1;    //灭
    }
    dx_h_green = 0;
    dx_h_red = 1;    //灭
    nb_h_green = 1;    //灭
    nb_h_red = 0;
   }
   else if(f_value < dx_ll + dx_time+dx_time_ll+ yellow_time)   //东西左转
   {
    if(flag_csf == 3)   //意思是只初始化一次
    {
     flag_csf = 4;
     nb_s = dx_time_ll + yellow_time; //是显示南北的总时间        
     dx_s = dx_time_ll; //给南北倒计时显示初始化值
    }   
    dx_red    = 1;    //灭   
    dx_green  = 1;    //灭   
    dx_yellow = 1;    //灭
    nb_red    = 0;   
    nb_green  = 1;    //灭   
    nb_yellow = 1;    //灭   
    dx_h_green = 1;    //灭
    nb_h_green = 1;    //灭
    nb_h_red = 0;
    nb_green_ll = 1;
    dx_green_ll = 0;
   }
   else if(f_value < dx_ll + dx_time+dx_time_ll+ yellow_time*2)   //当小于5秒时  黄灯要闪了
   {
    if(flag_csf == 4)   //意思是只初始化一次
    {
     flag_csf = 1;
     nb_s =  yellow_time; //是显示南北的总时间        
     dx_s = yellow_time; //给南北倒计时显示初始化值
    }   
    dx_red    = 1;    //灭   
    dx_green  = 1;    //灭   
    nb_red    = 0;   
    nb_green  = 1;    //灭   
    nb_yellow = 1;    //灭   
    if(flag_500ms == 0)
    {
     dx_yellow = 0;
    }
    else
    {
     dx_yellow = 1;    //灭
    }
    dx_h_green = 1;    //灭
    dx_h_red = 0;
    nb_h_green = 1;    //灭
    nb_h_red = 0;
    nb_green_ll = 1;    //灭
    dx_green_ll = 1;    //灭
   }
  }
if(flag_1s == 1)
{
  flag_1s = 0;
  miao ++;
  if(miao >= 60)
  {
   miao = 0;
  }
  dx_che_value = 0;
  dx_s --;
  nb_s --;
  f_value ++;
  if(flag_dx_nb == 0)    //南北时间
  {
   if(f_value >= dx_zong)
   {
    f_value = 0;
    flag_dx_nb = 1;   //东西绿灯模式
    if(nb_che_value >= 30)
    {
     nb_ll = 20;
    }
    else if(nb_che_value >= 20)
    {
     nb_ll = 10;
    }
    else
    {
     nb_ll = 0;
    }
   }
  }
  if(flag_dx_nb == 1)    //东西时间
  {
   if(f_value >= nb_zong)
   {
    f_value = 0;
    flag_dx_nb = 0;   //南北绿灯模式
    if(dx_che_value >= 30)
    {
     dx_ll = 20;
    }
    else if(dx_che_value >= 20)
    {
     dx_ll = 10;
    }
    else
    {
     dx_ll = 0;
    }
   }
  }
}   
dis_smg[0] = smg_du[dx_s % 10] ; //显示
dis_smg[1] = smg_du[dx_s / 10] ;
dis_smg[2] = smg_du[nb_s % 10] ;
dis_smg[3] = smg_du[nb_s / 10] ;
}
/********************独立按键程序*****************/
uchar key_can;  //按键值
void key()  //独立按键程序
{
static uchar key_new;
key_can = 20;                   //按键值还原
P1 |= 0x0f;
if((P1 & 0x0f) != 0x0f)  //按键按下
{
  delay_1ms(1);       //按键消抖动
  if(((P1 & 0x0f) != 0x0f) && (key_new == 1))
  {      //确认是按键按下
   key_new = 0;
   switch(P1 & 0x0f)
   {
    case 0x0e:  key_can = 4;  break;  //得到按键值
    case 0x0d:  key_can = 3;  break;  //得到按键值
    case 0x0b:  key_can = 2;  break;  //得到按键值
    case 0x07:  key_can = 1;  break;  //得到按键值
   }
  }   
}
else
  key_new = 1;
}
uchar menu_1,flag_s;

/********************设置函数*****************/
void key_with()
{
if(menu_1 == 0)
{
  if(key_can == 2)
   flag_che = 1;  //查看车流量
  if(key_can == 3)
   flag_che = 0;
}
if(key_can == 4)   //交通管制按键
{
  flag_jdgz ++;
  if(flag_jdgz > 6)
  {
   flag_jdgz = 0;
  }
  if(flag_jdgz == 1)  //  全部亮红灯
  {
   dx_green  = 1;    //灭
   dx_yellow = 1;    //灭
   nb_green  = 1;    //灭
   nb_yellow = 1;    //灭   

   nb_green_ll = 1;    //灭
   dx_green_ll = 1;    //灭
  }
  if(flag_jdgz == 2)  //  南北黄灯  东西黄灯
  {
   dx_red    = 1;    //灭   
   dx_green  = 1;    //灭
   dx_yellow = 0;    //亮
   nb_red    = 1;    //灭   
   nb_green  = 1;    //灭
   nb_yellow = 0;    //亮  
   
   nb_green_ll = 1;    //灭
   dx_green_ll = 1;    //灭
  }
  if(flag_jdgz == 3)  //  东西红灯  南北绿灯
  {
   dx_red    = 0;    //亮  
   dx_green  = 1;    //灭
   dx_yellow = 1;    //灭
   nb_red    = 1;    //灭   
   nb_green  = 0;    //亮
   nb_yellow = 1;    //灭   

   dx_h_green = 1;    //灭
   dx_h_red = 1;    //亮
   nb_h_green = 0;    //亮
   nb_h_red = 1;    //灭
   nb_green_ll = 1;    //灭
   dx_green_ll = 1;    //灭
  }
  if(flag_jdgz == 4)  //  南北红灯  东西绿灯
  {
   dx_red    = 1;    //灭   
   dx_green  = 0;    //亮
   dx_yellow = 1;    //灭
   nb_red    = 0;    //亮  
   dx_h_green = 0;    //亮
   dx_h_red = 1;    //灭
   nb_h_green = 1;    //灭
   nb_h_red = 0;    //亮
  }
  if(flag_jdgz == 5)  //    南北左转绿灯
  {
   dx_red    = 0;    //亮   
   dx_green  = 1;    //灭
   nb_green  = 1;    //灭
   nb_yellow = 1;    //灭   
   dx_h_green = 1;    //灭
   dx_h_red = 0;    //亮
   nb_h_green = 1;    //灭
   nb_h_red = 0;    //亮
  }
  if(flag_jdgz == 6)  //  南北红灯  东西左转绿灯
  {
   dx_red    = 0;    //亮   
   dx_green  = 1;    //灭
   dx_yellow = 1;    //灭
   nb_yellow = 1;    //灭   
   dx_h_green = 1;    //灭
   dx_h_red = 0;    //亮
   nb_h_green = 1;    //灭
   nb_h_red = 0;    //亮
   nb_green_ll = 1;    //灭
   dx_green_ll = 0;
  }
}
if(key_can == 1)   //设置键
{
  menu_1 ++;
  if(menu_1 > 5)
  {     
   menu_1  = 0;
  }
}
if(menu_1 == 1)    //设置东西的时间
{
  if(key_can == 2)
  {
   dx_time ++ ;  //加1
   if(dx_time > 99)
    dx_time = 99;
  }
  if(key_can == 3)
  {
   dx_time -- ;  //减1
   if(dx_time <= 5)
    dx_time = 5;
  }
  dis_smg[0] = smg_du[dx_time % 10] ;  //显示东西设置的时候
  dis_smg[1] = smg_du[dx_time / 10] ;
}
if(menu_1 == 2)    //设置南北的时间
{
  if(key_can == 2)
  {
   nb_time ++ ;  //加1
   if(nb_time > 99)
    nb_time = 99;
  }
  if(key_can == 3)
  {
   nb_time -- ;  //减1
   if(nb_time <= 5)
    nb_time = 5;
  }
  dis_smg[2] = smg_du[nb_time % 10] ;  //显示东西设置的时候
  dis_smg[3] = smg_du[nb_time / 10] ;
}
if(menu_1 == 3)    //设置黄灯的时间
{
  if(key_can == 2)
  {
   yellow_time ++ ;  //加1
   if(yellow_time > 99)
    yellow_time = 99;
  }
  if(key_can == 3)
  {
   yellow_time -- ;  //减1
   if(yellow_time <= 1)
    yellow_time = 1;
  }
  dis_smg[0] = smg_du[yellow_time % 10] ;  //显示黄灯时间
  dis_smg[1] = smg_du[yellow_time / 10] ;
  dis_smg[2] = smg_du[yellow_time % 10] ;  //显示黄灯时间
  dis_smg[3] = smg_du[yellow_time / 10] ;
}
if(menu_1 == 4)    //设置东西左边的时间
{
  if(key_can == 2)
  {
   dx_time_ll ++ ;  //加1
   if(dx_time_ll > 99)
    dx_time_ll = 99;
  }
  if(key_can == 3)
  {
   dx_time_ll -- ;  //减1
   if(dx_time_ll <= 5)
    dx_time_ll = 5;
  }
  dis_smg[0] = smg_du[dx_time_ll % 10] ;  //显示东西设置的时候
  dis_smg[1] = smg_du[dx_time_ll / 10] ;
  dis_smg[2] = 0xcc ; //不显示
  dis_smg[3] = 0x00 ; //L
}
if(menu_1 == 5)    //设置南北左转的时间
{
  if(key_can == 2)
  {
   nb_time_ll ++ ;  //加1
   if(nb_time_ll > 99)
    nb_time_ll = 99;
  }
  if(key_can == 3)
  {
   nb_time_ll -- ;  //减1
   if(nb_time_ll <= 5)
    nb_time_ll = 5;
  }
  dis_smg[0] = 0x00 ; //不显示
  dis_smg[1] = 0xcc ; //L
  dis_smg[2] = smg_du[nb_time_ll % 10] ;  //显示东西设置的时候
  dis_smg[3] = smg_du[nb_time_ll / 10] ;
}
}

/********************车计流量程序*****************/
void che_liuliang()  //车计流量程序
{
static uchar value1,value2;
if(nb_che == 0)  //计南北车的流量
{
  delay_1ms(1);       //按键消抖动
  if((nb_che == 0) && (value1 == 1))
  {      //确认是按键按下
   value1 = 0;
   nb[miao] += 1;
  }   
}
else
  value1 = 1;
if(dx_che == 0)  //计东西车的流量
{
  delay_1ms(1);       //按键消抖动
  if((dx_che == 0) && (value2 == 1))
  {      //确认是按键按下
   value2 = 0;
   dx[miao] += 1;
  }   
}
else
  value2 = 1;
}

/********************************************************************
* 名称 : main()
* 功能 : 实现灯的闪烁
* 输入 : 无
* 输出 : 无
*********************************************************************/
void main()
{
time0_init();
while(1)
{   
  key();
  if(key_can < 20)
   key_with();
  che_liuliang();  //车计流量程序
  jiaotongdeng_dis();
  display();
}
}  
/*********************定时器0中断服务程序************************/
void time0_int() interrupt 1  
{         
static uchar value;    //定时10ms中断一次
TH0 = 0x3c;
TL0 = 0xb0;     //50ms
value ++;
flag_5m_value++;
if(flag_5m_value % 10 == 0)
  flag_500ms = ~flag_500ms;
if(value >= 20)
{
  value = 0;
  flag_1s = 1;
}
}

TIM图片20180611000732.png (86.28 KB, 下载次数: 66)

TIM图片20180611000732.png
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:464230 发表于 2019-3-14 13:47 | 只看该作者
这程序仿真时就出错,不对
回复

使用道具 举报

板凳
ID:493144 发表于 2019-3-28 12:52 | 只看该作者
九幽幻辰 发表于 2019-3-14 13:47
这程序仿真时就出错,不对

请问您改出来了吗?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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