• 51单片机电子制作DIY-----交通灯控制器


    作者:李剀
    出处:https://www.cnblogs.com/kevin-nancy/
    或者
    https://blog.csdn.net/Kevin_8_Lee/article/details/91351632
    欢迎转载,但也请保留上面这段声明。谢谢!(上面两个都是我的博客,只是在不同平台)

    首先说一下背景吧 :

    最近在帮别人做一些小东西,是用51做的,主要给他们提供单片机课设的思路。 且由于时间问题,我也没有将程序进行优化,只是拿来分享一下,大家可以参考。 有思路之后可以稍微花点时间去优化一下代码,是代码更简洁。

    马丁·福勒 的一句名言与君共勉:

    任何一个傻瓜都会写能够让机器理解的代码,只有好的程序员才能写出人类可以理解的代码。—Martin Fowler

    ok, 废话不多说,下面是设计要求及制作过程,proteus仿真以及代码流程的介绍

    1) 题目及设计要求

    题目: 交通灯控制器
    要求:
    1、红灯和绿灯相互转换时经过黄灯,黄灯闪烁三次(6秒);

    2、主干道方向通行30秒,辅干道方向通行20秒,单独左转信号15秒;先直行信号,后左转信号。

    3、设手动、自动、特殊情况三种方式。

    4、特殊情况时所有路口红灯都亮,给120、110等通行。

    5、自动时显示各种状态倒计时。

    2) C51编程以及电路仿真软件

    编程
    51单片机的C语言编程一般都是keil3或者keil4,我一直以来用的keil3,这次使用的keil4,其实都一样的。

    (**注:**关于keil3/4/5的资料和安装破解教程,在我的另一篇博客讲过了,可以参考一下 点击蓝字–>> keil3/4/5安装及破解(附百度云资源))

    在这里插入图片描述
    keil4打开的界面如下:
    在这里插入图片描述

    ( PS:: 不过这次做这些东西的过程中,keil4经常自己卡死,害得我只能任务管理器关闭它,超级烦,不知道什么原因,有了解的可以评论一下告诉我,感激不尽 …但是老版本的keil3却很稳定)

    仿真:
    proteus仿真软件

    我用的7版本的
    在这里插入图片描述

    proteus打开界面如下:
    在这里插入图片描述
    这个界面里面的电路图与这个交通灯无关,是我以前做的一个,只是给大家演示

    3)解决思路

    硬件部分:

    交通灯显示部分分为6个部分
    • [ 1] 首先:主干道通行30秒 其中单独左转15秒 黄灯6秒
    1)主干道--------绿灯 辅干道--------红灯 0-15s // 单独直行
    2)主干道--------蓝灯 辅干道--------红灯 15-24s // 单独左转
    3)主干道--------黄灯 辅干道--------红灯 24-30s // 黄灯减速

    • [ 2] 辅干道通行20秒 单独左转15秒 黄灯6秒
    4)主干道--------红灯 辅干道--------绿灯 0-5s
    5)主干道--------红灯 辅干道--------蓝灯 5-14s
    6)主干道--------红灯 辅干道--------黄灯 14-20s

    模拟交通的灯的几个led灯的显示在程序中就是按照上面的流程显示的,由 1)—>2)—>…—>6)—>1)->… 一直循环

    仿真电路图各个部分展示:
    (1)单片机 & 复位电路 & 晶振

    在这里插入图片描述

    (2)交通灯部分

    在这里插入图片描述
    上图标注了每个灯对应的引脚 以及每个灯的颜色

    分别在上面和右面放置了一排 用来表示道路的方向

    D1-D4指示的是主干道 D5-D8指示的是辅干道

    (3)数码管显示部分

    这部分是和交通灯部分一起的 为了方便看到我写的标注,我把交通灯抹去了,抹去的部分就是上面交通灯的部分在这里插入图片描述
    在这里插入图片描述

    (该芯片使用方法这里不多说,网上很多资料。。。本质就是一个锁存器)

    软件部分

    首先代码流程图如下,对这个画图软件不是很熟,画的很垃圾,不过大致能体现出来
    在这里插入图片描述

    4)部分代码展示及解释

    # include <reg52.h>
    # define uchar unsigned char
    # define uint  unsigned int
    
    sbit wela = P2^7;  		// 数码管位选
    sbit dula = P2^6;		// 数码管段选
    
    // 按键位定义
    sbit	key_auto 	= P3^0;	// 自动
    sbit	key_step 	= P3^1;	// 手动
    sbit	key_emerg 	= P3^2;	// 紧急情况 110/120通过
    
    // 四位八段共阴极数码管数字显示编码
    uchar code table[]={
    //"0" "1"  "2"  "3"
    0x3f,0x06,0x5b,0x4f,
    //"4" "5"  "6"  "7"
    0x66,0x6d,0x7d,0x07,
    //"8" "9"  "A"  "B"
    0x7f,0x6f,0x77,0x7c,
    //"C" "D"  "E"  "F"
    0x39,0x5e,0x79,0x71
    };
    
    // 交通灯编码  自动模式时,交通灯亮灯顺序 我编成了一个数组,方便使用
    
    uchar code light[]={
    // 主G辅R      主G辅R    主Y辅R
        0xdb,       0xde,     0xd7,
    // 主R辅G      主R辅B    主R辅R
        0xbd,       0xed,     0x7d,
    };
    
    // 定时器0中断服务函数  用于计算时间过了几秒
    void timer0() interrupt 1
    {
    	TH0=0x4c;		// 定时器装初值 50ms(11.05926MHz  TH0=0x4c TL0=0x00) 
    	TL0=0x00;	    // (12MHz 的初值是 TH0=0x3c TL0=0xb0)
        cnt++;
    	if(cnt == 20)
    	{
    		cnt = 0;
    		sec++;	  // 记录1秒
    	}
    }
    
    // 按键扫描函数
    void key_scan()
    {
        //判断那个按键盘下
        
        /********************** 自动模式 *********************/
        ///如果是自动模式,就让交通灯正常运行  并显示倒计时
        // Display_C_time(15-sec);	// 主干道倒计时显示
        // Display_R_time(30-sec);  // 辅干道倒计时显示
        // P1 = light[0];		   // 交通灯编码显示
        // 具体代码省略、、、、、、、、、、
        
         /********************** 手动模式 *********************/
        //手动模式就让交通等步进变换
        if(key_step == 0)
    	{
    		delay_ms(5);
    		if(key_step == 0)
    		{
    			if(light_num == 6)
    			{
    				light_num = 0;
    			}
    			P1 = light[light_num];
    			light_num++;
    			while(!key_step);  // 松手检测
    		}
    	}
    	
    	 /********************** 紧急模式 *********************/
    	// 紧急模式  用于120/110紧急通行
    	// 让主干道和辅干道都是红灯即可
    	// 具体代码省略、、、、、、、、、、、
        
    }
    

    // 最后在主函数里面初始化,然后循环扫描按键

    void main()
    {
        system_Init();			// 系统初始化  里面是对定时器中断以及数码管进行初始化
    
        while(1)
    	{
    		key_scan();
    	}
    }
    

    5)整体效果演示

    在这里插入图片描述

    因为这个是帮别人设计的,所以完整源码和仿真工程文件不贴出。 如果需要完整的仿真以及源码,请私聊我或者评论留下联系方式


    2019/06/20 修改
    上面所使用的数码管是共阴极数码管,我标记错了,抱歉!

    今天所有的懒惰都会换来明天的卑微 加油吧!!!
  • 相关阅读:
    Delphi中TFlowPanel实现滚动条效果
    Delphi组件开发-在窗体标题栏添加按钮(使用MakeObjectInstance(NewWndProc),并处理好多消息)
    减小Delphi的Exe文件大小(11种方法)
    画出太极图
    类似地图的以鼠标为中心缩放图像
    andoid x项目的优化 1
    ICON图标文件解析
    所有语言的Awesome(2)
    获取EIP(汇编语言直接给Delphi变量赋值)
    Qt Windows下链接子系统与入口函数(终结版)(可同时存在main和WinMain函数)
  • 原文地址:https://www.cnblogs.com/kevin-nancy/p/12569389.html
Copyright © 2020-2023  润新知