开发者社区> 一生有你llx> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

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

简介: 一、说明:本程序与之前例程不同,采用c语言完成,实现四个方向的直走和左转车辆控制,采用51定时器精确计时二、原理图:三、基本设计思想: 1、硬件部分。七段数码管显示时间,采用共阳数码管,与P0口连接。
+关注继续查看
一、说明:本程序与之前例程不同,采用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 }

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 display_ew(num);
else
{
seg_1 = OFF;
seg_2 = OFF;
}
}

void display_sn_shan(unsigned int num)  //南北3s倒计时闪烁显示
{
if(count 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   {
  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   {
  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   {
  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   {
  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   {
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 {
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 {
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 {
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;
}

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
《C语言及程序设计》实践项目——穷举法解题
返回:贺老师课程教学链接 说明:穷举法在有些时候,并不是一种最有效率的解决方案,但却是最直观的。初学者依靠这一组问题的解决,将获得程序设计的最直接体验,以及会想问题的头脑。 【项目1-小明借书】小明有五本新书,要借给A,B,C三位小朋友,若每人每次只能借一本,则可以有多少种不同的借法?提示:本问题实际上是一个排列问题,即求从5个中取3个进行排列的方法的总数。首先对五本书从1至5进行编号,然后
1440 0
《C语言及程序设计》实践参考——回文日
返回:贺老师课程教学链接  项目要求 【项目6-回文日】很有趣的一个题目:2011年11月02日是一个回文日:2011 1102,在2011级同学做这道题时我们刚刚度过这一天!请列出本世纪还有多少个回文日(假如我们能活到百岁,你和我的……)。注意:一年只有12个月。[参考解答]     当年份确定后,如2015年,就看20155102能否构成一个合法的日期,其中51部分是月,02部分是日。显
642 0
《C语言及程序设计》实践参考——回文数
返回:贺老师课程教学链接  项目要求 【项目4-回文数】(1)输入一个正整数,判断其是否为一个回文数(例1221、12321都是回文数,正着看、倒着看,是同一个数)。[参考解答] #include <stdio.h> int main() { int n,m,k; scanf("%d", &n); k=n; m=0; //m将为n的反
685 0
《C语言及程序设计》实践参考——阿姆斯特朗数
返回:贺老师课程教学链接  项目要求 【项目5-阿姆斯特朗数】如果一个正整数等于其各个数字的立方和,则称该数为阿姆斯特朗数(亦称为自恋性数)。如 407=4^3+0^3+7^3就是一个阿姆斯特朗数。试编程求1000以内的所有阿姆斯特朗数。[参考解答] #include <stdio.h> int main() { int i,m,k,n; for(n=1; n&
813 0
《C语言及程序设计》实践参考——反序数
返回:贺老师课程教学链接  项目要求 【项目3-反序数】(1)输入一个正整数,输出它的反序数(反序数,即将其所有位的数字反过来。例如,123是321的反序数) [参考解答] #include &lt;stdio.h&gt; int main() { int n,m,k; scanf("%d", &amp;n); k=n; m=0; while(k&g
724 0
《C语言及程序设计》实践参考——n=a!+b!+c!
返回:贺老师课程教学链接  项目要求 【项目2 - n=a!+b!+c!】求满足条件n=a!+b!+c!的所有三位数n并输出,其中a,b,c分别为n的百、十、个位数。[参考解答] 解法1:n为3位数,n由100循环到999,每次循环,分离出百、十、个位数,以此判断 #include <stdio.h> int main() { int n,a,b,c,sum; int
985 0
《C语言及程序设计》实践参考——完数
返回:贺老师课程教学链接  项目要求 【项目1-完数】一个数如果恰好等于它的因子之和,这个数就称为“完数”。例如6=1+2+3,再如8的因子和是7(即1+2+4),8不是完数。(1)输入一个数n,判断n是否是完数[参考解答] 解1: #include &lt;stdio.h&gt; int main( ) { int n,s,m; printf("输入n:"); s
656 0
《C语言及程序设计》实践项目——数字游戏
返回:贺老师课程教学链接 说明:这里给出的题目比较多,可以耐心地做下去。初学者一旦通过这样一些小的程序,走出了循环的困局,程序设计的感觉,也便逐渐好了起来。循环作为初学者必须迈过去的一道坎,这样的训练自有价值。 【项目1-完数】一个数如果恰好等于它的因子之和,这个数就称为“完数”。例如6=1+2+3,再如8的因子和是7(即1+2+4),8不是完数。(1)输入一个数n,判断n是否是完数(2)输出
818 0
《C语言程序设计与实践(第2版)》——1.2 计算机与程序设计
计算机的功能非常强大,能做非常复杂、人脑难以胜任的许多工作。然而,从电子市场买回CPU、主板、内存、硬盘等硬件并组装好一台计算机后,你却发现这台计算机什么也做不了。究其原因,就是因为该计算机上还没有安装任何计算机程序,即软件。
1349 0
《C语言程序设计与实践(第2版)》——3.3 常量与变量
字符串常量是指用一对双引号括起来的一串字符。双引号只起定界作用,双引号括起的字符串中不能是双引号(")和反斜杠(\),它们有特定的表示方法,这将在转义字符中介绍。例如,"China"、"C program"、"YES&NO"、"33312-2341"等。
922 0
+关注
一生有你llx
专注物联网
文章
问答
文章排行榜
最热
最新
相关课程
更多
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载