2012年(1008)
分类:
2012-08-01 11:03:47
原文地址:51单片机模拟交通灯 作者:luozhiyong131
/*
* 功能:单片机控制系统 简单模拟交通灯功能
* 摘要:十字路**通灯控制系统。用2位数码管显示倒计时剩余时间
* 模拟XY方向的十字路**通信号控制情况
* A@T:李钦焰 2011-12-20
*/
#include
#define uchar unsigned char
sbit dula=P2^1; // 控制个位显示
sbit wela=P2^0; // 控制十位显示
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //数码管编码
uchar time = 59; /* 保存时间全局变量 */
/**
* 四种状态:东 西 P1口数据
* 红 绿 1000 0010
* 红 黄 1000 0100
* 绿 红 0010 1000
* 黄 红 0100 1000
*/
#define RG 0x41 // 红 绿
#define RY 0x21 // 红 黄
#define GY 0x14 // 绿 红
#define YE 0x12 // 黄 红
/**
* 功能:短延时
* 描述:ms延时
* time -> 要延时的ms数
*/
void MsDelay(uchar time)
{
int j, k;
for(j=time;j>0;j--)
for(k=125;k>0;k--);
}
/**
* 功能:数码管驱动函数
* 描述:两位数显示
* num -> 要显示的数值
*/
void LedDisplay(uchar num)
{
uchar num1, num2; /* 保存个位
num1 = num / 10; /* 得到十位 */
num2 = num % 10; /* 得到十位 */
/*
* 个位数显示
*/
wela = 1;
P0 = ~table[num1]; //数码管个位段信号输出
MsDelay(5);
wela = 0;
/*
* 第十位数显示
*/
dula = 1;
P0 = ~table[num2]; //数码管十位段信号输出
MsDelay(2);
dula = 0;
}
/**
* 功能:初始化函数
* 描述:中断定时器初始化 1s
*/
void init(void)
{
TMOD = 0x01; /* 采用定时模式1 */
TH0 = 0x3C;
TL0 = 0xB0;
TR0 = 1; /* 运行定时器 */
ET0 = 1; /* 开启定时中断0 */
EA = 1; /* 开启总中断 */
P1 = ~RG; /* 初始化 为 黄 红*/
}
/**
* 主函数:时间显示
*/
int main(void)
{
init(); /* 初始化 */
while(1)
{
LedDisplay(time % 30); /* 时间显示 */
}
return 0;
}
/**
* 功能:交通灯 - 红绿灯
* 描述:
* 东西: 红(30s) 绿(27s) 黄(3s)
* 南北: 绿(27s) 黄(3s) 红(30s)
* 时间对照:
* 59-33 32-30 29-3 2-0
*(东西) 红 红 绿 黄
* (南北) 绿 黄 红 红
*/
void funtion(uchar t)
{
if(t < 3)
P1 = ~YE;
else if(t < 30)
P1 = ~GY;
else if(t < 33)
P1 = ~RY;
else if(t <= 59)
P1 = ~RG;
else
time = 60;
}
/**
* 功能:定时中断函数
* 描述:一秒定时
*/
void IrqTime(void) interrupt 1
{
static unsigned int uiTount=0;
TH0 = 0x3C; /* 重赋初值 */
TL0 = 0xB0;
uiTount++; /* 计数加一 */
if(uiTount >= 20) /* 1S定时到*/
{
uiTount = 0;
funtion(--time); /* 时间减1 交通灯变色*/
}
}
完整工程代码 + proteus仿真图 交通灯.rar