基于MCS-51的交通灯程序设计(c语言控制直行左转)


一、说明:本程序与之前例程不同,采用c语言完成,实现四个方向的直走和左转车辆控制,采用51定时器精确计时


二、原理图:


三、基本设计思想:

1、硬件部分。七段数码管显示时间,采用共阳数码管,与P0口连接。根据51单片机的特性,P0口作为输出时,若要输出1,则必须外接上拉电阻。东西方向有直行红黄绿灯,左转红黄绿灯,共6个接口,分别接在P1.0~P1.5,显示时间的2位数码管位选开关接P1.6,P1.7。南北方向有直行红黄绿灯,左转红黄绿灯,共6个接口,分别接在P2.0~P2.5,显示时间的2位数码管位选开关接P2.6,P2.7。

本设计主要是介绍了单片机控制下的交通灯控制系统,详细介绍了其硬件和软件设计,并对其各功能模块做了详细介绍,其主要功能和指标如下:

2、软件部分。直行绿灯亮27s,数码管从30s倒计时,接着直行黄灯亮3秒,数码管闪烁倒计时3s。左转方向绿灯亮17s,数码管从20s倒计时,接着左转黄灯亮3s,数码管闪烁倒计时3s。开机东西直行绿灯27s,直行黄灯3s,左转绿灯17s,左转黄灯3s,此时南北方向一直红灯,倒计时50s。接着南北直行绿灯27s,直行黄灯3s,左转绿灯17s,左转黄灯3s,此时东西方向一直红灯,倒计时50s。

四、源代码:
#include 



#include 

#define uint unsigned int
#define uchar unsigned char 

#define OFF 0 //定义灯泡开关
#define ON 1

sbit ew_zx_red = P1^0;   //东西直行红黄绿
sbit ew_zx_yellow = P1^1;
sbit ew_zx_green = P1^2;

sbit ew_zz_red = P1^3;   //东西左转红黄绿
sbit ew_zz_yellow = P1^4;
sbit ew_zz_green = P1^5;

sbit sn_zx_red = P2^0;   //南北直行红黄绿
sbit sn_zx_yellow = P2^1;
sbit sn_zx_green = P2^2;

sbit sn_zz_red = P2^3;   //南北左转红黄绿
sbit sn_zz_yellow = P2^4;
sbit sn_zz_green = P2^5;

sbit seg_1 = P1^6;  //东西数码管位选开关
sbit seg_2 = P1^7;
sbit seg_3 = P2^6;  //南北数码管位选开关
sbit seg_4 = P2^7;

int time = 0; //计时器
int count = 0;

unsigned char SEG_CA[10] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};
unsigned char SEG_CC[10] = {0x3f, 0x06, 0x5b, 0x1f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};

void delay()
{
int i;
for(i = 0; i < 10; i++);
}

void display_ew(unsigned int num)  //东西数字显示
{
   P0 = SEG_CA[num/10];   //点亮数字高位
    seg_1 = ON;
delay();
    seg_1 = OFF;

    P0 = SEG_CA[num%10];   //点亮数字低位
seg_2 = ON;
delay();
    seg_2 = OFF;
}

void display_sn(unsigned int num)  //南北数字显示
{
   P0 = SEG_CA[num/10];  //点亮数字高位
    seg_3 = ON;
delay();
    seg_3 = OFF;

    P0 = SEG_CA[num%10];  //点亮数字低位
seg_4 = ON;
delay();
    seg_4 = OFF;
}

void display_ew_shan(unsigned int num)  //东西3s 倒计时闪烁显示
{
if(count < 2000)
display_ew(num);
else
{
seg_1 = OFF;
seg_2 = OFF;
}
}

void display_sn_shan(unsigned int num)  //南北3s倒计时闪烁显示
{
if(count < 2000)
display_sn(num);
else
{
seg_3 = OFF;
seg_4 = OFF;
}
}

void init()
{
P0 = 0x00;
P1 = 0x00;
P2 = 0x00;

EA = 0; //关总中断
ET0 = 1; //开定时器0中断
TMOD = 0x02; //定时器0工作方式2
TL0 = 6; //定时250us
TH0 = 6;
EA = 1;   //开总中断
TR0 = 1;  //开始定时
}

void main()
{
    init();
    while(1)
    {
/*************************************************************
开始东西直行绿灯亮,东西左转红灯亮27s,显示绿灯倒计时30s
南北直行、左转红灯亮50s,显示红灯倒计时50s
*************************************************************/
  while(time%100 < 27)
  {
  ew_zx_green = ON;  //东西直行绿灯亮,显示27s
  ew_zx_yellow = OFF;
  ew_zx_red = OFF;
  display_ew(30 - time);

  ew_zz_red = ON;  //东西左转红灯亮
  ew_zz_green = OFF;
  ew_zz_yellow = OFF;

  sn_zx_red = ON;  //南北直行红灯亮,显示时间50s
  sn_zx_yellow = OFF;
  sn_zx_green = OFF;
  display_sn(50 - time);

  sn_zz_red = ON;  //南北左转红灯亮,显示时间50s
  sn_zz_yellow = OFF;
  sn_zx_green = OFF;
  }
/*************************************************************
东西直行黄灯亮3s, 倒计时开始闪烁
东西左转,南北方向不变
*************************************************************/
  while(time%100 >= 27 && time%100 < 30)
  {
  ew_zx_yellow = ON;  //东西直行黄灯亮 ,显示时间3s
  ew_zx_red = OFF;
  ew_zx_green = OFF;
  display_ew_shan(30 - time);

  display_sn(50 - time);
  }
/*************************************************************
东西左转绿灯亮17s,直行红灯亮 ,显示绿灯倒计时20s
南北方向不变
*************************************************************/ 
  while(time%100 >= 30 && time%100 < 47)
  {
  ew_zz_green = ON; //东西左转绿灯亮,显示时间17s
  ew_zz_red = OFF;
  ew_zz_yellow = OFF;
  display_ew(50-time);

  ew_zx_red = ON;  //东西直行红灯亮
  ew_zx_yellow =OFF;
  ew_zx_green = OFF;

  display_sn(50-time);  //南北继续显示倒计时
  } 
/*************************************************************
东西左转黄灯亮3s, 倒计时开始闪烁 3s
东西直行,南北方向不变
*************************************************************/
  while(time%100 >= 47 && time%100 < 50)
  {
  ew_zz_yellow = ON; //东西左转黄灯亮,显示时间3s
  ew_zz_red = OFF;
  ew_zz_green = OFF;
  display_ew_shan(50-time);

  display_sn(50-time);  //南北继续显示倒计时
  }
/*************************************************************
东西左转红灯亮50s,直行不变,显示倒计时50s
南北直行绿灯亮27,左转不变,显示绿灯倒计时30s
*************************************************************/
  while(time%100 >=50 && time%100 < 77)
  {
sn_zx_green = ON; //南北直行绿灯亮,显示时间27s
sn_zx_yellow = OFF;
sn_zx_red = OFF;
display_sn(80 - time);

ew_zz_red = ON;   //东西左转红灯亮,显示时间50s
ew_zz_yellow = OFF;
ew_zz_green = OFF;
display_ew(100 - time);
}
/*************************************************************
南北直行黄灯亮3s,左转不变,显示黄灯闪烁倒计时3s
东西不变
*************************************************************/ 
while(time%100 >= 77 && time%100 < 80)
{
sn_zx_yellow = ON; //南北直行黄灯亮,显示时间3s
sn_zx_red = OFF;
sn_zx_green = OFF;
display_sn_shan(80 - time);

display_ew(100 - time);
}
/*************************************************************
南北左转绿灯亮17s,直行不变,显示绿灯倒计时20s
东西不变
*************************************************************/ 
while(time%100 >=80 && time%100 <97)
{
sn_zz_green = ON;  //南北左转绿灯亮, 显示17s
sn_zz_red = OFF;
sn_zz_yellow = OFF;
display_sn(100-time);

sn_zx_red = ON; //南北直行红灯亮
sn_zx_yellow = OFF;
sn_zx_green = OFF;

display_ew(100 - time); //东西继续倒计时
}
/*************************************************************
南北左转黄灯亮17s,直行不变,显示黄灯闪烁倒计时3s
东西不变
*************************************************************/ 
while(time%100 >= 97 && time<=100)
{
sn_zz_yellow = ON; //南北左转黄灯亮, 显示时间3s
sn_zz_red = OFF;
sn_zz_green = OFF;
display_sn_shan(100 - time);

display_ew(100 - time); //东西继续倒计时
}
   }
}

void timer0() interrupt 1
{
count++;
if(count == 4000)
{
time++;
count = 0;
}
if(time > 100)
time = 0;
}









来源:http://tekkamanninja.blog.chinaunix.net/uid-29270124-id-4183732.html

点击阅读原文直接进入


> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >

不同的方向不好直接对比,物联网发现速度快,如果往终端方向走建议单片机,如果往网关数据处理方向建议上系统。鱼和熊掌你要哪个呢?

生成海报
点赞 0

thePro

我还没有学会写个人说明!

相关推荐

基于8051单片机实现电子时钟+数字秒表设计

概述 电子时钟是一种利用数字电路来显示秒、分、时的计时装置,与传统的机械钟相比,它具有走时准确、显 示直观、无机械传动装置等优点,因而得到广泛应用。随着人们生活环境的不断改善和美化,在许

51小车(一)

1.准备: 借鉴: 详细介绍如何从零开始制作51单片机控制的智能小车(一)———让小车动起来_慕羽★的博客-CSDN博客_新手怎么制作单片机智能小车 2.已有模块 (1)  已有电机驱动 (2)

三相电机相电感,相电阻和极对数的测量

相电阻测量: 方法一:可使用万用表电阻档直接测量其中两端 方法二:可使用LCR数字电桥仪器测量 万用表操作: 将万用表旋转到电阻档的适当量程内 将万用表上的两表笔接触在电机的其中任意