用51单片机实现交通灯仿真,
①开始30秒上行,用定时器中断计时,1s一个数值,用数码管显示;5秒后黄灯阶段。
开始30秒右行,5秒后黄灯阶段;重复上诉过程。
②用74HC595芯片实现串转并联,控制8个交通灯亮灭,再用两个io控制右行人行灯。
③用P0口驱动数码管驱动显示,实际应该加74HC245增加驱动能力。
④运行过程中,有些LED会稍微闪烁,欢迎各位大佬交流讨论。
以下为代码:
//交通灯主程序
#include “reg52.h” //此文件中定义了单片机的一些特殊功能寄存
#include “intrins.h”
#include “_74Hc595_writeByte.H”
#include “delay.h”
#include “DigDisplay.h”
//–定义使用的IO口–//
#define u16 unsigned int //对数据类型进行声明定义
#define u8 unsigned char
sbit RED= P2^3; //右人行道红灯
sbit GREEN= P2^4; //右人行道绿灯
u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值
u8 Second;
void main()
{
Second = 1;
Timer0Init(); //定时器初始化
while(1)
{
if(Second == 71)
{
Second = 1;
}
//--上行通行,30秒--//
if(Second < 31)
{
DisplayData[0] = smgduan[(31 - Second) % 100 / 10];
DisplayData[1] = smgduan[(31 - Second) %10];
DisplayData[2] = DisplayData[0];
DisplayData[3] = DisplayData[1];
DigDisplay();
//--上行通行--//
_74Hc595_writeByte(0x00); //将所有的灯熄灭
RED = 0;
GREEN = 0;
_74Hc595_writeByte(0x32); //上行以及上行人行绿灯亮,右行红灯亮
RED=1; //右行人行道红灯亮
}
//--黄灯等待切换状态,5秒--//
else if(Second < 36)
{
DisplayData[0] = smgduan[(36 - Second) % 100 / 10];
DisplayData[1] = smgduan[(36 - Second) %10];
DisplayData[2] = DisplayData[0];
DisplayData[3] = DisplayData[1];
DigDisplay();
//--黄灯阶段--//
_74Hc595_writeByte(~0xFF); //将所有的灯熄灭
RED = 0;
GREEN = 0;
_74Hc595_writeByte(0x29);//上行黄灯亮以及上行人行红灯亮,右行红灯亮
RED = 1; //右行人行道红灯亮
}
//--右行通行--//
else if(Second < 66)
{
DisplayData[0] = smgduan[(66 - Second) % 100 / 10];
DisplayData[1] = smgduan[(66 - Second) %10];
DisplayData[2] = DisplayData[0];
DisplayData[3] = DisplayData[1];
DigDisplay();
_74Hc595_writeByte(~0xFF); //将所有的灯熄灭
RED = 0;
GREEN = 0;
_74Hc595_writeByte(0x85); // 上行红灯亮以及上行人行红灯亮,右行绿灯亮
GREEN=1; //右行人行道绿灯亮
}
//--黄灯等待切换状态,5秒--//
else
{
DisplayData[0] = smgduan[(71 - Second) % 100 / 10];
DisplayData[1] = smgduan[(71 - Second) %10];
DisplayData[2] = DisplayData[0];
DisplayData[3] = DisplayData[1];
DigDisplay();
//--黄灯阶段--//
_74Hc595_writeByte(~0xFF); //将所有的灯熄灭
RED = 0;
GREEN = 0;
_74Hc595_writeByte(0x45); //右行黄灯亮以及上行人行红灯亮,上行红灯亮
RED = 1; //右行路人行道红灯亮
}
}
}
void Timer0() interrupt 1
{
static u16 i;
TH0=0xFC; //给定时器赋初值,定时1ms
TL0=0x18;
i++;
if(i==1000)
{
i=0;
Second ++;
}
}
//数码管控制驱动程序,及中断初始化
#include “reg52.h” //此文件中定义了单片机的一些特殊功能寄存
#include “intrins.h”
#include “_74Hc595_writeByte.H”
#include “delay.h”
#define u16 unsigned int //对数据类型进行声明定义
#define u8 unsigned char
u8 DisplayData[8];
u8 i;
sbit LSA=P3^0;
sbit LSB=P3^1;
sbit LSC=P3^2;
sbit LSD=P3^3;
#define GPIO_DIG P0
void DigDisplay()
{
for(i=0;i<4;i++)
{
switch(i) //位选,选择点亮的数码管,
{
case(0):
LSA=0;LSB=1;LSC=1;LSD=1; break;//显示第0位
case(1):
LSA=1;LSB=0;LSC=1;LSD=1; break;//显示第1位
case(2):
LSA=1;LSB=1;LSC=0;LSD=1; break;//显示第2位
case(3):
LSA=1;LSB=1;LSC=1;LSD=0;break;//显示第3位
}
GPIO_DIG=DisplayData[i];//发送段码
delay(1); //间隔一段时间扫描
GPIO_DIG=0x00;//消隐
}
}
void Timer0Init()
{
TMOD|=0x01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
TH0=0xFC; //给定时器赋初值,定时1ms
TL0=0x18;
ET0=1;//打开定时器0中断允许
EA=1;//打开总中断
TR0=1;//打开定时器
}
#ifndef DigDisplay_H
#define DigDisplay_H
void DigDisplay();
void Timer0Init();
#define u8 unsigned char
extern u8 DisplayData[8];
#endif
//延时程序
#include “reg52.h” //此文件中定义了单片机的一些特殊功能寄存
#include “intrins.h”
void delay(unsigned char i) //@11.0592MHz 1ms
{
unsigned char j;
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
#ifndef delay_H
#define delay_H
void delay(i);
#endif
//595驱动程序
#include
sbit SER=P3^4; //串行输入,一位一位输入,输入口
sbit RCK=P3^5; //并行输出开,上升沿
sbit SCK=P3^6;
#define u16 unsigned int //对数据类型进行声明定义
#define u8 unsigned char
void _74Hc595_writeByte(u8 Byte)
{
u8 i;
for(i=0;i<8;i++)
{
SER=Byte&(0x80>>i);//1000 0000取出最高位
SCK=1;
SCK=0;
}
RCK=1;
RCK=0;
}
#ifndef _74Hc595_writeByte_H
#define _74Hc595_writeByte_H
void _74Hc595_writeByte(Byte);
#endif



