快捷搜索:  汽车  科技

51单片机交通灯proteus仿真图(基于proteus的51单片机开发实例17-模拟简单的交通灯)

51单片机交通灯proteus仿真图(基于proteus的51单片机开发实例17-模拟简单的交通灯)东西方向绿灯点亮,红灯熄灭、黄灯熄灭;南北方向红灯点亮,绿灯、黄灯熄灭。1、状态1-东西方向绿灯时间到本实例主要涉及51单片机的定时器/计数器的复杂应用,状态机的实现机制等知识。对于定时器/计数器的功能,前面例子已经多处讲过,这里就不再赘述。重点来了解一下本例中各种LED运行状态的切换。简易交通灯的处理流程:

1. 基于proteus的51单片机开发实例17-模拟简单的交通灯1.1. 实验目的

本实例实现模拟简单交通灯的效果。之所以说是简单的交通的,是因为本例中只有直行的红绿灯指示,没有转向指示灯。利用51单片机的定时器/计数器的定时功能,在定时中断里面实现功能的切换。

51单片机交通灯proteus仿真图(基于proteus的51单片机开发实例17-模拟简单的交通灯)(1)

图1 模拟简单交通的电路

1.2. 设计思路

交通灯我们都见过:在十字路口,当东西方向绿灯亮起时,南北方向的指示灯一定是红灯亮起,反之亦然。本例使用发光二极管模拟四个方向的交通灯,每个方向都有红、黄、绿三色指示灯。系统运行时,东西方向的交通灯按照“绿灯亮-黄灯闪烁-红灯亮”的流程运行,南北方向则与东西方向的运行流程相反。

东西南北四个方向,每个方向都有红、黄、绿三个指示灯,共计12个指示灯。单片机分别用P0、P1、P2、P3四个端的3个位来控制。

1.3. 基础知识

本实例主要涉及51单片机的定时器/计数器的复杂应用,状态机的实现机制等知识。对于定时器/计数器的功能,前面例子已经多处讲过,这里就不再赘述。

重点来了解一下本例中各种LED运行状态的切换。

简易交通灯的处理流程:

1、状态1-东西方向绿灯时间到

东西方向绿灯点亮,红灯熄灭、黄灯熄灭;南北方向红灯点亮,绿灯、黄灯熄灭。

2、状态2-东西方向黄灯时间到

东西方向黄灯闪烁,绿灯、红灯熄灭;南北方向红灯点亮,绿灯、黄灯熄灭。

3、状态3-南北方向绿灯时间到

东西方向红灯亮,黄灯、绿灯熄灭;南北方向绿灯点亮,红灯、黄灯熄灭。

4、状态4-黄灯时间到南北方向

南北方向黄灯闪烁,红灯、绿灯熄灭;东西方向红灯点亮,绿灯、黄灯熄灭。

5、状态4执行完毕后,下一个状态切换到状态1循环执行。

1.4. 电路设计

本例中,共用到12个LED,分为三种颜色:红、黄、绿。我们用P0端口的P0.0,P0.1,P0.2这三位控制北向的红、黄、绿三个发光二极管,用P1端口的P1.0,P1.1,P1.2这三位控制西向的红、黄、绿三个发光二极管,用P2端口的P2.0,P2.1,P2.2这三位控制东向的红、黄、绿三个发光二极管,用P3端口的P3.0,P3.1,P3.2这三位控制北向的红、黄、绿三个发光二极管。LED的驱动采用“灌电流”的方式,再次强调:本电路中的LED驱动方式不适合实际电路要求,在实际电路中,最好是用三极管驱动或者专用的LED驱动芯片。

1.5. 程序设计

本实例的程序代码如下。

#include <AT89x52.h>// sbit RED_west = P1^0;//西向红灯端口定义 sbit YELLOW_west = P1^1; sbit GREEN_west = P1^2; sbit RED_east = P2^0; //东向红灯端口定义 sbit YELLOW_east = P2^1; sbit GREEN_east = P2^2; sbit RED_north = P0^2;//北向红灯端口定义 sbit YELLOW_north = P0^1; sbit GREEN_north = P0^0; sbit RED_south = P3^2;//南向红灯端口定义 sbit YELLOW_south = P3^1; sbit GREEN_south = P3^0; unsigned char Time_Count = 0; // 全局变量定义及赋初值,定时计数变量 unsigned char Flash_Count = 0; // 全局变量定义及赋初值,闪烁计数变量 unsigned char Operation_Type = 1; // 全局变量定义及赋初值,状态计数变量 void T0_INT() interrupt 1 //单片机定时器/计数器T0中断服务程序 { TH0 = -50000/256; //进定时器中断后,首先重装定时初值 TL0 = -50000%6; switch(Operation_Type) //根据状态变量选择执行那一种状态 { case 1: { RED_west=RED_east=OFF; //东西方向红灯灭 YELLOW_west=YELLOW_east=OFF; //东西方向黄灯灭 GREEN_west=GREEN_east=ON; //东西方向绿灯亮 RED_north=RED_south=ON; //南北方向红灯亮 YELLOW_north=YELLOW_south=OFF; //南北方向黄灯灭 GREEN_north=GREEN_south=OFF; //南北方向绿灯灭 if( Time_Count != 100) //判断是否达到下一个状态时间 { return; } Time_Count=0; Operation_Type = 2; //切换状态,下一步执行状态2 } break; case 2: { if( Time_Count != 8) { return; } Time_Count=0; YELLOW_west=YELLOW_east=~YELLOW_west; //东西方向黄灯闪烁 GREEN_west=GREEN_east=OFF; //东西方向绿灯灭 if( Flash_Count != 10) //东西方向黄灯闪烁结束 { return; } Flash_Count=0; Operation_Type = 3; //状态切换,下一步执行状态3 } break; case 3: { RED_west=RED_east=ON; //东西方向红灯亮 YELLOW_west=YELLOW_east=OFF; //东西方向黄灯灭 GREEN_west=GREEN_east=OFF; //东西方向绿灯亮 RED_north=RED_south=OFF; //南北方向红灯灭 YELLOW_north=YELLOW_south=OFF; //南北方向黄灯灭 GREEN_north=GREEN_south=ON; //南北方向绿灯亮 if( Time_Count != 100) { return; } Time_Count=0; Operation_Type = 4; //改变工作状态,下一步执行状态4 } break; case 4: { if( Time_Count != 8) { return; } Time_Count=0; YELLOW_north=YELLOW_south=~YELLOW_north; //黄灯闪烁 GREEN_north=GREEN_south=OFF; //绿灯灭 if( Flash_Count !=10) //南北向黄灯闪烁完毕 { return; } Flash_Count=0; Operation_Type = 1; //工作状态切换回状态1 } break; } } int main(void) { TMOD = 0x01; //设置定时器T0的工作状态 TH0 = -50000/256;//定时器初值设定 TL0 = -50000%6; EA = 1; ET0 = 1; //打开定时器T0中断 TR0 = 1; //启动定时器T0工作 while(1) { } }

我们可以看到,在本程序中,主函数中只是进行了定时器的工作方式,定时器初值的设定。在主循环中没有任何程序语句。程序运行主要靠定时器的定时中断里面。程序的执行依靠全局变量Operation_Type的值来判断执行哪一种状态。

1.6. 实例仿真

编译程序后,将生成的hex文件载入proteus电路的单片机中,开始仿真,观察东、西、南、北方向的LED变化情况,是否符合设计预期。

下面视频是本实例的仿真过程。

1.7. 总结

通过本实例的学习,我们更加熟悉了51单片机定时器/计数器的定时功能,同时也对定时器的复杂应用有了更深认识,从中可以了解到在51单片机开发中,定时器/计数器是使用是非常广泛的。

猜您喜欢: